@@ -239,27 +239,36 @@ getSection(const object::MachOObjectFile &Obj,
239
239
// Transfer \a Segment from \a Obj to the output file. This calls into \a Writer
240
240
// to write these load commands directly in the output file at the current
241
241
// position.
242
+ //
242
243
// The function also tries to find a hole in the address map to fit the __DWARF
243
244
// segment of \a DwarfSegmentSize size. \a EndAddress is updated to point at the
244
245
// highest segment address.
246
+ //
245
247
// When the __LINKEDIT segment is transferred, its offset and size are set resp.
246
248
// to \a LinkeditOffset and \a LinkeditSize.
249
+ //
250
+ // When the eh_frame section is transferred, its offset and size are set resp.
251
+ // to \a EHFrameOffset and \a EHFrameSize.
247
252
template <typename SegmentTy>
248
253
static void transferSegmentAndSections (
249
254
const object::MachOObjectFile::LoadCommandInfo &LCI, SegmentTy Segment,
250
255
const object::MachOObjectFile &Obj, MachObjectWriter &Writer,
251
- uint64_t LinkeditOffset, uint64_t LinkeditSize, uint64_t DwarfSegmentSize,
252
- uint64_t &GapForDwarf, uint64_t &EndAddress) {
256
+ uint64_t LinkeditOffset, uint64_t LinkeditSize, uint64_t EHFrameOffset,
257
+ uint64_t EHFrameSize, uint64_t DwarfSegmentSize, uint64_t &GapForDwarf,
258
+ uint64_t &EndAddress) {
253
259
if (StringRef (" __DWARF" ) == Segment.segname )
254
260
return ;
255
261
256
- Segment.fileoff = Segment.filesize = 0 ;
257
-
258
- if (StringRef (" __LINKEDIT" ) == Segment.segname ) {
262
+ if (StringRef (" __TEXT" ) == Segment.segname && EHFrameSize > 0 ) {
263
+ Segment.fileoff = EHFrameOffset;
264
+ Segment.filesize = EHFrameSize;
265
+ } else if (StringRef (" __LINKEDIT" ) == Segment.segname ) {
259
266
Segment.fileoff = LinkeditOffset;
260
267
Segment.filesize = LinkeditSize;
261
268
// Resize vmsize by rounding to the page size.
262
269
Segment.vmsize = alignTo (LinkeditSize, 0x1000 );
270
+ } else {
271
+ Segment.fileoff = Segment.filesize = 0 ;
263
272
}
264
273
265
274
// Check if the end address of the last segment and our current
@@ -280,7 +289,12 @@ static void transferSegmentAndSections(
280
289
Writer.W .OS .write (reinterpret_cast <char *>(&Segment), sizeof (Segment));
281
290
for (unsigned i = 0 ; i < nsects; ++i) {
282
291
auto Sect = getSection (Obj, Segment, LCI, i);
283
- Sect.offset = Sect.reloff = Sect.nreloc = 0 ;
292
+ if (StringRef (" __eh_frame" ) == Sect.sectname ) {
293
+ Sect.offset = EHFrameOffset;
294
+ Sect.reloff = Sect.nreloc = 0 ;
295
+ } else {
296
+ Sect.offset = Sect.reloff = Sect.nreloc = 0 ;
297
+ }
284
298
if (Obj.isLittleEndian () != sys::IsLittleEndianHost)
285
299
MachO::swapStruct (Sect);
286
300
Writer.W .OS .write (reinterpret_cast <char *>(&Sect), sizeof (Sect));
@@ -417,6 +431,27 @@ bool generateDsymCompanion(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
417
431
++NumLoadCommands;
418
432
}
419
433
434
+ // If we have a valid eh_frame to copy, do it.
435
+ uint64_t EHFrameSize = 0 ;
436
+ StringRef EHFrameData;
437
+ for (const object::SectionRef &Section : InputBinary.sections ()) {
438
+ Expected<StringRef> NameOrErr = Section.getName ();
439
+ if (!NameOrErr) {
440
+ consumeError (NameOrErr.takeError ());
441
+ continue ;
442
+ }
443
+ StringRef SectionName = *NameOrErr;
444
+ SectionName = SectionName.substr (SectionName.find_first_not_of (" ._" ));
445
+ if (SectionName == " eh_frame" ) {
446
+ if (Expected<StringRef> ContentsOrErr = Section.getContents ()) {
447
+ EHFrameData = *ContentsOrErr;
448
+ EHFrameSize = Section.getSize ();
449
+ } else {
450
+ consumeError (ContentsOrErr.takeError ());
451
+ }
452
+ }
453
+ }
454
+
420
455
unsigned HeaderSize =
421
456
Is64Bit ? sizeof (MachO::mach_header_64) : sizeof (MachO::mach_header);
422
457
// We will copy every segment that isn't __DWARF.
@@ -496,7 +531,10 @@ bool generateDsymCompanion(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
496
531
Writer.writeSymtabLoadCommand (SymtabStart, NumSyms, StringStart,
497
532
NewStringsSize);
498
533
499
- uint64_t DwarfSegmentStart = StringStart + NewStringsSize;
534
+ uint64_t EHFrameStart = StringStart + NewStringsSize;
535
+ EHFrameStart = alignTo (EHFrameStart, 0x1000 );
536
+
537
+ uint64_t DwarfSegmentStart = EHFrameStart + EHFrameSize;
500
538
DwarfSegmentStart = alignTo (DwarfSegmentStart, 0x1000 );
501
539
502
540
// Write the load commands for the segments and sections we 'import' from
@@ -505,15 +543,15 @@ bool generateDsymCompanion(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
505
543
uint64_t GapForDwarf = UINT64_MAX;
506
544
for (auto &LCI : InputBinary.load_commands ()) {
507
545
if (LCI.C .cmd == MachO::LC_SEGMENT)
508
- transferSegmentAndSections (LCI, InputBinary. getSegmentLoadCommand (LCI),
509
- InputBinary, Writer, SymtabStart ,
510
- StringStart + NewStringsSize - SymtabStart,
511
- DwarfSegmentSize, GapForDwarf, EndAddress);
546
+ transferSegmentAndSections (
547
+ LCI, InputBinary. getSegmentLoadCommand (LCI), InputBinary, Writer ,
548
+ SymtabStart, StringStart + NewStringsSize - SymtabStart, EHFrameStart ,
549
+ EHFrameSize, DwarfSegmentSize, GapForDwarf, EndAddress);
512
550
else if (LCI.C .cmd == MachO::LC_SEGMENT_64)
513
- transferSegmentAndSections (LCI, InputBinary. getSegment64LoadCommand (LCI),
514
- InputBinary, Writer, SymtabStart ,
515
- StringStart + NewStringsSize - SymtabStart,
516
- DwarfSegmentSize, GapForDwarf, EndAddress);
551
+ transferSegmentAndSections (
552
+ LCI, InputBinary. getSegment64LoadCommand (LCI), InputBinary, Writer ,
553
+ SymtabStart, StringStart + NewStringsSize - SymtabStart, EHFrameStart ,
554
+ EHFrameSize, DwarfSegmentSize, GapForDwarf, EndAddress);
517
555
}
518
556
519
557
uint64_t DwarfVMAddr = alignTo (EndAddress, 0x1000 );
@@ -554,11 +592,19 @@ bool generateDsymCompanion(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
554
592
EntryRef.getString ().size () + 1 );
555
593
}
556
594
}
557
-
558
595
assert (OutFile.tell () == StringStart + NewStringsSize);
559
596
597
+ // Pad till the EH frame start.
598
+ OutFile.write_zeros (EHFrameStart - (StringStart + NewStringsSize));
599
+ assert (OutFile.tell () == EHFrameStart);
600
+
601
+ // Transfer eh_frame.
602
+ if (EHFrameSize > 0 )
603
+ OutFile << EHFrameData;
604
+ assert (OutFile.tell () == EHFrameStart + EHFrameSize);
605
+
560
606
// Pad till the Dwarf segment start.
561
- OutFile.write_zeros (DwarfSegmentStart - (StringStart + NewStringsSize ));
607
+ OutFile.write_zeros (DwarfSegmentStart - (EHFrameStart + EHFrameSize ));
562
608
assert (OutFile.tell () == DwarfSegmentStart);
563
609
564
610
// Emit the Dwarf sections contents.
0 commit comments