[ELF] Pass Ctx & to MapFile

This commit is contained in:
Fangrui Song 2024-09-29 15:39:52 -07:00
parent 5c33424778
commit 17473182f5
3 changed files with 21 additions and 19 deletions

View File

@ -44,7 +44,7 @@ static constexpr char indent8[] = " "; // 8 spaces
static constexpr char indent16[] = " "; // 16 spaces
// Print out the first three columns of a line.
static void writeHeader(raw_ostream &os, uint64_t vma, uint64_t lma,
static void writeHeader(Ctx &ctx, raw_ostream &os, uint64_t vma, uint64_t lma,
uint64_t size, uint64_t align) {
if (ctx.arg.is64)
os << format("%16llx %16llx %8llx %5lld ", vma, lma, size, align);
@ -90,14 +90,14 @@ static SymbolMapTy getSectionSyms(ArrayRef<Defined *> syms) {
// Demangling symbols (which is what toString() does) is slow, so
// we do that in batch using parallel-for.
static DenseMap<Symbol *, std::string>
getSymbolStrings(ArrayRef<Defined *> syms) {
getSymbolStrings(Ctx &ctx, ArrayRef<Defined *> syms) {
auto strs = std::make_unique<std::string[]>(syms.size());
parallelFor(0, syms.size(), [&](size_t i) {
raw_string_ostream os(strs[i]);
OutputSection *osec = syms[i]->getOutputSection();
uint64_t vma = syms[i]->getVA();
uint64_t lma = osec ? osec->getLMA() + vma - osec->getVA(0) : 0;
writeHeader(os, vma, lma, syms[i]->getSize(), 1);
writeHeader(ctx, os, vma, lma, syms[i]->getSize(), 1);
os << indent16 << toString(*syms[i]);
});
@ -113,7 +113,7 @@ getSymbolStrings(ArrayRef<Defined *> syms) {
// .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, const EhFrameSection *sec) {
static void printEhFrame(Ctx &ctx, raw_ostream &os, const EhFrameSection *sec) {
std::vector<EhSectionPiece> pieces;
auto add = [&](const EhSectionPiece &p) {
@ -139,18 +139,18 @@ static void printEhFrame(raw_ostream &os, const EhFrameSection *sec) {
// Print out section pieces.
const OutputSection *osec = sec->getOutputSection();
for (EhSectionPiece &p : pieces) {
writeHeader(os, osec->addr + p.outputOff, osec->getLMA() + p.outputOff,
writeHeader(ctx, os, osec->addr + p.outputOff, osec->getLMA() + p.outputOff,
p.size, 1);
os << indent8 << toString(p.sec->file) << ":(" << p.sec->name << "+0x"
<< Twine::utohexstr(p.inputOff) + ")\n";
}
}
static void writeMapFile(raw_fd_ostream &os) {
static void writeMapFile(Ctx &ctx, raw_fd_ostream &os) {
// Collect symbol info that we want to print out.
std::vector<Defined *> syms = getSymbols();
SymbolMapTy sectionSyms = getSectionSyms(syms);
DenseMap<Symbol *, std::string> symStr = getSymbolStrings(syms);
DenseMap<Symbol *, std::string> symStr = getSymbolStrings(ctx, syms);
// Print out the header line.
int w = ctx.arg.is64 ? 16 : 8;
@ -163,7 +163,7 @@ static void writeMapFile(raw_fd_ostream &os) {
if (assign->provide && !assign->sym)
continue;
uint64_t lma = osec ? osec->getLMA() + assign->addr - osec->getVA(0) : 0;
writeHeader(os, assign->addr, lma, assign->size, 1);
writeHeader(ctx, os, assign->addr, lma, assign->size, 1);
os << assign->commandString << '\n';
continue;
}
@ -171,7 +171,8 @@ static void writeMapFile(raw_fd_ostream &os) {
continue;
osec = &cast<OutputDesc>(cmd)->osec;
writeHeader(os, osec->addr, osec->getLMA(), osec->size, osec->addralign);
writeHeader(ctx, os, osec->addr, osec->getLMA(), osec->size,
osec->addralign);
os << osec->name << '\n';
// Dump symbols for each input section.
@ -179,11 +180,11 @@ static void writeMapFile(raw_fd_ostream &os) {
if (auto *isd = dyn_cast<InputSectionDescription>(subCmd)) {
for (InputSection *isec : isd->sections) {
if (auto *ehSec = dyn_cast<EhFrameSection>(isec)) {
printEhFrame(os, ehSec);
printEhFrame(ctx, os, ehSec);
continue;
}
writeHeader(os, isec->getVA(), osec->getLMA() + isec->outSecOff,
writeHeader(ctx, os, isec->getVA(), osec->getLMA() + isec->outSecOff,
isec->getSize(), isec->addralign);
os << indent8 << toString(isec) << '\n';
for (Symbol *sym : llvm::make_first_range(sectionSyms[isec]))
@ -193,7 +194,7 @@ static void writeMapFile(raw_fd_ostream &os) {
}
if (auto *data = dyn_cast<ByteCommand>(subCmd)) {
writeHeader(os, osec->addr + data->offset,
writeHeader(ctx, os, osec->addr + data->offset,
osec->getLMA() + data->offset, data->size, 1);
os << indent8 << data->commandString << '\n';
continue;
@ -202,7 +203,7 @@ static void writeMapFile(raw_fd_ostream &os) {
if (auto *assign = dyn_cast<SymbolAssignment>(subCmd)) {
if (assign->provide && !assign->sym)
continue;
writeHeader(os, assign->addr,
writeHeader(ctx, os, assign->addr,
osec->getLMA() + assign->addr - osec->getVA(0),
assign->size, 1);
os << indent8 << assign->commandString << '\n';
@ -223,7 +224,7 @@ static void writeMapFile(raw_fd_ostream &os) {
//
// In this case, strlen is defined by libc.so.6 and used by other two
// files.
static void writeCref(raw_fd_ostream &os) {
static void writeCref(Ctx &ctx, raw_fd_ostream &os) {
// Collect symbols and files.
MapVector<Symbol *, SetVector<InputFile *>> map;
for (ELFFileBase *file : ctx.objectFiles) {
@ -256,7 +257,7 @@ static void writeCref(raw_fd_ostream &os) {
}
}
void elf::writeMapAndCref() {
void elf::writeMapAndCref(Ctx &ctx) {
if (ctx.arg.mapFile.empty() && !ctx.arg.cref)
return;
@ -272,7 +273,7 @@ void elf::writeMapAndCref() {
}
if (!ctx.arg.mapFile.empty())
writeMapFile(os);
writeMapFile(ctx, os);
if (ctx.arg.cref)
writeCref(os);
writeCref(ctx, os);
}

View File

@ -10,7 +10,8 @@
#define LLD_ELF_MAPFILE_H
namespace lld::elf {
void writeMapAndCref();
struct Ctx;
void writeMapAndCref(Ctx &);
}
#endif

View File

@ -336,7 +336,7 @@ template <class ELFT> void Writer<ELFT>::run() {
// Handle --print-map(-M)/--Map and --cref. Dump them before checkSections()
// because the files may be useful in case checkSections() or openFile()
// fails, for example, due to an erroneous file size.
writeMapAndCref();
writeMapAndCref(ctx);
// Handle --print-memory-usage option.
if (ctx.arg.printMemoryUsage)