Skip to content

Commit

Permalink
[ELF] Add .eh_frame pieces to map file
Browse files Browse the repository at this point in the history
This patch is a simplified version of https://reviews.llvm.org/D42960
written by Andrew Ng.

Differential Revision: https://reviews.llvm.org/D44168

llvm-svn: 327574
  • Loading branch information
rui314 committed Mar 14, 2018
1 parent 6366efe commit a5c1ed3
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 3 deletions.
42 changes: 42 additions & 0 deletions lld/ELF/MapFile.cpp
Expand Up @@ -112,6 +112,43 @@ getSymbolStrings(ArrayRef<Symbol *> Syms) {
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<EhSectionPiece> 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;
Expand Down Expand Up @@ -141,6 +178,11 @@ void elf::writeMapFile() {

// 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])
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/SyntheticSections.h
Expand Up @@ -83,6 +83,7 @@ class EhFrameSection final : public SyntheticSection {
};

std::vector<FdeData> getFdeData() const;
ArrayRef<CieRecord *> getCieRecords() const { return CieRecords; }

private:
uint64_t Size = 0;
Expand Down
2 changes: 2 additions & 0 deletions lld/test/ELF/Inputs/map-file2.s
@@ -1,5 +1,7 @@
foo:
.cfi_startproc
nop
.cfi_endproc
.global bar
bar:
nop
Expand Down
10 changes: 7 additions & 3 deletions lld/test/ELF/map-file.s
Expand Up @@ -15,6 +15,8 @@

.global _start
_start:
.cfi_startproc
.cfi_endproc
.quad sharedFoo
.quad sharedBar
.byte 0xe8
Expand All @@ -26,8 +28,8 @@ _start:
.global _Z1fi
_Z1fi:
.cfi_startproc
.cfi_endproc
nop
.cfi_endproc
.weak bar
bar:
.long bar - .
Expand All @@ -51,8 +53,10 @@ labs = 0x1AB5
// CHECK-NEXT: 00000000002002d0 0000000000000030 8 <internal>:(.rela.dyn)
// CHECK-NEXT: 0000000000200300 0000000000000030 8 .rela.plt
// CHECK-NEXT: 0000000000200300 0000000000000030 8 <internal>:(.rela.plt)
// CHECK-NEXT: 0000000000200330 0000000000000030 8 .eh_frame
// CHECK-NEXT: 0000000000200330 0000000000000030 8 <internal>:(.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
Expand Down

0 comments on commit a5c1ed3

Please sign in to comment.