summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/alpha/process.cc11
-rw-r--r--src/arch/alpha/system.cc6
-rw-r--r--src/arch/arm/freebsd/system.cc4
-rw-r--r--src/arch/arm/linux/system.cc4
-rw-r--r--src/arch/arm/process.cc12
-rw-r--r--src/arch/arm/system.cc2
-rw-r--r--src/arch/mips/process.cc10
-rw-r--r--src/arch/power/process.cc10
-rw-r--r--src/arch/riscv/bare_metal/system.cc2
-rw-r--r--src/arch/riscv/process.cc8
-rw-r--r--src/arch/sparc/process.cc8
-rw-r--r--src/arch/sparc/process.hh4
-rw-r--r--src/arch/sparc/system.cc28
-rw-r--r--src/arch/x86/process.cc12
-rw-r--r--src/base/SConscript1
-rw-r--r--src/base/loader/aout_object.cc22
-rw-r--r--src/base/loader/aout_object.hh15
-rw-r--r--src/base/loader/dtb_object.cc13
-rw-r--r--src/base/loader/dtb_object.hh74
-rw-r--r--src/base/loader/ecoff_object.cc24
-rw-r--r--src/base/loader/ecoff_object.hh14
-rw-r--r--src/base/loader/elf_object.cc20
-rw-r--r--src/base/loader/elf_object.hh38
-rw-r--r--src/base/loader/memory_image.cc64
-rw-r--r--src/base/loader/memory_image.hh146
-rw-r--r--src/base/loader/object_file.cc25
-rw-r--r--src/base/loader/object_file.hh87
-rw-r--r--src/base/loader/raw_object.cc10
-rw-r--r--src/base/loader/raw_object.hh17
-rw-r--r--src/sim/process.cc16
-rw-r--r--src/sim/process.hh4
-rw-r--r--src/sim/syscall_emul.hh19
-rw-r--r--src/sim/system.cc34
-rw-r--r--src/sim/system.hh2
34 files changed, 426 insertions, 340 deletions
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index e266b92b2..9311a6415 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -54,10 +54,10 @@ AlphaProcess::AlphaProcess(ProcessParams *params, ObjectFile *objFile)
objFile)
{
fatal_if(params->useArchPT, "Arch page tables not implemented.");
- Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
+ Addr brk_point = roundUp(image.maxAddr(), PageBytes);
// Set up stack. On Alpha, stack goes below the image.
- Addr stack_base = objFile->minSegmentAddr() - (409600 + 4096);
+ Addr stack_base = image.minAddr() - (409600 + 4096);
// Set up region for mmaps.
Addr mmap_end = 0x10000;
@@ -74,13 +74,6 @@ AlphaProcess::AlphaProcess(ProcessParams *params, ObjectFile *objFile)
void
AlphaProcess::argsInit(int intSize, int pageSize)
{
- // Patch the ld_bias for dynamic executables.
- updateBias();
-
- objFile->loadSegments(initVirtMem);
- if (objFile->getInterpreter())
- objFile->getInterpreter()->loadSegments(initVirtMem);
-
std::vector<AuxVector<uint64_t>> auxv;
ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc
index 31e7aa062..a7a47036a 100644
--- a/src/arch/alpha/system.cc
+++ b/src/arch/alpha/system.cc
@@ -57,13 +57,11 @@ AlphaSystem::AlphaSystem(Params *p)
*/
// Load Console Code
console = createObjectFile(params()->console);
- console->setLoadMask(loadAddrMask);
if (console == NULL)
fatal("Could not load console file %s", params()->console);
// Load pal file
pal = createObjectFile(params()->pal);
- pal->setLoadMask(loadAddrMask);
if (pal == NULL)
fatal("Could not load PALcode file %s", params()->pal);
@@ -111,8 +109,8 @@ AlphaSystem::initState()
System::initState();
// Load program sections into memory
- pal->loadSegments(physProxy);
- console->loadSegments(physProxy);
+ pal->buildImage().mask(loadAddrMask).write(physProxy);
+ console->buildImage().mask(loadAddrMask).write(physProxy);
/**
* Copy the osflags (kernel arguments) into the consoles
diff --git a/src/arch/arm/freebsd/system.cc b/src/arch/arm/freebsd/system.cc
index 764f036b4..106c8e432 100644
--- a/src/arch/arm/freebsd/system.cc
+++ b/src/arch/arm/freebsd/system.cc
@@ -132,8 +132,8 @@ FreebsdArmSystem::initState()
if (ra)
bootReleaseAddr = ra & ~ULL(0x7F);
- dtb_file->setLoadOffset(params()->atags_addr + loadAddrOffset);
- dtb_file->loadSegments(physProxy);
+ dtb_file->buildImage().
+ offset(params()->atags_addr + loadAddrOffset).write(physProxy);
delete dtb_file;
// Kernel boot requirements to set up r0, r1 and r2 in ARMv7
diff --git a/src/arch/arm/linux/system.cc b/src/arch/arm/linux/system.cc
index a0869b46a..740d2e0e6 100644
--- a/src/arch/arm/linux/system.cc
+++ b/src/arch/arm/linux/system.cc
@@ -151,8 +151,8 @@ LinuxArmSystem::initState()
"to DTB file: %s\n", params()->dtb_filename);
}
- dtb_file->setLoadOffset(params()->atags_addr + loadAddrOffset);
- dtb_file->loadSegments(physProxy);
+ dtb_file->buildImage().
+ offset(params()->atags_addr + loadAddrOffset).write(physProxy);
delete dtb_file;
} else {
// Using ATAGS
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
index ff3b92f48..d9b714c44 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -75,7 +75,7 @@ ArmProcess32::ArmProcess32(ProcessParams *params, ObjectFile *objFile,
ObjectFile::Arch _arch)
: ArmProcess(params, objFile, _arch)
{
- Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
+ Addr brk_point = roundUp(image.maxAddr(), PageBytes);
Addr stack_base = 0xbf000000L;
Addr max_stack_size = 8 * 1024 * 1024;
Addr next_thread_stack_base = stack_base - max_stack_size;
@@ -89,7 +89,7 @@ ArmProcess64::ArmProcess64(ProcessParams *params, ObjectFile *objFile,
ObjectFile::Arch _arch)
: ArmProcess(params, objFile, _arch)
{
- Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
+ Addr brk_point = roundUp(image.maxAddr(), PageBytes);
Addr stack_base = 0x7fffff0000L;
Addr max_stack_size = 8 * 1024 * 1024;
Addr next_thread_stack_base = stack_base - max_stack_size;
@@ -266,14 +266,6 @@ ArmProcess::argsInit(int pageSize, IntRegIndex spIndex)
//We want 16 byte alignment
uint64_t align = 16;
- // Patch the ld_bias for dynamic executables.
- updateBias();
-
- // load object file into target memory
- objFile->loadSegments(initVirtMem);
- if (objFile->getInterpreter())
- objFile->getInterpreter()->loadSegments(initVirtMem);
-
//Setup the auxilliary vectors. These will already have endian conversion.
//Auxilliary vectors are loaded only for elf formatted executables.
ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc
index efc347d9d..bf2881026 100644
--- a/src/arch/arm/system.cc
+++ b/src/arch/arm/system.cc
@@ -143,7 +143,7 @@ ArmSystem::initState()
if (bootldr) {
bool isGICv3System = dynamic_cast<Gicv3 *>(getGIC()) != nullptr;
- bootldr->loadSegments(physProxy);
+ bootldr->buildImage().write(physProxy);
inform("Using bootloader at address %#x\n", bootldr->entryPoint());
diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc
index 4c4b0e414..8e1e22b66 100644
--- a/src/arch/mips/process.cc
+++ b/src/arch/mips/process.cc
@@ -65,7 +65,7 @@ MipsProcess::MipsProcess(ProcessParams *params, ObjectFile *objFile)
Addr next_thread_stack_base = stack_base - max_stack_size;
// Set up break point (Top of Heap)
- Addr brk_point = objFile->maxSegmentAddr();
+ Addr brk_point = image.maxAddr();
brk_point = roundUp(brk_point, PageBytes);
// Set up region for mmaps. Start it 1GB above the top of the heap.
@@ -89,14 +89,6 @@ MipsProcess::argsInit(int pageSize)
{
int intSize = sizeof(IntType);
- // Patch the ld_bias for dynamic executables.
- updateBias();
-
- // load object file into target memory
- objFile->loadSegments(initVirtMem);
- if (objFile->getInterpreter())
- objFile->getInterpreter()->loadSegments(initVirtMem);
-
std::vector<AuxVector<IntType>> auxv;
ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
index 89b94b21f..7b53d7038 100644
--- a/src/arch/power/process.cc
+++ b/src/arch/power/process.cc
@@ -56,7 +56,7 @@ PowerProcess::PowerProcess(ProcessParams *params, ObjectFile *objFile)
{
fatal_if(params->useArchPT, "Arch page tables not implemented.");
// Set up break point (Top of Heap)
- Addr brk_point = objFile->maxSegmentAddr();
+ Addr brk_point = image.maxAddr();
brk_point = roundUp(brk_point, PageBytes);
Addr stack_base = 0xbf000000L;
@@ -95,13 +95,9 @@ PowerProcess::argsInit(int intSize, int pageSize)
//We want 16 byte alignment
uint64_t align = 16;
- // Patch the ld_bias for dynamic executables.
- updateBias();
-
// load object file into target memory
- objFile->loadSegments(initVirtMem);
- if (objFile->getInterpreter())
- objFile->getInterpreter()->loadSegments(initVirtMem);
+ image.write(initVirtMem);
+ interpImage.write(initVirtMem);
//Setup the auxilliary vectors. These will already have endian conversion.
//Auxilliary vectors are loaded only for elf formatted executables.
diff --git a/src/arch/riscv/bare_metal/system.cc b/src/arch/riscv/bare_metal/system.cc
index 3fb07a489..44e14e5ce 100644
--- a/src/arch/riscv/bare_metal/system.cc
+++ b/src/arch/riscv/bare_metal/system.cc
@@ -55,7 +55,7 @@ BareMetalRiscvSystem::initState()
RiscvSystem::initState();
// load program sections into memory
- if (!bootloader->loadSegments(physProxy)) {
+ if (!bootloader->buildImage().write(physProxy)) {
warn("could not load sections to memory");
}
}
diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc
index 35dde7600..617efa0ee 100644
--- a/src/arch/riscv/process.cc
+++ b/src/arch/riscv/process.cc
@@ -75,7 +75,7 @@ RiscvProcess64::RiscvProcess64(ProcessParams *params, ObjectFile *objFile) :
const Addr stack_base = 0x7FFFFFFFFFFFFFFFL;
const Addr max_stack_size = 8 * 1024 * 1024;
const Addr next_thread_stack_base = stack_base - max_stack_size;
- const Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
+ const Addr brk_point = roundUp(image.maxAddr(), PageBytes);
const Addr mmap_end = 0x4000000000000000L;
memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
next_thread_stack_base, mmap_end);
@@ -87,7 +87,7 @@ RiscvProcess32::RiscvProcess32(ProcessParams *params, ObjectFile *objFile) :
const Addr stack_base = 0x7FFFFFFF;
const Addr max_stack_size = 8 * 1024 * 1024;
const Addr next_thread_stack_base = stack_base - max_stack_size;
- const Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
+ const Addr brk_point = roundUp(image.maxAddr(), PageBytes);
const Addr mmap_end = 0x40000000L;
memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
next_thread_stack_base, mmap_end);
@@ -123,10 +123,6 @@ RiscvProcess::argsInit(int pageSize)
const int RandomBytes = 16;
const int addrSize = sizeof(IntType);
- updateBias();
- objFile->loadSegments(initVirtMem);
- if (objFile->getInterpreter())
- objFile->getInterpreter()->loadSegments(initVirtMem);
ElfObject* elfObject = dynamic_cast<ElfObject*>(objFile);
memState->setStackMin(memState->getStackBase());
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 1c020c6b1..048c7e957 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -204,14 +204,6 @@ SparcProcess::argsInit(int pageSize)
// maintain double word alignment of the stack pointer.
uint64_t align = 16;
- // Patch the ld_bias for dynamic executables.
- updateBias();
-
- // load object file into target memory
- objFile->loadSegments(initVirtMem);
- if (objFile->getInterpreter())
- objFile->getInterpreter()->loadSegments(initVirtMem);
-
enum hardwareCaps
{
M5_HWCAP_SPARC_FLUSH = 1,
diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh
index f8f19f290..0ef34352b 100644
--- a/src/arch/sparc/process.hh
+++ b/src/arch/sparc/process.hh
@@ -78,7 +78,7 @@ class Sparc32Process : public SparcProcess
Sparc32Process(ProcessParams * params, ObjectFile *objFile)
: SparcProcess(params, objFile, 0)
{
- Addr brk_point = objFile->maxSegmentAddr();
+ Addr brk_point = image.maxAddr();
brk_point = roundUp(brk_point, SparcISA::PageBytes);
// Reserve 8M for main stack.
@@ -122,7 +122,7 @@ class Sparc64Process : public SparcProcess
Sparc64Process(ProcessParams * params, ObjectFile *objFile)
: SparcProcess(params, objFile, 2047)
{
- Addr brk_point = objFile->maxSegmentAddr();
+ Addr brk_point = image.maxAddr();
brk_point = roundUp(brk_point, SparcISA::PageBytes);
Addr max_stack_size = 8 * 1024 * 1024;
diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc
index e9615b00c..255cc1453 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -136,25 +136,15 @@ SparcSystem::initState()
// Call the initialisation of the super class
System::initState();
- // Load reset binary into memory
- reset->setLoadOffset(params()->reset_addr);
- reset->loadSegments(physProxy);
- // Load the openboot binary
- openboot->setLoadOffset(params()->openboot_addr);
- openboot->loadSegments(physProxy);
- // Load the hypervisor binary
- hypervisor->setLoadOffset(params()->hypervisor_addr);
- hypervisor->loadSegments(physProxy);
- // Load the nvram image
- nvram->setLoadOffset(params()->nvram_addr);
- nvram->loadSegments(physProxy);
- // Load the hypervisor description image
- hypervisor_desc->setLoadOffset(params()->hypervisor_desc_addr);
- hypervisor_desc->loadSegments(physProxy);
- // Load the partition description image
- partition_desc->setLoadOffset(params()->partition_desc_addr);
- partition_desc->loadSegments(physProxy);
-
+ reset->buildImage().offset(params()->reset_addr).write(physProxy);
+ openboot->buildImage().offset(params()->openboot_addr).write(physProxy);
+ hypervisor->buildImage().
+ offset(params()->hypervisor_addr).write(physProxy);
+ nvram->buildImage().offset(params()->nvram_addr).write(physProxy);
+ hypervisor_desc->buildImage().
+ offset(params()->hypervisor_desc_addr).write(physProxy);
+ partition_desc->buildImage().
+ offset(params()->partition_desc_addr).write(physProxy);
// @todo any fixup code over writing data in binaries on setting break
// events on functions should happen here.
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 546474138..11b46c824 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -136,7 +136,7 @@ X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile,
vsyscallPage.vtimeOffset = 0x400;
vsyscallPage.vgettimeofdayOffset = 0x0;
- Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
+ Addr brk_point = roundUp(image.maxAddr(), PageBytes);
Addr stack_base = 0x7FFFFFFFF000ULL;
Addr max_stack_size = 8 * 1024 * 1024;
Addr next_thread_stack_base = stack_base - max_stack_size;
@@ -175,7 +175,7 @@ I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
vsyscallPage.vsyscallOffset = 0x400;
vsyscallPage.vsysexitOffset = 0x410;
- Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
+ Addr brk_point = roundUp(image.maxAddr(), PageBytes);
Addr stack_base = _gdtStart;
Addr max_stack_size = 8 * 1024 * 1024;
Addr next_thread_stack_base = stack_base - max_stack_size;
@@ -770,14 +770,6 @@ X86Process::argsInit(int pageSize,
// We want 16 byte alignment
uint64_t align = 16;
- // Patch the ld_bias for dynamic executables.
- updateBias();
-
- // load object file into target memory
- objFile->loadSegments(initVirtMem);
- if (objFile->getInterpreter())
- objFile->getInterpreter()->loadSegments(initVirtMem);
-
enum X86CpuFeature {
X86_OnboardFPU = 1 << 0,
X86_VirtualModeExtensions = 1 << 1,
diff --git a/src/base/SConscript b/src/base/SConscript
index 0c7558d09..efa7df700 100644
--- a/src/base/SConscript
+++ b/src/base/SConscript
@@ -76,6 +76,7 @@ Source('loader/aout_object.cc')
Source('loader/dtb_object.cc')
Source('loader/ecoff_object.cc')
Source('loader/elf_object.cc')
+Source('loader/memory_image.cc')
Source('loader/object_file.cc')
Source('loader/raw_object.cc')
Source('loader/symtab.cc')
diff --git a/src/base/loader/aout_object.cc b/src/base/loader/aout_object.cc
index 97651586f..eb633c1ce 100644
--- a/src/base/loader/aout_object.cc
+++ b/src/base/loader/aout_object.cc
@@ -58,17 +58,23 @@ AoutObject::AoutObject(const string &_filename,
: ObjectFile(_filename, _len, _data, _arch, _opSys)
{
execHdr = (aout_exechdr *)fileData;
-
entry = execHdr->entry;
+}
- addSegment("text", N_TXTADDR(*execHdr), fileData + N_TXTOFF(*execHdr),
- execHdr->tsize);
- addSegment("data", N_DATADDR(*execHdr), fileData + N_DATOFF(*execHdr),
- execHdr->dsize);
- addSegment("bss", N_BSSADDR(*execHdr), nullptr, execHdr->bsize);
+MemoryImage
+AoutObject::buildImage() const
+{
+ MemoryImage image({
+ { "text", N_TXTADDR(*execHdr),
+ fileData + N_TXTOFF(*execHdr), execHdr->tsize },
+ { "data", N_DATADDR(*execHdr),
+ fileData + N_DATOFF(*execHdr), execHdr->dsize },
+ { "bss", N_BSSADDR(*execHdr), nullptr, execHdr->bsize}
+ });
- for (auto &seg: segments)
- DPRINTFR(Loader, "%s\n", *seg);
+ for (auto &seg: image.segments())
+ DPRINTFR(Loader, "%s\n", seg);
+ return image;
}
diff --git a/src/base/loader/aout_object.hh b/src/base/loader/aout_object.hh
index 65ed7ca0f..4f8c86fcd 100644
--- a/src/base/loader/aout_object.hh
+++ b/src/base/loader/aout_object.hh
@@ -48,13 +48,14 @@ class AoutObject : public ObjectFile
public:
virtual ~AoutObject() {}
- 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);
+ MemoryImage buildImage() const override;
+
+ bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask = MaxAddr) override;
+ bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
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 275139a8c..f5b206a74 100644
--- a/src/base/loader/dtb_object.cc
+++ b/src/base/loader/dtb_object.cc
@@ -53,10 +53,8 @@ DtbObject::tryFile(const std::string &fname, size_t len, uint8_t *data)
DtbObject::DtbObject(const std::string &_filename, size_t _len, uint8_t *_data,
Arch _arch, OpSys _opSys)
- : ObjectFile(_filename, _len, _data, _arch, _opSys),
- data(new Segment{ "data", 0, fileData, len })
+ : ObjectFile(_filename, _len, _data, _arch, _opSys)
{
- segments.emplace_back(data);
fileDataMmapped = true;
}
@@ -131,9 +129,6 @@ DtbObject::addBootCmdLine(const char* _args, size_t len)
return false;
}
- data->size = newLen;
- data->data = fdt_buf_w_space;
-
// clean up old buffer and set to new fdt blob
munmap(fileData, this->len);
fileData = fdt_buf_w_space;
@@ -164,6 +159,12 @@ DtbObject::findReleaseAddr()
return rel_addr;
}
+MemoryImage
+DtbObject::buildImage() const
+{
+ return {{"data", 0, fileData, len}};
+}
+
bool
DtbObject::loadAllSymbols(SymbolTable *symtab, Addr base, Addr offset,
Addr addr_mask)
diff --git a/src/base/loader/dtb_object.hh b/src/base/loader/dtb_object.hh
index 7cb842e43..1284025ff 100644
--- a/src/base/loader/dtb_object.hh
+++ b/src/base/loader/dtb_object.hh
@@ -40,50 +40,50 @@
*/
class DtbObject : public ObjectFile
{
- protected:
- DtbObject(const std::string &_filename, size_t _len, uint8_t *_data,
- Arch _arch, OpSys _opSys);
+ protected:
+ DtbObject(const std::string &_filename, size_t _len, uint8_t *_data,
+ Arch _arch, OpSys _opSys);
- /** Bool marking if this dtb file has replaced the original
- * read in DTB file with a new modified buffer
- */
- bool fileDataMmapped;
+ /** Bool marking if this dtb file has replaced the original
+ * read in DTB file with a new modified buffer
+ */
+ bool fileDataMmapped;
- Segment *data;
+ public:
+ virtual ~DtbObject();
- public:
- virtual ~DtbObject();
+ /** Adds the passed in Command Line options for the kernel
+ * to the proper location in the device tree.
+ * @param _args command line to append
+ * @param len length of the command line string
+ * @return returns true on success, false otherwise
+ */
+ bool addBootCmdLine(const char* _args, size_t len);
- /** Adds the passed in Command Line options for the kernel
- * to the proper location in the device tree.
- * @param _args command line to append
- * @param len length of the command line string
- * @return returns true on success, false otherwise
- */
- bool addBootCmdLine(const char* _args, size_t len);
+ /** Parse the DTB file enough to find the provided release
+ * address and return it.
+ * @return release address for SMP boot
+ */
+ Addr findReleaseAddr();
- /** Parse the DTB file enough to find the provided release
- * address and return it.
- * @return release address for SMP boot
- */
- Addr findReleaseAddr();
+ MemoryImage buildImage() const override;
- 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);
+ bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addrMask=MaxAddr) override;
+ bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addrMask=MaxAddr) override;
+ bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addrMask=MaxAddr) override;
- /** Static function that tries to load file as a
- * flattened device tree blob.
- * @param fname path to file
- * @param len length of file
- * @param data mmap'ed data buffer containing file contents
- * @return ObjectFile representing closest match of file type
- */
- static ObjectFile *tryFile(const std::string &fname,
- size_t len, uint8_t *data);
+ /** Static function that tries to load file as a
+ * flattened device tree blob.
+ * @param fname path to file
+ * @param len length of file
+ * @param data mmap'ed data buffer containing file contents
+ * @return ObjectFile representing closest match of file type
+ */
+ static ObjectFile *tryFile(const std::string &fname,
+ size_t len, uint8_t *data);
};
#endif //__DTB_OBJECT_HH__
diff --git a/src/base/loader/ecoff_object.cc b/src/base/loader/ecoff_object.cc
index 56f9b35fc..cecc68dc1 100644
--- a/src/base/loader/ecoff_object.cc
+++ b/src/base/loader/ecoff_object.cc
@@ -72,15 +72,23 @@ EcoffObject::EcoffObject(const string &_filename, size_t _len, uint8_t *_data,
aoutHdr = &(execHdr->a);
entry = aoutHdr->entry;
+}
- addSegment("text", aoutHdr->text_start, fileData + ECOFF_TXTOFF(execHdr),
- aoutHdr->tsize);
- addSegment("data", aoutHdr->data_start, fileData + ECOFF_DATOFF(execHdr),
- aoutHdr->dsize);
- addSegment("bss", aoutHdr->bss_start, nullptr, aoutHdr->bsize);
-
- for (auto &seg: segments)
- DPRINTFR(Loader, "%s\n", *seg);
+MemoryImage
+EcoffObject::buildImage() const
+{
+ MemoryImage image({
+ { "text", aoutHdr->text_start,
+ fileData + ECOFF_TXTOFF(execHdr), aoutHdr->tsize },
+ { "data", aoutHdr->data_start,
+ fileData + ECOFF_DATOFF(execHdr), aoutHdr->dsize },
+ { "bss", aoutHdr->bss_start, nullptr, aoutHdr->bsize }
+ });
+
+ for (auto &seg: image.segments())
+ DPRINTFR(Loader, "%s\n", seg);
+
+ return image;
}
bool
diff --git a/src/base/loader/ecoff_object.hh b/src/base/loader/ecoff_object.hh
index b1ae91107..94811158e 100644
--- a/src/base/loader/ecoff_object.hh
+++ b/src/base/loader/ecoff_object.hh
@@ -51,12 +51,14 @@ class EcoffObject : public ObjectFile
public:
virtual ~EcoffObject() {}
- 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);
+ MemoryImage buildImage() const override;
+
+ bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
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 4cf20975d..7a83c0bd2 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -339,26 +339,25 @@ ElfObject::ElfObject(const std::string &_filename, size_t _len,
section = elf_getscn(elf, ++sec_idx);
}
- addSegment(name, phdr.p_paddr, fileData + phdr.p_offset,
- phdr.p_filesz);
+ image.addSegment(name, phdr.p_paddr, fileData + phdr.p_offset,
+ phdr.p_filesz);
Addr uninitialized = phdr.p_memsz - phdr.p_filesz;
if (uninitialized) {
// There may be parts of a segment which aren't included in the
// file. In those cases, we need to create a new segment with no
// data to take up the extra space. This should be zeroed when
// loaded into memory.
- addSegment(name + "(uninitialized)", phdr.p_paddr + phdr.p_filesz,
- nullptr, uninitialized);
+ image.addSegment(name + "(uninitialized)",
+ phdr.p_paddr + phdr.p_filesz, nullptr, uninitialized);
}
}
// should have found at least one loadable segment
- warn_if(segments.empty(),
- "No loadable segments in '%s'. ELF file corrupted?\n",
- filename);
+ warn_if(image.segments().empty(),
+ "No loadable segments in '%s'. ELF file corrupted?\n", filename);
- for (auto &seg: segments)
- DPRINTFR(Loader, "%s\n", *seg);
+ for (auto &seg: image.segments())
+ DPRINTFR(Loader, "%s\n", seg);
elf_end(elf);
@@ -518,6 +517,5 @@ ElfObject::updateBias(Addr bias_addr)
entry += bias_addr;
// Patch segments with the bias_addr.
- for (auto &segment : segments)
- segment->base += bias_addr;
+ image.offset(bias_addr);
}
diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh
index dbefadd19..0b8c79b47 100644
--- a/src/base/loader/elf_object.hh
+++ b/src/base/loader/elf_object.hh
@@ -86,34 +86,30 @@ class ElfObject : public ObjectFile
void getSections();
bool sectionExists(std::string sec);
+ MemoryImage image;
+
public:
virtual ~ElfObject() {}
- 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;
+ MemoryImage buildImage() const override { return image; }
- virtual bool loadWeakSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr)
- override;
+ bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadWeakSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
- virtual ObjectFile *getInterpreter() const override
- { return interpreter; }
- virtual Addr bias() const override { return ldBias; }
- virtual bool relocatable() const override { return relocate; }
- virtual Addr mapSize() const override { return ldMax - ldMin; }
- virtual void updateBias(Addr bias_addr) override;
+ ObjectFile *getInterpreter() const override { return interpreter; }
+ Addr bias() const override { return ldBias; }
+ bool relocatable() const override { return relocate; }
+ Addr mapSize() const override { return ldMax - ldMin; }
+ void updateBias(Addr bias_addr) override;
- virtual bool hasTLS() override { return sectionExists(".tbss"); }
+ bool hasTLS() override { return sectionExists(".tbss"); }
static ObjectFile *tryFile(const std::string &fname,
size_t len, uint8_t *data,
diff --git a/src/base/loader/memory_image.cc b/src/base/loader/memory_image.cc
new file mode 100644
index 000000000..6fa70c99d
--- /dev/null
+++ b/src/base/loader/memory_image.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2002-2004 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#include "base/loader/memory_image.hh"
+#include "mem/port_proxy.hh"
+
+bool
+MemoryImage::writeSegment(const Segment &seg, const PortProxy &proxy) const
+{
+ if (seg.size != 0) {
+ if (seg.data) {
+ proxy.writeBlob(seg.base, seg.data, seg.size);
+ } else {
+ // no image: must be bss
+ proxy.memsetBlob(seg.base, 0, seg.size);
+ }
+ }
+ return true;
+}
+
+bool
+MemoryImage::write(const PortProxy &proxy) const
+{
+ for (auto &seg: _segments)
+ if (!writeSegment(seg, proxy))
+ return false;
+ return true;
+}
+
+MemoryImage &
+MemoryImage::move(std::function<Addr(Addr)> mapper)
+{
+ for (auto &seg: _segments)
+ seg.base = mapper(seg.base);
+ return *this;
+}
diff --git a/src/base/loader/memory_image.hh b/src/base/loader/memory_image.hh
new file mode 100644
index 000000000..866e9560c
--- /dev/null
+++ b/src/base/loader/memory_image.hh
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2002-2004 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#ifndef __BASE_LOADER_MEMORY_IMAGE_HH__
+#define __BASE_LOADER_MEMORY_IMAGE_HH__
+
+#include <functional>
+#include <initializer_list>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/logging.hh"
+#include "base/types.hh"
+
+class PortProxy;
+class Process;
+class ProcessParams;
+class SymbolTable;
+
+class MemoryImage
+{
+ public:
+ struct Segment
+ {
+ std::string name;
+ Addr base;
+ uint8_t *data;
+ size_t size;
+ };
+
+ MemoryImage() {}
+
+ MemoryImage(std::initializer_list<Segment> new_segs)
+ {
+ for (auto &seg: new_segs)
+ addSegment(seg);
+ }
+
+ private:
+ std::vector<Segment> _segments;
+ bool writeSegment(const Segment &seg, const PortProxy &proxy) const;
+
+ public:
+ const std::vector<Segment> &
+ segments() const
+ {
+ return _segments;
+ }
+
+ void
+ addSegment(const Segment &seg)
+ {
+ _segments.emplace_back(seg);
+ }
+
+ void
+ addSegment(std::string name, Addr base, uint8_t *data, size_t size)
+ {
+ _segments.push_back(Segment({name, base, data, size}));
+ }
+
+ bool write(const PortProxy &proxy) const;
+ MemoryImage &move(std::function<Addr(Addr)> mapper);
+ MemoryImage &
+ offset(Addr by)
+ {
+ return move([by](Addr a){ return by + a; });
+ }
+ MemoryImage &
+ mask(Addr m) {
+ return move([m](Addr a) { return a & m; });
+ }
+
+ Addr
+ maxAddr() const
+ {
+ Addr max = 0;
+ for (auto &seg: _segments) {
+ Addr end = seg.base + seg.size;
+ if (end > max)
+ max = end;
+ }
+ return max;
+ }
+
+ Addr
+ minAddr() const
+ {
+ Addr min = MaxAddr;
+ for (auto &seg: _segments)
+ if (seg.base < min)
+ min = seg.base;
+ return min;
+ }
+
+ bool
+ contains(Addr addr) const
+ {
+ for (auto &seg: _segments) {
+ Addr start = seg.base;
+ Addr end = seg.base + seg.size;
+ if (addr >= start && addr < end)
+ return true;
+ }
+ return false;
+ }
+};
+
+static inline std::ostream &
+operator << (std::ostream &os, const MemoryImage::Segment &seg)
+{
+ ccprintf(os, "%s: %#x %d", seg.name, seg.base, seg.size);
+ return os;
+}
+
+
+#endif // __BASE_LOADER_MEMORY_IMAGE_HH__
diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc
index d63b2221b..afecd21e3 100644
--- a/src/base/loader/object_file.cc
+++ b/src/base/loader/object_file.cc
@@ -70,31 +70,6 @@ ObjectFile::~ObjectFile()
}
-bool
-ObjectFile::loadSegment(Segment *seg, const PortProxy &mem_proxy)
-{
- if (seg->size != 0) {
- Addr addr = (seg->base & loadMask) + loadOffset;
- if (seg->data) {
- mem_proxy.writeBlob(addr, seg->data, seg->size);
- } else {
- // no image: must be bss
- mem_proxy.memsetBlob(addr, 0, seg->size);
- }
- }
- return true;
-}
-
-
-bool
-ObjectFile::loadSegments(const PortProxy &proxy)
-{
- for (auto &seg: segments)
- if (!loadSegment(seg.get(), proxy))
- return false;
- return true;
-}
-
namespace
{
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
index e5053ad82..669afeb11 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -37,6 +37,7 @@
#include <string>
#include <vector>
+#include "base/loader/memory_image.hh"
#include "base/logging.hh"
#include "base/types.hh"
@@ -74,14 +75,10 @@ class ObjectFile
FreeBSD
};
- static const Addr maxAddr = std::numeric_limits<Addr>::max();
-
protected:
const std::string filename;
uint8_t *fileData;
size_t len;
- Addr loadOffset=0;
- Addr loadMask=maxAddr;
Arch arch;
OpSys opSys;
@@ -92,16 +89,16 @@ class ObjectFile
public:
virtual ~ObjectFile();
- virtual bool loadSegments(const PortProxy &mem_proxy);
+ virtual MemoryImage buildImage() const = 0;
virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset=0, Addr mask=maxAddr) = 0;
+ Addr offset=0, Addr mask=MaxAddr) = 0;
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset=0, Addr mask=maxAddr) = 0;
+ Addr offset=0, Addr mask=MaxAddr) = 0;
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
- Addr offset=0, Addr mask=maxAddr) = 0;
+ Addr offset=0, Addr mask=MaxAddr) = 0;
virtual bool loadWeakSymbols(SymbolTable *symtab, Addr base=0,
- Addr offset=0, Addr mask=maxAddr)
+ Addr offset=0, Addr mask=MaxAddr)
{ return false; }
virtual ObjectFile *getInterpreter() const { return nullptr; }
@@ -117,77 +114,12 @@ class ObjectFile
Arch getArch() const { return arch; }
OpSys getOpSys() const { return opSys; }
- struct Segment
- {
- std::string name;
- Addr base;
- uint8_t *data;
- size_t size;
- };
-
protected:
Addr entry;
- std::vector<std::unique_ptr<Segment>> segments;
-
- void
- addSegment(std::string name, Addr base, uint8_t *data, size_t size)
- {
- Segment *seg = new Segment;
- seg->name = name;
- seg->base = base;
- seg->data = data;
- seg->size = size;
- segments.emplace_back(seg);
- }
-
- bool loadSegment(Segment *seg, const PortProxy &mem_proxy);
-
public:
Addr entryPoint() const { return entry; }
- Addr
- maxSegmentAddr() const
- {
- Addr max = 0;
- for (auto &seg: segments) {
- Addr end = seg->base + seg->size;
- if (end > max)
- max = end;
- }
- return max;
- }
-
- Addr
- minSegmentAddr() const
- {
- Addr min = maxAddr;
- for (auto &seg: segments)
- if (seg->base < min)
- min = seg->base;
- return min;
- }
-
- bool
- contains(Addr addr) const
- {
- for (auto &seg: segments) {
- Addr start = seg->base;
- Addr end = seg->base + seg->size;
- if (addr >= start && addr < end)
- return true;
- }
- return false;
- }
-
- /* This function allows you to override the base address where
- * a binary is going to be loaded or set it if the binary is just a
- * blob that doesn't include an object header.
- * @param a address to load the binary/text section at
- */
- void setLoadOffset(Addr val) { loadOffset = val; }
- void setLoadMask(Addr val) { loadMask = val; }
-
/**
* Each instance of a Loader subclass will have a chance to try to load
* an object file when tryLoaders is called. If they can't because they
@@ -221,13 +153,6 @@ class ObjectFile
static Process *tryLoaders(ProcessParams *params, ObjectFile *obj_file);
};
-static inline std::ostream &
-operator << (std::ostream &os, const ObjectFile::Segment &seg)
-{
- ccprintf(os, "%s: %#x %d", seg.name, seg.base, seg.size);
- return os;
-}
-
ObjectFile *createObjectFile(const std::string &fname, bool raw = false);
diff --git a/src/base/loader/raw_object.cc b/src/base/loader/raw_object.cc
index b0ece3ba2..35ed485c4 100644
--- a/src/base/loader/raw_object.cc
+++ b/src/base/loader/raw_object.cc
@@ -43,10 +43,14 @@ RawObject::tryFile(const std::string &fname, size_t len, uint8_t *data)
RawObject::RawObject(const std::string &_filename, size_t _len,
uint8_t *_data, Arch _arch, OpSys _opSys)
- : ObjectFile(_filename, _len, _data, _arch, _opSys),
- data(new Segment{ "data", 0, fileData, len })
+ : ObjectFile(_filename, _len, _data, _arch, _opSys)
{
- segments.emplace_back(data);
+}
+
+MemoryImage
+RawObject::buildImage() const
+{
+ return {{ "data", 0, fileData, len }};
}
bool
diff --git a/src/base/loader/raw_object.hh b/src/base/loader/raw_object.hh
index 9eb929107..6dc54c7aa 100644
--- a/src/base/loader/raw_object.hh
+++ b/src/base/loader/raw_object.hh
@@ -39,18 +39,17 @@ class RawObject: public ObjectFile
RawObject(const std::string &_filename, size_t _len,
uint8_t *_data, Arch _arch, OpSys _opSys);
- Segment *data;
-
public:
virtual ~RawObject() {}
- 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);
+ MemoryImage buildImage() const override;
+
+ bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
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 224152a32..a01cfea91 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -129,6 +129,8 @@ Process::Process(ProcessParams *params, EmulationPageTable *pTable,
exitGroup = new bool();
sigchld = new bool();
+ image = objFile->buildImage();
+
if (!debugSymbolTable) {
debugSymbolTable = new SymbolTable();
if (!objFile->loadGlobalSymbols(debugSymbolTable) ||
@@ -271,6 +273,16 @@ Process::revokeThreadContext(int context_id)
}
void
+Process::init()
+{
+ // Patch the ld_bias for dynamic executables.
+ updateBias();
+
+ if (objFile->getInterpreter())
+ interpImage = objFile->getInterpreter()->buildImage();
+}
+
+void
Process::initState()
{
if (contextIds.empty())
@@ -283,6 +295,10 @@ Process::initState()
tc->activate();
pTable->initState();
+
+ // load object file into target memory
+ image.write(initVirtMem);
+ interpImage.write(initVirtMem);
}
DrainState
diff --git a/src/sim/process.hh b/src/sim/process.hh
index ae23de420..8e353071c 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -41,6 +41,7 @@
#include <vector>
#include "arch/registers.hh"
+#include "base/loader/memory_image.hh"
#include "base/statistics.hh"
#include "base/types.hh"
#include "config/the_isa.hh"
@@ -69,6 +70,7 @@ class Process : public SimObject
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;
+ void init() override;
void initState() override;
DrainState drain() override;
@@ -182,6 +184,8 @@ class Process : public SimObject
SETranslatingPortProxy initVirtMem; // memory proxy for initial image load
ObjectFile *objFile;
+ MemoryImage image;
+ MemoryImage interpImage;
std::vector<std::string> argv;
std::vector<std::string> envp;
std::string executable;
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 6c3b172c2..91ddb2567 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -1886,17 +1886,14 @@ mmapImpl(SyscallDesc *desc, int num, ThreadContext *tc, bool is_mmap2)
// 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) {
- if (interpreter->contains(tc->pcState().instAddr())) {
- std::shared_ptr<FDEntry> fdep = (*p->fds)[tgt_fd];
- auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
- ObjectFile *lib = createObjectFile(ffdp->getFileName());
-
- if (lib) {
- lib->loadAllSymbols(debugSymbolTable,
- lib->minSegmentAddr(), start);
- }
+ if (p->interpImage.contains(tc->pcState().instAddr())) {
+ std::shared_ptr<FDEntry> fdep = (*p->fds)[tgt_fd];
+ auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
+ ObjectFile *lib = createObjectFile(ffdp->getFileName());
+
+ if (lib) {
+ lib->loadAllSymbols(debugSymbolTable,
+ lib->buildImage().minAddr(), start);
}
}
diff --git a/src/sim/system.cc b/src/sim/system.cc
index bf8b45239..87a220311 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -152,16 +152,16 @@ System::System(Params *p)
} else {
// Get the kernel code
kernel = createObjectFile(params()->kernel);
- kernel->setLoadOffset(loadAddrOffset);
- kernel->setLoadMask(loadAddrMask);
inform("kernel located at: %s", params()->kernel);
if (kernel == NULL)
fatal("Could not load kernel file %s", params()->kernel);
+ kernelImage = kernel->buildImage();
+
// setup entry points
- kernelStart = kernel->minSegmentAddr();
- kernelEnd = kernel->maxSegmentAddr();
+ kernelStart = kernelImage.minAddr();
+ kernelEnd = kernelImage.maxAddr();
kernelEntry = kernel->entryPoint();
// If load_addr_mask is set to 0x0, then auto-calculate
@@ -170,9 +170,12 @@ System::System(Params *p)
if (loadAddrMask == 0) {
Addr shift_amt = findMsbSet(kernelEnd - kernelStart) + 1;
loadAddrMask = ((Addr)1 << shift_amt) - 1;
- kernel->setLoadMask(loadAddrMask);
}
+ kernelImage.move([this](Addr a) {
+ return (a & loadAddrMask) + loadAddrOffset;
+ });
+
// load symbols
if (!kernel->loadGlobalSymbols(kernelSymtab))
fatal("could not load kernel symbols\n");
@@ -195,8 +198,6 @@ System::System(Params *p)
ObjectFile *obj = createObjectFile(obj_name);
fatal_if(!obj, "Failed to additional kernel object '%s'.\n",
obj_name);
- obj->setLoadOffset(loadAddrOffset);
- obj->setLoadMask(loadAddrMask);
kernelExtras.push_back(obj);
}
}
@@ -316,25 +317,24 @@ System::initState()
/**
* Load the kernel code into memory
*/
+ auto mapper = [this](Addr a) {
+ return (a & loadAddrMask) + loadAddrOffset;
+ };
if (params()->kernel != "") {
if (params()->kernel_addr_check) {
// Validate kernel mapping before loading binary
- if (!(isMemAddr((kernelStart & loadAddrMask) +
- loadAddrOffset) &&
- isMemAddr((kernelEnd & loadAddrMask) +
- loadAddrOffset))) {
+ if (!isMemAddr(mapper(kernelStart)) ||
+ !isMemAddr(mapper(kernelEnd))) {
fatal("Kernel is mapped to invalid location (not memory). "
"kernelStart 0x(%x) - kernelEnd 0x(%x) %#x:%#x\n",
- kernelStart,
- kernelEnd, (kernelStart & loadAddrMask) +
- loadAddrOffset,
- (kernelEnd & loadAddrMask) + loadAddrOffset);
+ kernelStart, kernelEnd,
+ mapper(kernelStart), mapper(kernelEnd));
}
}
// Load program sections into memory
- kernel->loadSegments(physProxy);
+ kernelImage.write(physProxy);
for (const auto &extra_kernel : kernelExtras)
- extra_kernel->loadSegments(physProxy);
+ extra_kernel->buildImage().move(mapper).write(physProxy);
DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd);
diff --git a/src/sim/system.hh b/src/sim/system.hh
index c618e3944..345d83c2a 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -53,6 +53,7 @@
#include <vector>
#include "arch/isa_traits.hh"
+#include "base/loader/memory_image.hh"
#include "base/loader/symtab.hh"
#include "base/statistics.hh"
#include "config/the_isa.hh"
@@ -224,6 +225,7 @@ class System : public SimObject
/** Object pointer for the kernel code */
ObjectFile *kernel;
+ MemoryImage kernelImage;
/** Additional object files */
std::vector<ObjectFile *> kernelExtras;