diff --git a/src/arch/arm/freebsd/system.cc b/src/arch/arm/freebsd/system.cc index d6f3e4e9a..da427e832 100644 --- a/src/arch/arm/freebsd/system.cc +++ b/src/arch/arm/freebsd/system.cc @@ -86,8 +86,8 @@ FreebsdArmSystem::initState() // to do this permanently, for but early bootup work // it is helpful. if (params()->early_kernel_symbols) { - kernel->loadGlobalSymbols(kernelSymtab, loadAddrMask); - kernel->loadGlobalSymbols(debugSymbolTable, loadAddrMask); + kernel->loadGlobalSymbols(kernelSymtab, 0, 0, loadAddrMask); + kernel->loadGlobalSymbols(debugSymbolTable, 0, 0, loadAddrMask); } // Setup boot data structure diff --git a/src/arch/arm/linux/system.cc b/src/arch/arm/linux/system.cc index c22ce160f..a78bab5bf 100644 --- a/src/arch/arm/linux/system.cc +++ b/src/arch/arm/linux/system.cc @@ -110,8 +110,8 @@ LinuxArmSystem::initState() // to do this permanently, for but early bootup work // it is helpful. if (params()->early_kernel_symbols) { - kernel->loadGlobalSymbols(kernelSymtab, loadAddrMask); - kernel->loadGlobalSymbols(debugSymbolTable, loadAddrMask); + kernel->loadGlobalSymbols(kernelSymtab, 0, 0, loadAddrMask); + kernel->loadGlobalSymbols(debugSymbolTable, 0, 0, loadAddrMask); } // Setup boot data structure diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc index b6fa645ce..5c7f06db3 100644 --- a/src/arch/sparc/system.cc +++ b/src/arch/sparc/system.cc @@ -115,7 +115,7 @@ SparcSystem::SparcSystem(Params *p) // Strip off the rom address so when the hypervisor is copied into memory we // have symbols still - if (!hypervisor->loadLocalSymbols(debugSymbolTable, 0xFFFFFF)) + if (!hypervisor->loadLocalSymbols(debugSymbolTable, 0, 0, 0xFFFFFF)) panic("could not load hypervisor symbols\n"); if (!nvram->loadGlobalSymbols(debugSymbolTable)) diff --git a/src/base/loader/aout_object.cc b/src/base/loader/aout_object.cc index 07acc8fbd..468b1b1f0 100644 --- a/src/base/loader/aout_object.cc +++ b/src/base/loader/aout_object.cc @@ -80,14 +80,23 @@ AoutObject::AoutObject(const string &_filename, bool -AoutObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask) +AoutObject::loadAllSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) +{ + return false; +} + +bool +AoutObject::loadGlobalSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { // a.out symbols not supported yet return false; } bool -AoutObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask) +AoutObject::loadLocalSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { // a.out symbols not supported yet return false; diff --git a/src/base/loader/aout_object.hh b/src/base/loader/aout_object.hh index 110dcfd36..65ed7ca0f 100644 --- a/src/base/loader/aout_object.hh +++ b/src/base/loader/aout_object.hh @@ -48,10 +48,13 @@ class AoutObject : public ObjectFile public: virtual ~AoutObject() {} - virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()); - virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()); + virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr); + virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, + Addr addr_mask = maxAddr); + virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr); static ObjectFile *tryFile(const std::string &fname, size_t len, uint8_t *data); diff --git a/src/base/loader/dtb_object.cc b/src/base/loader/dtb_object.cc index ead667f11..e9bbceec4 100644 --- a/src/base/loader/dtb_object.cc +++ b/src/base/loader/dtb_object.cc @@ -171,16 +171,24 @@ DtbObject::findReleaseAddr() return rel_addr; } +bool +DtbObject::loadAllSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) +{ + return false; +} bool -DtbObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask) +DtbObject::loadGlobalSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { // nothing to do here return false; } bool -DtbObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask) +DtbObject::loadLocalSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { // nothing to do here return false; diff --git a/src/base/loader/dtb_object.hh b/src/base/loader/dtb_object.hh index 451b52a4c..c49b144ac 100644 --- a/src/base/loader/dtb_object.hh +++ b/src/base/loader/dtb_object.hh @@ -66,10 +66,12 @@ class DtbObject : public ObjectFile */ Addr findReleaseAddr(); - bool loadGlobalSymbols(SymbolTable *symtab, - Addr addrMask = std::numeric_limits::max()); - bool loadLocalSymbols(SymbolTable *symtab, - Addr addrMask = std::numeric_limits::max()); + bool loadAllSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addrMask = maxAddr); + bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addrMask = maxAddr); + bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addrMask = maxAddr); /** Static function that tries to load file as a * flattened device tree blob. diff --git a/src/base/loader/ecoff_object.cc b/src/base/loader/ecoff_object.cc index c3c1c1108..1869efa13 100644 --- a/src/base/loader/ecoff_object.cc +++ b/src/base/loader/ecoff_object.cc @@ -89,9 +89,18 @@ EcoffObject::EcoffObject(const string &_filename, size_t _len, uint8_t *_data, bss.baseAddr, bss.size); } +bool +EcoffObject::loadAllSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) +{ + bool retval = loadGlobalSymbols(symtab, base, offset, addr_mask); + retval = retval && loadLocalSymbols(symtab, base, offset, addr_mask); + return retval; +} bool -EcoffObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask) +EcoffObject::loadGlobalSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { if (!symtab) return false; @@ -120,7 +129,8 @@ EcoffObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask) } bool -EcoffObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask) +EcoffObject::loadLocalSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { if (!symtab) return false; diff --git a/src/base/loader/ecoff_object.hh b/src/base/loader/ecoff_object.hh index 0a5a43f72..b1ae91107 100644 --- a/src/base/loader/ecoff_object.hh +++ b/src/base/loader/ecoff_object.hh @@ -51,10 +51,12 @@ class EcoffObject : public ObjectFile public: virtual ~EcoffObject() {} - virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()); - virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()); + virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr); + virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr); + virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr); static ObjectFile *tryFile(const std::string &fname, size_t len, uint8_t *data); diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index fb5ec4c14..73c1c5dcd 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -396,7 +396,8 @@ ElfObject::ElfObject(const std::string &_filename, size_t _len, bool -ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask) +ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask, + Addr base, Addr offset) { if (!symtab) return false; @@ -432,9 +433,11 @@ ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask) if (GELF_ST_BIND(sym.st_info) == binding) { char *sym_name = elf_strptr(elf, shdr.sh_link, sym.st_name); if (sym_name && sym_name[0] != '$') { - DPRINTF(Loader, "Symbol: %-40s value %#x\n", - sym_name, sym.st_value); - symtab->insert(sym.st_value & mask, sym_name); + Addr value = sym.st_value - base + offset; + if (symtab->insert(value & mask, sym_name)) { + DPRINTF(Loader, "Symbol: %-40s value %#x\n", + sym_name, value); + } } } } @@ -449,23 +452,45 @@ ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask) } bool -ElfObject::loadGlobalSymbols(SymbolTable *symtab, Addr addr_mask) +ElfObject::loadAllSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { - return loadSomeSymbols(symtab, STB_GLOBAL, addr_mask); + return (loadGlobalSymbols(symtab, base, offset, addr_mask) && + loadLocalSymbols(symtab, base, offset, addr_mask) && + loadWeakSymbols(symtab, base, offset, addr_mask)); } bool -ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addr_mask) +ElfObject::loadGlobalSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { - bool found_local = loadSomeSymbols(symtab, STB_LOCAL, addr_mask); - bool found_weak = loadSomeSymbols(symtab, STB_WEAK, addr_mask); - return found_local || found_weak; + if (interpreter) { + interpreter->loadSomeSymbols(symtab, STB_GLOBAL, addr_mask, + base, offset); + } + return loadSomeSymbols(symtab, STB_GLOBAL, addr_mask, base, offset); } bool -ElfObject::loadWeakSymbols(SymbolTable *symtab, Addr addr_mask) +ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { - return loadSomeSymbols(symtab, STB_WEAK, addr_mask); + if (interpreter) { + interpreter->loadSomeSymbols(symtab, STB_LOCAL, addr_mask, + base, offset); + } + return loadSomeSymbols(symtab, STB_LOCAL, addr_mask, base, offset); +} + +bool +ElfObject::loadWeakSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) +{ + if (interpreter) { + interpreter->loadSomeSymbols(symtab, STB_WEAK, addr_mask, + base, offset); + } + return loadSomeSymbols(symtab, STB_WEAK, addr_mask, base, offset); } bool diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh index cec20a47a..aa28cd62a 100644 --- a/src/base/loader/elf_object.hh +++ b/src/base/loader/elf_object.hh @@ -81,7 +81,8 @@ class ElfObject : public ObjectFile Addr ldMax; /// Helper functions for loadGlobalSymbols() and loadLocalSymbols(). - bool loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask); + bool loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask, + Addr base, Addr offset); ElfObject(const std::string &_filename, size_t _len, uint8_t *_data, Arch _arch, OpSys _opSys); @@ -94,15 +95,25 @@ class ElfObject : public ObjectFile public: virtual ~ElfObject() {} - bool loadSections(PortProxy& memProxy, - Addr addrMask = std::numeric_limits::max(), - Addr offset = 0) override; - virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()) override; - virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()) override; - virtual bool loadWeakSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()) override; + bool loadSections(PortProxy& mem_proxy, Addr addr_mask = maxAddr, + Addr offset = 0) override; + + virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr) + override; + + virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr) + override; + + virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr) + override; + + virtual bool loadWeakSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr) + override; + virtual ObjectFile *getInterpreter() const override { return interpreter; } diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh index fb30118e0..b2628a0d0 100644 --- a/src/base/loader/object_file.hh +++ b/src/base/loader/object_file.hh @@ -82,15 +82,19 @@ class ObjectFile public: virtual ~ObjectFile(); - virtual bool loadSections(PortProxy& memProxy, Addr addrMask = - std::numeric_limits::max(), - Addr offset = 0); - virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()) = 0; - virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()) = 0; - virtual bool loadWeakSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()) + static const Addr maxAddr = std::numeric_limits::max(); + + virtual bool loadSections(PortProxy& mem_proxy, + Addr mask = maxAddr, Addr offset = 0); + + virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr mask = maxAddr) = 0; + virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr mask = maxAddr) = 0; + virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr mask = maxAddr) = 0; + virtual bool loadWeakSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr mask = maxAddr) { return false; } virtual ObjectFile *getInterpreter() const { return nullptr; } @@ -121,7 +125,7 @@ class ObjectFile Section data; Section bss; - bool loadSection(Section *sec, PortProxy& memProxy, Addr addrMask, + bool loadSection(Section *sec, PortProxy& mem_proxy, Addr mask, Addr offset = 0); void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; } diff --git a/src/base/loader/raw_object.cc b/src/base/loader/raw_object.cc index 73d8372ef..35a952741 100644 --- a/src/base/loader/raw_object.cc +++ b/src/base/loader/raw_object.cc @@ -62,21 +62,30 @@ RawObject::RawObject(const std::string &_filename, size_t _len, } bool -RawObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask) +RawObject::loadAllSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) +{ + return true; +} + +bool +RawObject::loadGlobalSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { /* int fnameStart = filename.rfind('/',filename.size()) + 1; int extStart = filename.rfind('.',filename.size()); - symtab->insert(text.baseAddr & addrMask, filename.substr(fnameStart, + symtab->insert(text.baseAddr & addr_mask, filename.substr(fnameStart, extStart-fnameStart) + "_start");*/ return true; } bool -RawObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask) +RawObject::loadLocalSymbols(SymbolTable *symtab, Addr base, Addr offset, + Addr addr_mask) { /* int fnameStart = filename.rfind('/',filename.size()) + 1; int extStart = filename.rfind('.',filename.size()); - symtab->insert(text.baseAddr & addrMask, filename.substr(fnameStart, + symtab->insert(text.baseAddr & addr_mask, filename.substr(fnameStart, extStart-fnameStart) + "_start");*/ return true; } diff --git a/src/base/loader/raw_object.hh b/src/base/loader/raw_object.hh index 3865425d0..6931a1321 100644 --- a/src/base/loader/raw_object.hh +++ b/src/base/loader/raw_object.hh @@ -41,10 +41,13 @@ class RawObject: public ObjectFile public: virtual ~RawObject() {} - virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()); - virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask = - std::numeric_limits::max()); + virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr); + virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, + Addr addr_mask = maxAddr); + virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0, + Addr offset = 0, Addr addr_mask = maxAddr); static ObjectFile *tryFile(const std::string &fname, size_t len, uint8_t *data); diff --git a/src/sim/process.cc b/src/sim/process.cc index 7fa160995..d0dd3d92b 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -543,10 +543,17 @@ LiveProcess::updateBias() } +ObjectFile * +LiveProcess::getInterpreter() +{ + return objFile->getInterpreter(); +} + + Addr LiveProcess::getBias() { - ObjectFile *interp = objFile->getInterpreter(); + ObjectFile *interp = getInterpreter(); return interp ? interp->bias() : objFile->bias(); } @@ -555,7 +562,7 @@ LiveProcess::getBias() Addr LiveProcess::getStartPC() { - ObjectFile *interp = objFile->getInterpreter(); + ObjectFile *interp = getInterpreter(); return interp ? interp->entryPoint() : objFile->entryPoint(); } diff --git a/src/sim/process.hh b/src/sim/process.hh index aa4c7a008..54e6b2df2 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -341,6 +341,8 @@ class LiveProcess : public Process // bias are not available when the object file is created. void updateBias(); + ObjectFile *getInterpreter(); + Addr getBias(); Addr getStartPC(); diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 71c0dd090..e9ed130f0 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -57,18 +57,20 @@ #ifdef __CYGWIN32__ #include // for O_BINARY + #endif +#include #include #include #include #include -#include #include #include #include "base/chunk_generator.hh" #include "base/intmath.hh" // for RoundUp +#include "base/loader/object_file.hh" #include "base/misc.hh" #include "base/trace.hh" #include "base/types.hh" @@ -1354,6 +1356,31 @@ mmapImpl(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc, // Cleanup the mmap region before exiting this function. munmap(pmap, length); + // Maintain the symbol table for dynamic executables. + // The loader will call mmap to map the images into its address + // space and we intercept that here. We can verify that we are + // executing inside the loader by checking the program counter value. + // XXX: with multiprogrammed workloads or multi-node configurations, + // this will not work since there is a single global symbol table. + ObjectFile *interpreter = p->getInterpreter(); + if (interpreter) { + Addr text_start = interpreter->textBase(); + Addr text_end = text_start + interpreter->textSize(); + + Addr pc = tc->pcState().pc(); + + if (pc >= text_start && pc < text_end) { + FDEntry *fde = p->getFDEntry(tgt_fd); + + ObjectFile *lib = createObjectFile(fde->filename); + + if (lib) { + lib->loadAllSymbols(debugSymbolTable, + lib->textBase(), start); + } + } + } + // Note that we do not zero out the remainder of the mapping. This // is done by a real system, but it probably will not affect // execution (hopefully).