diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/eh_frame/eh_frame.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/eh_frame/eh_frame.o new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ static void transferSegmentAndSections( const object::MachOObjectFile::LoadCommandInfo &LCI, SegmentTy Segment, const object::MachOObjectFile &Obj, MachObjectWriter &Writer, - uint64_t LinkeditOffset, uint64_t LinkeditSize, uint64_t DwarfSegmentSize, - uint64_t &GapForDwarf, uint64_t &EndAddress) { + uint64_t LinkeditOffset, uint64_t LinkeditSize, uint64_t EHFrameOffset, + uint64_t EHFrameSize, uint64_t DwarfSegmentSize, uint64_t &GapForDwarf, + uint64_t &EndAddress) { if (StringRef("__DWARF") == Segment.segname) return; - Segment.fileoff = Segment.filesize = 0; - - if (StringRef("__LINKEDIT") == Segment.segname) { + if (StringRef("__TEXT") == Segment.segname && EHFrameSize > 0) { + Segment.fileoff = EHFrameOffset; + Segment.filesize = EHFrameSize; + } else if (StringRef("__LINKEDIT") == Segment.segname) { Segment.fileoff = LinkeditOffset; Segment.filesize = LinkeditSize; // Resize vmsize by rounding to the page size. Segment.vmsize = alignTo(LinkeditSize, 0x1000); + } else { + Segment.fileoff = Segment.filesize = 0; } // Check if the end address of the last segment and our current @@ -280,7 +289,12 @@ Writer.W.OS.write(reinterpret_cast(&Segment), sizeof(Segment)); for (unsigned i = 0; i < nsects; ++i) { auto Sect = getSection(Obj, Segment, LCI, i); - Sect.offset = Sect.reloff = Sect.nreloc = 0; + if (StringRef("__eh_frame") == Sect.sectname) { + Sect.offset = EHFrameOffset; + Sect.reloff = Sect.nreloc = 0; + } else { + Sect.offset = Sect.reloff = Sect.nreloc = 0; + } if (Obj.isLittleEndian() != sys::IsLittleEndianHost) MachO::swapStruct(Sect); Writer.W.OS.write(reinterpret_cast(&Sect), sizeof(Sect)); @@ -417,6 +431,27 @@ ++NumLoadCommands; } + // If we have a valid eh_frame to copy, do it. + uint64_t EHFrameSize = 0; + StringRef EHFrameData; + for (const object::SectionRef &Section : InputBinary.sections()) { + Expected NameOrErr = Section.getName(); + if (!NameOrErr) { + consumeError(NameOrErr.takeError()); + continue; + } + StringRef SectionName = *NameOrErr; + SectionName = SectionName.substr(SectionName.find_first_not_of("._")); + if (SectionName == "eh_frame") { + if (Expected ContentsOrErr = Section.getContents()) { + EHFrameData = *ContentsOrErr; + EHFrameSize = Section.getSize(); + } else { + consumeError(ContentsOrErr.takeError()); + } + } + } + unsigned HeaderSize = Is64Bit ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header); // We will copy every segment that isn't __DWARF. @@ -496,7 +531,10 @@ Writer.writeSymtabLoadCommand(SymtabStart, NumSyms, StringStart, NewStringsSize); - uint64_t DwarfSegmentStart = StringStart + NewStringsSize; + uint64_t EHFrameStart = StringStart + NewStringsSize; + EHFrameStart = alignTo(EHFrameStart, 0x1000); + + uint64_t DwarfSegmentStart = EHFrameStart + EHFrameSize; DwarfSegmentStart = alignTo(DwarfSegmentStart, 0x1000); // Write the load commands for the segments and sections we 'import' from @@ -505,15 +543,15 @@ uint64_t GapForDwarf = UINT64_MAX; for (auto &LCI : InputBinary.load_commands()) { if (LCI.C.cmd == MachO::LC_SEGMENT) - transferSegmentAndSections(LCI, InputBinary.getSegmentLoadCommand(LCI), - InputBinary, Writer, SymtabStart, - StringStart + NewStringsSize - SymtabStart, - DwarfSegmentSize, GapForDwarf, EndAddress); + transferSegmentAndSections( + LCI, InputBinary.getSegmentLoadCommand(LCI), InputBinary, Writer, + SymtabStart, StringStart + NewStringsSize - SymtabStart, EHFrameStart, + EHFrameSize, DwarfSegmentSize, GapForDwarf, EndAddress); else if (LCI.C.cmd == MachO::LC_SEGMENT_64) - transferSegmentAndSections(LCI, InputBinary.getSegment64LoadCommand(LCI), - InputBinary, Writer, SymtabStart, - StringStart + NewStringsSize - SymtabStart, - DwarfSegmentSize, GapForDwarf, EndAddress); + transferSegmentAndSections( + LCI, InputBinary.getSegment64LoadCommand(LCI), InputBinary, Writer, + SymtabStart, StringStart + NewStringsSize - SymtabStart, EHFrameStart, + EHFrameSize, DwarfSegmentSize, GapForDwarf, EndAddress); } uint64_t DwarfVMAddr = alignTo(EndAddress, 0x1000); @@ -554,11 +592,19 @@ EntryRef.getString().size() + 1); } } - assert(OutFile.tell() == StringStart + NewStringsSize); + // Pad till the EH frame start. + OutFile.write_zeros(EHFrameStart - (StringStart + NewStringsSize)); + assert(OutFile.tell() == EHFrameStart); + + // Transfer eh_frame. + if (EHFrameSize > 0) + OutFile << EHFrameData; + assert(OutFile.tell() == EHFrameStart + EHFrameSize); + // Pad till the Dwarf segment start. - OutFile.write_zeros(DwarfSegmentStart - (StringStart + NewStringsSize)); + OutFile.write_zeros(DwarfSegmentStart - (EHFrameStart + EHFrameSize)); assert(OutFile.tell() == DwarfSegmentStart); // Emit the Dwarf sections contents.