From d2d3ebb81992e107edf95c1c136d7a342d9b1418 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 16 Apr 2017 16:03:39 +0000 Subject: Vendor import of lld trunk r300422: https://llvm.org/svn/llvm-project/lld/trunk@300422 --- ELF/MapFile.cpp | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 ELF/MapFile.cpp (limited to 'ELF/MapFile.cpp') diff --git a/ELF/MapFile.cpp b/ELF/MapFile.cpp new file mode 100644 index 000000000000..31c8091bb6a1 --- /dev/null +++ b/ELF/MapFile.cpp @@ -0,0 +1,131 @@ +//===- MapFile.cpp --------------------------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the -Map option. It shows lists in order and +// hierarchically the output sections, input sections, input files and +// symbol: +// +// Address Size Align Out In File Symbol +// ================================================================= +// 00201000 00000015 4 .text +// 00201000 0000000e 4 .text +// 00201000 0000000e 4 test.o +// 0020100e 00000000 0 local +// 00201005 00000000 0 f(int) +// +//===----------------------------------------------------------------------===// + +#include "MapFile.h" +#include "InputFiles.h" +#include "Strings.h" + +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; +using namespace llvm::object; + +using namespace lld; +using namespace lld::elf; + +static void writeOutSecLine(raw_fd_ostream &OS, int Width, uint64_t Address, + uint64_t Size, uint64_t Align, StringRef Name) { + OS << format("%0*llx %0*llx %5lld ", Width, Address, Width, Size, Align) + << left_justify(Name, 7); +} + +static void writeInSecLine(raw_fd_ostream &OS, int Width, uint64_t Address, + uint64_t Size, uint64_t Align, StringRef Name) { + // Pass an empty name to align the text to the correct column. + writeOutSecLine(OS, Width, Address, Size, Align, ""); + OS << ' ' << left_justify(Name, 7); +} + +static void writeFileLine(raw_fd_ostream &OS, int Width, uint64_t Address, + uint64_t Size, uint64_t Align, StringRef Name) { + // Pass an empty name to align the text to the correct column. + writeInSecLine(OS, Width, Address, Size, Align, ""); + OS << ' ' << left_justify(Name, 7); +} + +static void writeSymbolLine(raw_fd_ostream &OS, int Width, uint64_t Address, + uint64_t Size, StringRef Name) { + // Pass an empty name to align the text to the correct column. + writeFileLine(OS, Width, Address, Size, 0, ""); + OS << ' ' << left_justify(Name, 7); +} + +template +static void writeInputSection(raw_fd_ostream &OS, const InputSection *IS, + StringRef &PrevName) { + int Width = ELFT::Is64Bits ? 16 : 8; + StringRef Name = IS->Name; + if (Name != PrevName) { + writeInSecLine(OS, Width, IS->OutSec->Addr + IS->OutSecOff, IS->getSize(), + IS->Alignment, Name); + OS << '\n'; + PrevName = Name; + } + + elf::ObjectFile *File = IS->template getFile(); + if (!File) + return; + writeFileLine(OS, Width, IS->OutSec->Addr + IS->OutSecOff, IS->getSize(), + IS->Alignment, toString(File)); + OS << '\n'; + + for (SymbolBody *Sym : File->getSymbols()) { + auto *DR = dyn_cast(Sym); + if (!DR) + continue; + if (DR->Section != IS) + continue; + if (DR->isSection()) + continue; + writeSymbolLine(OS, Width, Sym->getVA(), Sym->getSize(), + toString(*Sym)); + OS << '\n'; + } +} + +template +static void writeMapFile2(raw_fd_ostream &OS, + ArrayRef OutputSections) { + int Width = ELFT::Is64Bits ? 16 : 8; + + OS << left_justify("Address", Width) << ' ' << left_justify("Size", Width) + << " Align Out In File Symbol\n"; + + for (OutputSection *Sec : OutputSections) { + writeOutSecLine(OS, Width, Sec->Addr, Sec->Size, Sec->Alignment, Sec->Name); + OS << '\n'; + + StringRef PrevName = ""; + for (InputSection *IS : Sec->Sections) { + writeInputSection(OS, IS, PrevName); + } + } +} + +template +void elf::writeMapFile(ArrayRef OutputSections) { + if (Config->MapFile.empty()) + return; + + std::error_code EC; + raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None); + if (EC) + error("cannot open " + Config->MapFile + ": " + EC.message()); + else + writeMapFile2(OS, OutputSections); +} + +template void elf::writeMapFile(ArrayRef); +template void elf::writeMapFile(ArrayRef); +template void elf::writeMapFile(ArrayRef); +template void elf::writeMapFile(ArrayRef); -- cgit v1.3