Index: lld/trunk/ELF/MapFile.cpp =================================================================== --- lld/trunk/ELF/MapFile.cpp +++ lld/trunk/ELF/MapFile.cpp @@ -112,6 +112,43 @@ return Ret; } +// Print .eh_frame contents. Since the section consists of EhSectionPieces, +// we need a specialized printer for that section. +// +// .eh_frame tend to contain a lot of section pieces that are contiguous +// both in input file and output file. Such pieces are squashed before +// being displayed to make output compact. +static void printEhFrame(raw_ostream &OS, OutputSection *OSec) { + std::vector Pieces; + + auto Add = [&](const EhSectionPiece &P) { + // If P is adjacent to Last, squash the two. + if (!Pieces.empty()) { + EhSectionPiece &Last = Pieces.back(); + if (Last.Sec == P.Sec && Last.InputOff + Last.Size == P.InputOff && + Last.OutputOff + Last.Size == P.OutputOff) { + Last.Size += P.Size; + return; + } + } + Pieces.push_back(P); + }; + + // Gather section pieces. + for (const CieRecord *Rec : InX::EhFrame->getCieRecords()) { + Add(*Rec->Cie); + for (const EhSectionPiece *Fde : Rec->Fdes) + Add(*Fde); + } + + // Print out section pieces. + for (EhSectionPiece &P : Pieces) { + writeHeader(OS, OSec->Addr + P.OutputOff, P.Size, 0); + OS << Indent8 << toString(P.Sec->File) << ":(" << P.Sec->Name << "+0x" + << Twine::utohexstr(P.InputOff) + ")\n"; + } +} + void elf::writeMapFile() { if (Config->MapFile.empty()) return; @@ -141,6 +178,11 @@ // Dump symbols for each input section. for (InputSection *IS : getInputSections(OSec)) { + if (IS == InX::EhFrame) { + printEhFrame(OS, OSec); + continue; + } + writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), IS->Alignment); OS << Indent8 << toString(IS) << '\n'; for (Symbol *Sym : SectionSyms[IS]) Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -83,6 +83,7 @@ }; std::vector getFdeData() const; + ArrayRef getCieRecords() const { return CieRecords; } private: uint64_t Size = 0; Index: lld/trunk/test/ELF/Inputs/map-file2.s =================================================================== --- lld/trunk/test/ELF/Inputs/map-file2.s +++ lld/trunk/test/ELF/Inputs/map-file2.s @@ -1,5 +1,7 @@ foo: +.cfi_startproc nop +.cfi_endproc .global bar bar: nop Index: lld/trunk/test/ELF/map-file.s =================================================================== --- lld/trunk/test/ELF/map-file.s +++ lld/trunk/test/ELF/map-file.s @@ -15,6 +15,8 @@ .global _start _start: +.cfi_startproc +.cfi_endproc .quad sharedFoo .quad sharedBar .byte 0xe8 @@ -26,8 +28,8 @@ .global _Z1fi _Z1fi: .cfi_startproc -.cfi_endproc nop +.cfi_endproc .weak bar bar: .long bar - . @@ -51,8 +53,10 @@ // CHECK-NEXT: 00000000002002d0 0000000000000030 8 :(.rela.dyn) // CHECK-NEXT: 0000000000200300 0000000000000030 8 .rela.plt // CHECK-NEXT: 0000000000200300 0000000000000030 8 :(.rela.plt) -// CHECK-NEXT: 0000000000200330 0000000000000030 8 .eh_frame -// CHECK-NEXT: 0000000000200330 0000000000000030 8 :(.eh_frame) +// CHECK-NEXT: 0000000000200330 0000000000000060 8 .eh_frame +// CHECK-NEXT: 0000000000200330 000000000000002c 0 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x0) +// CHECK-NEXT: 0000000000200360 0000000000000014 0 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x2c) +// CHECK-NEXT: 0000000000200378 0000000000000018 0 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.eh_frame+0x18) // CHECK-NEXT: 0000000000201000 000000000000002d 4 .text // CHECK-NEXT: 0000000000201000 0000000000000028 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text) // CHECK-NEXT: 0000000000201000 0000000000000000 0 _start