diff options
author | Brandon Potter <brandon.potter@amd.com> | 2016-03-17 10:34:27 -0700 |
---|---|---|
committer | Brandon Potter <brandon.potter@amd.com> | 2016-03-17 10:34:27 -0700 |
commit | 4a9dd1feb846e015303196ad5274a829a7c18525 (patch) | |
tree | 8822d5eb77832ca8986ddbfe145b593de32783cc /src/sim | |
parent | de8077763e4d3f5b218d98eb9cf772a115725bf4 (diff) | |
download | gem5-4a9dd1feb846e015303196ad5274a829a7c18525.tar.xz |
base: add symbol support for dynamic libraries
Libraries are loaded into the process address space using the
mmap system call. Conveniently, this happens to be a good
time to update the process symbol table with the library's
incoming symbols so we handle the table update from within the
system call.
This works just like an application's normal symbols. The only
difference between a dynamic library and a main executable is
when the symbol table update occurs. The symbol table update for
an executable happens at program load time and is finished before
the process ever begins executing. Since dynamic linking happens
at runtime, the symbol loading happens after the library is
first loaded into the process address space. The library binary
is examined at this time for a symbol section and that section
is parsed for symbol types with specific bindings (global,
local, weak). Subsequently, these symbols are added to the table
and are available for use by gem5 for things like trace
generation.
Checkpointing should work just as it did previously. The address
space (and therefore the library) will be recorded and the symbol
table will be entirely recorded. (It's not possible to do anything
clever like checkpoint a program and then load the program back
with different libraries with LD_LIBRARY_PATH, because the
library becomes part of the address space after being loaded.)
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/process.cc | 11 | ||||
-rw-r--r-- | src/sim/process.hh | 2 | ||||
-rw-r--r-- | src/sim/syscall_emul.hh | 29 |
3 files changed, 39 insertions, 3 deletions
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). |