// 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
// 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
// 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))
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;
public:
virtual ~AoutObject() {}
- virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::max());
- virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::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);
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;
*/
Addr findReleaseAddr();
- bool loadGlobalSymbols(SymbolTable *symtab,
- Addr addrMask = std::numeric_limits<Addr>::max());
- bool loadLocalSymbols(SymbolTable *symtab,
- Addr addrMask = std::numeric_limits<Addr>::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.
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;
}
bool
-EcoffObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
+EcoffObject::loadLocalSymbols(SymbolTable *symtab, Addr base, Addr offset,
+ Addr addr_mask)
{
if (!symtab)
return false;
public:
virtual ~EcoffObject() {}
- virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::max());
- virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::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);
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;
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);
+ }
}
}
}
}
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
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);
public:
virtual ~ElfObject() {}
- bool loadSections(PortProxy& memProxy,
- Addr addrMask = std::numeric_limits<Addr>::max(),
- Addr offset = 0) override;
- virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::max()) override;
- virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::max()) override;
- virtual bool loadWeakSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::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; }
public:
virtual ~ObjectFile();
- virtual bool loadSections(PortProxy& memProxy, Addr addrMask =
- std::numeric_limits<Addr>::max(),
- Addr offset = 0);
- virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::max()) = 0;
- virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::max()) = 0;
- virtual bool loadWeakSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::max())
+ static const Addr maxAddr = std::numeric_limits<Addr>::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; }
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; }
}
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;
}
public:
virtual ~RawObject() {}
- virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::max());
- virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
- std::numeric_limits<Addr>::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);
}
+ObjectFile *
+LiveProcess::getInterpreter()
+{
+ return objFile->getInterpreter();
+}
+
+
Addr
LiveProcess::getBias()
{
- ObjectFile *interp = objFile->getInterpreter();
+ ObjectFile *interp = getInterpreter();
return interp ? interp->bias() : objFile->bias();
}
Addr
LiveProcess::getStartPC()
{
- ObjectFile *interp = objFile->getInterpreter();
+ ObjectFile *interp = getInterpreter();
return interp ? interp->entryPoint() : objFile->entryPoint();
}
// bias are not available when the object file is created.
void updateBias();
+ ObjectFile *getInterpreter();
+
Addr getBias();
Addr getStartPC();
#ifdef __CYGWIN32__
#include <sys/fcntl.h> // for O_BINARY
+
#endif
+#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/uio.h>
-#include <fcntl.h>
#include <cerrno>
#include <string>
#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"
// 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).