summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/freebsd/system.cc4
-rw-r--r--src/arch/arm/linux/system.cc4
-rw-r--r--src/arch/sparc/system.cc2
-rw-r--r--src/base/loader/aout_object.cc13
-rw-r--r--src/base/loader/aout_object.hh11
-rw-r--r--src/base/loader/dtb_object.cc12
-rw-r--r--src/base/loader/dtb_object.hh10
-rw-r--r--src/base/loader/ecoff_object.cc14
-rw-r--r--src/base/loader/ecoff_object.hh10
-rw-r--r--src/base/loader/elf_object.cc49
-rw-r--r--src/base/loader/elf_object.hh31
-rw-r--r--src/base/loader/object_file.hh24
-rw-r--r--src/base/loader/raw_object.cc17
-rw-r--r--src/base/loader/raw_object.hh11
-rw-r--r--src/sim/process.cc11
-rw-r--r--src/sim/process.hh2
-rw-r--r--src/sim/syscall_emul.hh29
17 files changed, 188 insertions, 66 deletions
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<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);
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<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.
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<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);
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<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; }
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<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; }
@@ -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<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);
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 <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"
@@ -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).