From c5b2b8e19fe33b30e233b928fe3728bca54418de Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 21 Jan 2020 05:44:00 -0800 Subject: [PATCH] arch,base,cpu,kern,sim: Encapsulate symbols in a class. The SymbolTable class had been tracking symbols as two independent pieces, a name and an address, and acted as a way to translate between them. Symbols can be more complex than that, and so this change encapsulates the information associated with a symbol in a new class. As a step towards simplifying the API for reading symbols from a binary, this change also adds a "binding" field to that class so that global, local and weak symbols can all go in the same table and be differentiated later as needed. That should unify the current API which has a method for each symbol type. While the innards of SymbolTable were being reworked, this change also makes that class more STL like by adding iterators, and begin and end methods. These iterate over a new vector which holds all the symbols. The address and name keyed maps now hold indexes into that vector instead of the other half of the symbol. Change-Id: I8084f86fd737f697ec041bac86a635a315fd1194 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24784 Reviewed-by: Giacomo Travaglini Maintainer: Gabe Black Tested-by: kokoro --- src/arch/arm/freebsd/fs_workload.cc | 3 +- src/arch/arm/insts/static_inst.cc | 38 ++++--- src/arch/arm/linux/fs_workload.cc | 3 +- src/arch/arm/stacktrace.cc | 7 +- src/arch/generic/linux/threadinfo.hh | 7 +- src/arch/mips/isa/formats/branch.isa | 14 +-- src/arch/power/insts/branch.cc | 32 +++--- src/arch/riscv/bare_metal/fs_workload.hh | 4 +- src/arch/sparc/fs_workload.hh | 4 +- src/arch/sparc/insts/branch.cc | 13 +-- src/arch/x86/stacktrace.cc | 12 +- src/base/loader/elf_object.cc | 18 ++- src/base/loader/symtab.cc | 74 ++++++++---- src/base/loader/symtab.hh | 139 ++++++++++------------- src/cpu/base.cc | 13 ++- src/cpu/exetrace.cc | 23 ++-- src/cpu/profile.cc | 23 ++-- src/kern/linux/helpers.cc | 29 ++--- src/sim/kernel_workload.hh | 4 +- src/sim/pseudo_inst.cc | 10 +- src/sim/workload.hh | 14 +-- src/unittest/nmtest.cc | 23 ++-- src/unittest/symtest.cc | 10 +- 23 files changed, 276 insertions(+), 241 deletions(-) diff --git a/src/arch/arm/freebsd/fs_workload.cc b/src/arch/arm/freebsd/fs_workload.cc index 91a1d895c..ea99b4273 100644 --- a/src/arch/arm/freebsd/fs_workload.cc +++ b/src/arch/arm/freebsd/fs_workload.cc @@ -88,8 +88,7 @@ FsFreebsd::initState() // Check if the kernel image has a symbol that tells us it supports // device trees. - Addr addr; - fatal_if(!kernelSymtab->findAddress("fdt_get_range", addr), + fatal_if(kernelSymtab->find("fdt_get_range") == kernelSymtab->end(), "Kernel must have fdt support."); fatal_if(params()->dtb_filename == "", "dtb file is not specified."); diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index 70e5fb952..9c686f6ca 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -393,18 +393,19 @@ void ArmStaticInst::printTarget(std::ostream &os, Addr target, const Loader::SymbolTable *symtab) const { - Addr symbolAddr; - std::string symbol; - - if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) { - ccprintf(os, "<%s", symbol); - if (symbolAddr != target) - ccprintf(os, "+%d>", target - symbolAddr); - else - ccprintf(os, ">"); - } else { - ccprintf(os, "%#x", target); + if (symtab) { + auto it = symtab->findNearest(target); + if (it != symtab->end()) { + ccprintf(os, "<%s", it->name); + Addr delta = target - it->address; + if (delta) + ccprintf(os, "+%d>", delta); + else + ccprintf(os, ">"); + return; + } } + ccprintf(os, "%#x", target); } void @@ -477,13 +478,14 @@ ArmStaticInst::printMemSymbol(std::ostream &os, const Addr addr, const std::string &suffix) const { - Addr symbolAddr; - std::string symbol; - if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) { - ccprintf(os, "%s%s", prefix, symbol); - if (symbolAddr != addr) - ccprintf(os, "+%d", addr - symbolAddr); - ccprintf(os, suffix); + if (symtab) { + auto it = symtab->findNearest(addr); + if (it != symtab->end()) { + ccprintf(os, "%s%s", prefix, it->name); + if (it->address != addr) + ccprintf(os, "+%d", addr - it->address); + ccprintf(os, suffix); + } } } diff --git a/src/arch/arm/linux/fs_workload.cc b/src/arch/arm/linux/fs_workload.cc index cc28193d9..9ebb1172b 100644 --- a/src/arch/arm/linux/fs_workload.cc +++ b/src/arch/arm/linux/fs_workload.cc @@ -82,11 +82,10 @@ FsLinux::initState() } // Setup boot data structure - Addr addr; // Check if the kernel image has a symbol that tells us it supports // device trees. bool kernel_has_fdt_support = - kernelSymtab->findAddress("unflatten_device_tree", addr); + kernelSymtab->find("unflatten_device_tree") != kernelSymtab->end(); bool dtb_file_specified = params()->dtb_filename != ""; if (kernel_has_fdt_support && dtb_file_specified) { diff --git a/src/arch/arm/stacktrace.cc b/src/arch/arm/stacktrace.cc index d0e702c6b..535cddd02 100644 --- a/src/arch/arm/stacktrace.cc +++ b/src/arch/arm/stacktrace.cc @@ -47,11 +47,10 @@ readSymbol(ThreadContext *tc, const std::string name) PortProxy &vp = tc->getVirtProxy(); const auto *symtab = tc->getSystemPtr()->workload->symtab(tc); - Addr addr; - if (!symtab->findAddress(name, addr)) - panic("thread info not compiled into kernel\n"); + auto it = symtab->find(name); + panic_if(it == symtab->end(), "Thread info not compiled into kernel."); - return vp.read(addr, GuestByteOrder); + return vp.read(it->address, GuestByteOrder); } ProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc) diff --git a/src/arch/generic/linux/threadinfo.hh b/src/arch/generic/linux/threadinfo.hh index 83e41b97a..5e058cf2e 100644 --- a/src/arch/generic/linux/threadinfo.hh +++ b/src/arch/generic/linux/threadinfo.hh @@ -46,15 +46,16 @@ class ThreadInfo bool get_data(const char *symbol, T &data) { - Addr addr = 0; - if (!sys->workload->symtab(tc)->findAddress(symbol, addr)) { + auto *symtab = sys->workload->symtab(tc); + auto it = symtab->find(symbol); + if (it == symtab->end()) { warn_once("Unable to find kernel symbol %s\n", symbol); warn_once("Kernel not compiled with task_struct info; can't get " "currently executing task/process/thread name/ids!\n"); return false; } - data = tc->getVirtProxy().read(addr, TheISA::GuestByteOrder); + data = tc->getVirtProxy().read(it->address, TheISA::GuestByteOrder); return true; } diff --git a/src/arch/mips/isa/formats/branch.isa b/src/arch/mips/isa/formats/branch.isa index 06662f092..4975a1321 100644 --- a/src/arch/mips/isa/formats/branch.isa +++ b/src/arch/mips/isa/formats/branch.isa @@ -193,11 +193,11 @@ output decoder {{ Addr target = pc + 4 + disp; - std::string str; - if (symtab && symtab->findSymbol(target, str)) - ss << str; + Loader::SymbolTable::const_iterator it; + if (symtab && (it = symtab->find(target)) != symtab->end()) + ss << it->name; else - ccprintf(ss, "0x%x", target); + ccprintf(ss, "%#x", target); return ss.str(); } @@ -213,9 +213,9 @@ output decoder {{ Addr npc = pc + 4; ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp); } else if (_numSrcRegs == 0) { - std::string str; - if (symtab && symtab->findSymbol(disp, str)) - ss << str; + Loader::SymbolTable::const_iterator it; + if (symtab && (it = symtab->find(disp)) != symtab->end()) + ss << it->name; else ccprintf(ss, "0x%x", disp); } else if (_numSrcRegs == 1) { diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc index 5fe0c4e8f..3511b6b3c 100644 --- a/src/arch/power/insts/branch.cc +++ b/src/arch/power/insts/branch.cc @@ -68,11 +68,11 @@ BranchPCRel::generateDisassembly( Addr target = pc + disp; - std::string str; - if (symtab && symtab->findSymbol(target, str)) - ss << str; + Loader::SymbolTable::const_iterator it; + if (symtab && (it = symtab->find(target)) != symtab->end()) + ss << it->name; else - ccprintf(ss, "0x%x", target); + ccprintf(ss, "%#x", target); return ss.str(); } @@ -91,11 +91,11 @@ BranchNonPCRel::generateDisassembly( ccprintf(ss, "%-10s ", mnemonic); - std::string str; - if (symtab && symtab->findSymbol(targetAddr, str)) - ss << str; + Loader::SymbolTable::const_iterator it; + if (symtab && (it = symtab->find(targetAddr)) != symtab->end()) + ss << it->name; else - ccprintf(ss, "0x%x", targetAddr); + ccprintf(ss, "%#x", targetAddr); return ss.str(); } @@ -118,11 +118,11 @@ BranchPCRelCond::generateDisassembly( Addr target = pc + disp; - std::string str; - if (symtab && symtab->findSymbol(target, str)) - ss << str; + Loader::SymbolTable::const_iterator it; + if (symtab && (it = symtab->find(target)) != symtab->end()) + ss << it->name; else - ccprintf(ss, "0x%x", target); + ccprintf(ss, "%#x", target); return ss.str(); } @@ -143,11 +143,11 @@ BranchNonPCRelCond::generateDisassembly( ss << bo << ", " << bi << ", "; - std::string str; - if (symtab && symtab->findSymbol(targetAddr, str)) - ss << str; + Loader::SymbolTable::const_iterator it; + if (symtab && (it = symtab->find(targetAddr)) != symtab->end()) + ss << it->name; else - ccprintf(ss, "0x%x", targetAddr); + ccprintf(ss, "%#x", targetAddr); return ss.str(); } diff --git a/src/arch/riscv/bare_metal/fs_workload.hh b/src/arch/riscv/bare_metal/fs_workload.hh index 2e26ad1b2..a142d4759 100644 --- a/src/arch/riscv/bare_metal/fs_workload.hh +++ b/src/arch/riscv/bare_metal/fs_workload.hh @@ -55,9 +55,9 @@ class BareMetal : public RiscvISA::FsWorkload return bootloaderSymtab; } bool - insertSymbol(Addr address, const std::string &symbol) override + insertSymbol(const Loader::Symbol &symbol) override { - return bootloaderSymtab->insert(address, symbol); + return bootloaderSymtab->insert(symbol); } }; diff --git a/src/arch/sparc/fs_workload.hh b/src/arch/sparc/fs_workload.hh index 0323714e7..650ed37a0 100644 --- a/src/arch/sparc/fs_workload.hh +++ b/src/arch/sparc/fs_workload.hh @@ -61,9 +61,9 @@ class FsWorkload : public Workload } bool - insertSymbol(Addr address, const std::string &symbol) override + insertSymbol(const Loader::Symbol &symbol) override { - return defaultSymtab.insert(address, symbol); + return defaultSymtab.insert(symbol); } }; diff --git a/src/arch/sparc/insts/branch.cc b/src/arch/sparc/insts/branch.cc index 8ffa24165..52517e620 100644 --- a/src/arch/sparc/insts/branch.cc +++ b/src/arch/sparc/insts/branch.cc @@ -77,18 +77,17 @@ BranchDisp::generateDisassembly( Addr pc, const Loader::SymbolTable *symtab) const { std::stringstream response; - std::string symbol; - Addr symbol_addr; Addr target = disp + pc; printMnemonic(response, mnemonic); - ccprintf(response, "0x%x", target); + ccprintf(response, "%#x", target); - if (symtab && symtab->findNearestSymbol(target, symbol, symbol_addr)) { - ccprintf(response, " <%s", symbol); - if (symbol_addr != target) - ccprintf(response, "+%d>", target - symbol_addr); + Loader::SymbolTable::const_iterator it; + if (symtab && (it = symtab->findNearest(target)) != symtab->end()) { + ccprintf(response, " <%s", it->name); + if (it->address != target) + ccprintf(response, "+%d>", target - it->address); else ccprintf(response, ">"); } diff --git a/src/arch/x86/stacktrace.cc b/src/arch/x86/stacktrace.cc index a7c548ea2..0e5341c00 100644 --- a/src/arch/x86/stacktrace.cc +++ b/src/arch/x86/stacktrace.cc @@ -47,11 +47,10 @@ readSymbol(ThreadContext *tc, const std::string name) PortProxy &vp = tc->getVirtProxy(); const auto *symtab = tc->getSystemPtr()->workload->symtab(tc); - Addr addr; - if (!symtab->findAddress(name, addr)) - panic("thread info not compiled into kernel\n"); + auto it = symtab->find(name); + panic_if(it == symtab->end(), "Thread info not compiled into kernel."); - return vp.read(addr, GuestByteOrder); + return vp.read(it->address, GuestByteOrder); } ProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc) @@ -196,14 +195,15 @@ StackTrace::dump() std::string symbol; for (int i = 0, size = stack.size(); i < size; ++i) { Addr addr = stack[size - i - 1]; + Loader::SymbolTable::const_iterator it; if (addr == user) symbol = "user"; else if (addr == console) symbol = "console"; else if (addr == unknown) symbol = "unknown"; - else - symtab->findSymbol(addr, symbol); + else if ((it = symtab->find(addr)) != symtab->end()) + symbol = it->name; DPRINTFN("%#x: %s\n", addr, symbol); } diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 8876a8735..ceafc53fb 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -341,7 +341,23 @@ ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask, elf_strptr(elf, shdr.sh_link, sym.st_name); if (sym_name && sym_name[0] != '$') { Addr value = sym.st_value - base + offset; - if (symtab->insert(value & mask, sym_name)) { + Loader::Symbol symbol; + symbol.address = value & mask; + symbol.name = sym_name; + switch (binding) { + case STB_GLOBAL: + symbol.binding = Loader::Symbol::Binding::Global; + break; + case STB_LOCAL: + symbol.binding = Loader::Symbol::Binding::Local; + break; + case STB_WEAK: + symbol.binding = Loader::Symbol::Binding::Weak; + break; + default: + panic("Unrecognized binding type"); + } + if (symtab->insert(symbol)) { DPRINTF(Loader, "Symbol: %-40s value %#x\n", sym_name, value); } diff --git a/src/base/loader/symtab.cc b/src/base/loader/symtab.cc index 9e0f1f68c..a8e1a1534 100644 --- a/src/base/loader/symtab.cc +++ b/src/base/loader/symtab.cc @@ -35,6 +35,7 @@ #include "base/logging.hh" #include "base/str.hh" +#include "base/trace.hh" #include "base/types.hh" #include "sim/serialize.hh" @@ -48,26 +49,48 @@ SymbolTable *debugSymbolTable = NULL; void SymbolTable::clear() { - addrTable.clear(); - symbolTable.clear(); + addrMap.clear(); + nameMap.clear(); + symbols.clear(); } bool -SymbolTable::insert(Addr address, string symbol) +SymbolTable::insert(const Symbol &symbol) { - if (symbol.empty()) + if (symbol.name.empty()) return false; - if (!symbolTable.insert(make_pair(symbol, address)).second) + int idx = symbols.size(); + + if (!nameMap.insert({ symbol.name, idx }).second) return false; // There can be multiple symbols for the same address, so always // update the addrTable multimap when we see a new symbol name. - addrTable.insert(make_pair(address, symbol)); + addrMap.insert({ symbol.address, idx }); + + symbols.emplace_back(symbol); return true; } +bool +SymbolTable::insert(const SymbolTable &other) +{ + // Check if any symbol in other already exists in our table. + NameMap intersection; + std::set_intersection(other.nameMap.begin(), other.nameMap.end(), + nameMap.begin(), nameMap.end(), + std::inserter(intersection, intersection.begin()), + nameMap.value_comp()); + if (!intersection.empty()) + return false; + + for (const Symbol &symbol: other) + insert(symbol); + + return true; +} bool SymbolTable::load(const string &filename) @@ -92,51 +115,54 @@ SymbolTable::load(const string &filename) if (address.empty()) return false; - string symbol = buffer.substr(idx + 1); - eat_white(symbol); - if (symbol.empty()) + string name = buffer.substr(idx + 1); + eat_white(name); + if (name.empty()) return false; Addr addr; if (!to_number(address, addr)) return false; - if (!insert(addr, symbol)) + if (!insert({ Symbol::Binding::Global, name, addr })) return false; } file.close(); - return true; } void SymbolTable::serialize(const string &base, CheckpointOut &cp) const { - paramOut(cp, base + ".size", addrTable.size()); + paramOut(cp, base + ".size", symbols.size()); int i = 0; - ATable::const_iterator p, end = addrTable.end(); - for (p = addrTable.begin(); p != end; ++p) { - paramOut(cp, csprintf("%s.addr_%d", base, i), p->first); - paramOut(cp, csprintf("%s.symbol_%d", base, i), p->second); - ++i; + for (auto &symbol: symbols) { + paramOut(cp, csprintf("%s.addr_%d", base, i), symbol.address); + paramOut(cp, csprintf("%s.symbol_%d", base, i), symbol.name); + paramOut(cp, csprintf("%s.binding_%d", base, i), (int)symbol.binding); + i++; } } void -SymbolTable::unserialize(const string &base, CheckpointIn &cp) +SymbolTable::unserialize(const string &base, CheckpointIn &cp, + Symbol::Binding default_binding) { clear(); int size; paramIn(cp, base + ".size", size); for (int i = 0; i < size; ++i) { - Addr addr; - std::string symbol; - - paramIn(cp, csprintf("%s.addr_%d", base, i), addr); - paramIn(cp, csprintf("%s.symbol_%d", base, i), symbol); - insert(addr, symbol); + Addr address; + std::string name; + Symbol::Binding binding = default_binding; + + paramIn(cp, csprintf("%s.addr_%d", base, i), address); + paramIn(cp, csprintf("%s.symbol_%d", base, i), name); + if (!optParamIn(cp, csprintf("%s.binding_%d", base, i), binding)) + binding = default_binding; + insert({binding, name, address}); } } diff --git a/src/base/loader/symtab.hh b/src/base/loader/symtab.hh index b09d8545f..38e97ea9c 100644 --- a/src/base/loader/symtab.hh +++ b/src/base/loader/symtab.hh @@ -32,140 +32,123 @@ #include #include #include +#include +#include "base/trace.hh" #include "base/types.hh" #include "sim/serialize.hh" namespace Loader { -class SymbolTable +struct Symbol { - public: - typedef std::multimap ATable; - typedef std::map STable; + enum class Binding { + Global, + Local, + Weak + }; + + Binding binding; + std::string name; + Addr address; +}; +class SymbolTable +{ private: - ATable addrTable; - STable symbolTable; + typedef std::vector SymbolVector; + // Map addresses to an index into the symbol vector. + typedef std::multimap AddrMap; + // Map a symbol name to an index into the symbol vector. + typedef std::map NameMap; + + SymbolVector symbols; + AddrMap addrMap; + NameMap nameMap; - private: bool - upperBound(Addr addr, ATable::const_iterator &iter) const + upperBound(Addr addr, AddrMap::const_iterator &iter) const { // find first key *larger* than desired address - iter = addrTable.upper_bound(addr); + iter = addrMap.upper_bound(addr); // if very first key is larger, we're out of luck - if (iter == addrTable.begin()) + if (iter == addrMap.begin()) return false; return true; } public: - SymbolTable() {} - SymbolTable(const std::string &file) { load(file); } - ~SymbolTable() {} + typedef SymbolVector::iterator iterator; + typedef SymbolVector::const_iterator const_iterator; + + const_iterator begin() const { return symbols.begin(); } + const_iterator end() const { return symbols.end(); } void clear(); - bool insert(Addr address, std::string symbol); + // Insert either a single symbol or the contents of an entire symbol table + // into this one. + bool insert(const Symbol &symbol); + bool insert(const SymbolTable &other); bool load(const std::string &file); - const ATable &getAddrTable() const { return addrTable; } - const STable &getSymbolTable() const { return symbolTable; } - - public: void serialize(const std::string &base, CheckpointOut &cp) const; - void unserialize(const std::string &base, CheckpointIn &cp); + void unserialize(const std::string &base, CheckpointIn &cp, + Symbol::Binding default_binding=Symbol::Binding::Global); - public: - bool - findSymbol(Addr address, std::string &symbol) const + const_iterator + find(Addr address) const { - ATable::const_iterator i = addrTable.find(address); - if (i == addrTable.end()) - return false; + AddrMap::const_iterator i = addrMap.find(address); + if (i == addrMap.end()) + return end(); // There are potentially multiple symbols that map to the same // address. For simplicity, just return the first one. - symbol = (*i).second; - return true; + return symbols.begin() + i->second; } - bool - findAddress(const std::string &symbol, Addr &address) const + const_iterator + find(const std::string &name) const { - STable::const_iterator i = symbolTable.find(symbol); - if (i == symbolTable.end()) - return false; + NameMap::const_iterator i = nameMap.find(name); + if (i == nameMap.end()) + return end(); - address = (*i).second; - return true; + return symbols.begin() + i->second; } /// Find the nearest symbol equal to or less than the supplied /// address (e.g., the label for the enclosing function). /// @param addr The address to look up. - /// @param symbol Return reference for symbol string. - /// @param symaddr Return reference for symbol address. /// @param nextaddr Address of following symbol (for /// determining valid range of symbol). - /// @retval True if a symbol was found. - bool - findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr, - Addr &nextaddr) const + /// @retval A const_iterator which points to the symbol if found, or end. + const_iterator + findNearest(Addr addr, Addr &nextaddr) const { - ATable::const_iterator i; + AddrMap::const_iterator i = addrMap.end(); if (!upperBound(addr, i)) - return false; + return end(); nextaddr = i->first; --i; - symaddr = i->first; - symbol = i->second; - return true; + return symbols.begin() + i->second; } /// Overload for findNearestSymbol() for callers who don't care /// about nextaddr. - bool - findNearestSymbol(Addr addr, std::string &symbol, Addr &symaddr) const + const_iterator + findNearest(Addr addr) const { - ATable::const_iterator i; + AddrMap::const_iterator i = addrMap.end(); if (!upperBound(addr, i)) - return false; + return end(); --i; - symaddr = i->first; - symbol = i->second; - return true; - } - - - bool - findNearestAddr(Addr addr, Addr &symaddr, Addr &nextaddr) const - { - ATable::const_iterator i; - if (!upperBound(addr, i)) - return false; - - nextaddr = i->first; - --i; - symaddr = i->first; - return true; - } - - bool - findNearestAddr(Addr addr, Addr &symaddr) const - { - ATable::const_iterator i; - if (!upperBound(addr, i)) - return false; - - --i; - symaddr = i->first; - return true; + return symbols.begin() + i->second; } }; diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 36474829f..a74e285ca 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -757,15 +757,18 @@ BaseCPU::traceFunctionsInternal(Addr pc) // if pc enters different function, print new function symbol and // update saved range. Otherwise do nothing. if (pc < currentFunctionStart || pc >= currentFunctionEnd) { - string sym_str; - bool found = Loader::debugSymbolTable->findNearestSymbol( - pc, sym_str, currentFunctionStart, currentFunctionEnd); + auto it = Loader::debugSymbolTable->findNearest( + pc, currentFunctionEnd); - if (!found) { + string sym_str; + if (it == Loader::debugSymbolTable->end()) { // no symbol found: use addr as label - sym_str = csprintf("0x%x", pc); + sym_str = csprintf("%#x", pc); currentFunctionStart = pc; currentFunctionEnd = pc + 1; + } else { + sym_str = it->name; + currentFunctionStart = it->address; } ccprintf(*functionTraceStream, " (%d)\n%d: %s", diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 06154daa7..60c8fd0ac 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -76,27 +76,28 @@ Trace::ExeTracerRecord::traceInst(const StaticInstPtr &inst, bool ran) if (Debug::ExecThread) outs << "T" << thread->threadId() << " : "; - std::string sym_str; - Addr sym_addr; Addr cur_pc = pc.instAddr(); + Loader::SymbolTable::const_iterator it; if (Loader::debugSymbolTable && Debug::ExecSymbol && (!FullSystem || !inUserMode(thread)) && - Loader::debugSymbolTable->findNearestSymbol( - cur_pc, sym_str, sym_addr)) { - if (cur_pc != sym_addr) - sym_str += csprintf("+%d",cur_pc - sym_addr); - outs << "@" << sym_str; + (it = Loader::debugSymbolTable->findNearest(cur_pc)) != + Loader::debugSymbolTable->end()) { + Addr delta = cur_pc - it->address; + if (delta) + ccprintf(outs, "@%s+%d", it->name, delta); + else + ccprintf(outs, "@%s", it->name); } else { - outs << "0x" << hex << cur_pc; + ccprintf(outs, "%#x", cur_pc); } if (inst->isMicroop()) { - outs << "." << setw(2) << dec << pc.microPC(); + ccprintf(outs, ".%2d", pc.microPC()); } else { - outs << " "; + ccprintf(outs, " "); } - outs << " : "; + ccprintf(outs, " : "); // // Print decoded instruction diff --git a/src/cpu/profile.cc b/src/cpu/profile.cc index aa2cff892..fee0681cb 100644 --- a/src/cpu/profile.cc +++ b/src/cpu/profile.cc @@ -57,6 +57,7 @@ ProfileNode::dump(const string &symbol, uint64_t id, ccprintf(os, "\n"); + Loader::SymbolTable::const_iterator it; for (i = children.begin(); i != end; ++i) { Addr addr = i->first; string symbol; @@ -66,7 +67,9 @@ ProfileNode::dump(const string &symbol, uint64_t id, symbol = "console"; else if (addr == 3) symbol = "unknown"; - else if (!symtab->findSymbol(addr, symbol)) + else if ((it = symtab->find(addr)) != symtab->end()) + symbol = it->name; + else panic("could not find symbol for address %#x\n", addr); const ProfileNode *node = i->second; @@ -127,13 +130,15 @@ FunctionProfile::dump(ThreadContext *tc, ostream &os) const Addr pc = i->first; Counter count = i->second; - std::string symbol; - if (pc == 1) + Loader::SymbolTable::const_iterator it; + if (pc == 1) { ccprintf(os, "user %d\n", count); - else if (symtab->findSymbol(pc, symbol) && !symbol.empty()) - ccprintf(os, "%s %d\n", symbol, count); - else + } else if ((it = symtab->find(pc)) != symtab->end() && + !it->name.empty()) { + ccprintf(os, "%s %d\n", it->name, count); + } else { ccprintf(os, "%#x %d\n", pc, count); + } } ccprintf(os, ">>>function data\n"); @@ -145,9 +150,9 @@ FunctionProfile::sample(ProfileNode *node, Addr pc) { node->count++; - Addr symaddr; - if (symtab->findNearestAddr(pc, symaddr)) { - pc_count[symaddr]++; + auto it = symtab->findNearest(pc); + if (it != symtab->end()) { + pc_count[it->address]++; } else { // record PC even if we don't have a symbol to avoid // silently biasing the histogram diff --git a/src/kern/linux/helpers.cc b/src/kern/linux/helpers.cc index 9286ab071..80ff52632 100644 --- a/src/kern/linux/helpers.cc +++ b/src/kern/linux/helpers.cc @@ -96,24 +96,25 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os) const auto *symtab = system->workload->symtab(tc); PortProxy &proxy = tc->getVirtProxy(); - Addr addr_lb = 0, addr_lb_len = 0, addr_first = 0, addr_next = 0; - const bool found_symbols = - symtab->findAddress("__log_buf", addr_lb) && - symtab->findAddress("log_buf_len", addr_lb_len) && - symtab->findAddress("log_first_idx", addr_first) && - symtab->findAddress("log_next_idx", addr_next); - - if (!found_symbols) { + auto lb = symtab->find("__log_buf"); + auto lb_len = symtab->find("log_buf_len"); + auto first = symtab->find("log_first_idx"); + auto next = symtab->find("log_next_idx"); + + auto end_it = symtab->end(); + + if (lb == end_it || lb_len == end_it || + first == end_it || next == end_it) { warn("Failed to find kernel dmesg symbols.\n"); return; } uint32_t log_buf_len = - proxy.read(addr_lb_len, TheISA::GuestByteOrder); + proxy.read(lb_len->address, TheISA::GuestByteOrder); uint32_t log_first_idx = - proxy.read(addr_first, TheISA::GuestByteOrder); + proxy.read(first->address, TheISA::GuestByteOrder); uint32_t log_next_idx = - proxy.read(addr_next, TheISA::GuestByteOrder); + proxy.read(next->address, TheISA::GuestByteOrder); if (log_first_idx >= log_buf_len || log_next_idx >= log_buf_len) { warn("dmesg pointers/length corrupted\n"); @@ -129,7 +130,7 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os) warn("Unexpected dmesg buffer length\n"); return; } - proxy.readBlob(addr_lb + log_first_idx, log_buf.data(), length); + proxy.readBlob(lb->address + log_first_idx, log_buf.data(), length); } else { const int length_2 = log_buf_len - log_first_idx; if (length_2 < 0 || length_2 + log_next_idx > log_buf.size()) { @@ -137,8 +138,8 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os) return; } length = log_buf_len; - proxy.readBlob(addr_lb + log_first_idx, log_buf.data(), length_2); - proxy.readBlob(addr_lb, log_buf.data() + length_2, log_next_idx); + proxy.readBlob(lb->address + log_first_idx, log_buf.data(), length_2); + proxy.readBlob(lb->address, log_buf.data() + length_2, log_next_idx); } // Print dmesg buffer content diff --git a/src/sim/kernel_workload.hh b/src/sim/kernel_workload.hh index b88051a55..34406ebc5 100644 --- a/src/sim/kernel_workload.hh +++ b/src/sim/kernel_workload.hh @@ -98,9 +98,9 @@ class KernelWorkload : public Workload } bool - insertSymbol(Addr address, const std::string &symbol) override + insertSymbol(const Loader::Symbol &symbol) override { - return kernelSymtab->insert(address, symbol); + return kernelSymtab->insert(symbol); } void initState() override; diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index c65fdc016..64a9c449e 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -241,8 +241,10 @@ loadsymbol(ThreadContext *tc) if (!to_number(address, addr)) continue; - if (!tc->getSystemPtr()->workload->insertSymbol(addr, symbol)) + if (!tc->getSystemPtr()->workload->insertSymbol( + { Loader::Symbol::Binding::Global, symbol, addr })) { continue; + } DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); @@ -263,8 +265,10 @@ addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); - tc->getSystemPtr()->workload->insertSymbol(addr, symbol); - Loader::debugSymbolTable->insert(addr, symbol); + tc->getSystemPtr()->workload->insertSymbol( + { Loader::Symbol::Binding::Global, symbol, addr }); + Loader::debugSymbolTable->insert( + { Loader::Symbol::Binding::Global, symbol, addr }); } uint64_t diff --git a/src/sim/workload.hh b/src/sim/workload.hh index ca2dffbd4..e24aa746e 100644 --- a/src/sim/workload.hh +++ b/src/sim/workload.hh @@ -50,7 +50,7 @@ class Workload : public SimObject virtual Loader::Arch getArch() const = 0; virtual const Loader::SymbolTable *symtab(ThreadContext *tc) = 0; - virtual bool insertSymbol(Addr address, const std::string &symbol) = 0; + virtual bool insertSymbol(const Loader::Symbol &symbol) = 0; /** @{ */ /** @@ -70,14 +70,12 @@ class Workload : public SimObject addFuncEvent(const Loader::SymbolTable *symtab, const char *lbl, const std::string &desc, Args... args) { - Addr addr M5_VAR_USED = 0; // initialize only to avoid compiler warning + auto it = symtab->find(lbl); + if (it == symtab->end()) + return nullptr; - if (symtab->findAddress(lbl, addr)) { - return new T(system, desc, fixFuncEventAddr(addr), - std::forward(args)...); - } - - return nullptr; + return new T(system, desc, fixFuncEventAddr(it->address), + std::forward(args)...); } template diff --git a/src/unittest/nmtest.cc b/src/unittest/nmtest.cc index f444a90d4..3601fa877 100644 --- a/src/unittest/nmtest.cc +++ b/src/unittest/nmtest.cc @@ -52,27 +52,24 @@ main(int argc, char *argv[]) obj->loadLocalSymbols(&symtab); if (argc == 2) { - Loader::SymbolTable::ATable::const_iterator i = - symtab.getAddrTable().begin(); - Loader::SymbolTable::ATable::const_iterator end = - symtab.getAddrTable().end(); - while (i != end) { - cprintf("%#x %s\n", i->first, i->second); - ++i; - } + for (const Loader::Symbol &symbol: symtab) + cprintf("%#x %s\n", symbol.address, symbol.name); } else { string symbol = argv[2]; Addr address; if (symbol[0] == '0' && symbol[1] == 'x') { + Loader::SymbolTable::const_iterator it; if (to_number(symbol, address) && - symtab.findSymbol(address, symbol)) - cprintf("address = %#x, symbol = %s\n", address, symbol); - else + (it = symtab.find(address)) != symtab.end()) { + cprintf("address = %#x, symbol = %s\n", address, it->name); + } else { cprintf("address = %#x was not found\n", address); + } } else { - if (symtab.findAddress(symbol, address)) - cprintf("symbol = %s address = %#x\n", symbol, address); + auto it = symtab.find(symbol); + if (it != symtab.end()) + cprintf("symbol = %s address = %#x\n", symbol, it->address); else cprintf("symbol = %s was not found\n", symbol); } diff --git a/src/unittest/symtest.cc b/src/unittest/symtest.cc index fd006b482..369e1a4d9 100644 --- a/src/unittest/symtest.cc +++ b/src/unittest/symtest.cc @@ -60,19 +60,21 @@ main(int argc, char *argv[]) Addr address; if (!to_number(symbol, address)) { - if (!symtab.findAddress(symbol, address)) { + auto it = symtab.find(symbol); + if (it == symtab.end()) { cout << "could not find symbol: " << symbol << endl; exit(1); } - cout << symbol << " -> " << "0x" << hex << address << endl; + cout << symbol << " -> " << "0x" << hex << it->address << endl; } else { - if (!symtab.findSymbol(address, symbol)) { + auto it = symtab.find(address); + if (it == symtab.end()) { cout << "could not find address: " << address << endl; exit(1); } - cout << "0x" << hex << address << " -> " << symbol<< endl; + cout << "0x" << hex << address << " -> " << it->name << endl; } return 0; -- 2.30.2