summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/alpha/process.cc6
-rw-r--r--src/arch/alpha/system.cc6
-rw-r--r--src/arch/arm/freebsd/system.cc2
-rw-r--r--src/arch/arm/linux/system.cc2
-rw-r--r--src/arch/arm/process.cc6
-rw-r--r--src/arch/mips/process.cc3
-rw-r--r--src/arch/power/process.cc3
-rw-r--r--src/arch/riscv/process.cc6
-rw-r--r--src/arch/sparc/process.hh6
-rw-r--r--src/arch/sparc/system.cc12
-rw-r--r--src/arch/x86/process.cc6
-rw-r--r--src/base/loader/aout_object.cc23
-rw-r--r--src/base/loader/dtb_object.cc51
-rw-r--r--src/base/loader/dtb_object.hh2
-rw-r--r--src/base/loader/ecoff_object.cc23
-rw-r--r--src/base/loader/elf_object.cc133
-rw-r--r--src/base/loader/elf_object.hh5
-rw-r--r--src/base/loader/object_file.cc21
-rw-r--r--src/base/loader/object_file.hh83
-rw-r--r--src/base/loader/raw_object.cc19
-rw-r--r--src/base/loader/raw_object.hh3
-rw-r--r--src/sim/syscall_emul.hh9
-rw-r--r--src/sim/system.cc17
23 files changed, 201 insertions, 246 deletions
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index d0bfa79c8..59cbebc1c 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -54,12 +54,10 @@ AlphaProcess::AlphaProcess(ProcessParams *params, ObjectFile *objFile)
objFile)
{
fatal_if(params->useArchPT, "Arch page tables not implemented.");
- Addr brk_point = objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize();
- brk_point = roundUp(brk_point, PageBytes);
+ Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
// Set up stack. On Alpha, stack goes below the image.
- Addr stack_base = objFile->textBase() - (409600 + 4096);
+ Addr stack_base = objFile->minSegmentAddr() - (409600 + 4096);
// Set up region for mmaps.
Addr mmap_end = 0x10000;
diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc
index 7bff6da01..31e7aa062 100644
--- a/src/arch/alpha/system.cc
+++ b/src/arch/alpha/system.cc
@@ -57,11 +57,13 @@ 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);
@@ -109,8 +111,8 @@ AlphaSystem::initState()
System::initState();
// Load program sections into memory
- pal->loadSegments(physProxy, loadAddrMask);
- console->loadSegments(physProxy, loadAddrMask);
+ pal->loadSegments(physProxy);
+ console->loadSegments(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 6e544a70e..764f036b4 100644
--- a/src/arch/arm/freebsd/system.cc
+++ b/src/arch/arm/freebsd/system.cc
@@ -132,7 +132,7 @@ FreebsdArmSystem::initState()
if (ra)
bootReleaseAddr = ra & ~ULL(0x7F);
- dtb_file->setTextBase(params()->atags_addr + loadAddrOffset);
+ dtb_file->setLoadOffset(params()->atags_addr + loadAddrOffset);
dtb_file->loadSegments(physProxy);
delete dtb_file;
diff --git a/src/arch/arm/linux/system.cc b/src/arch/arm/linux/system.cc
index f03a5c6cb..a0869b46a 100644
--- a/src/arch/arm/linux/system.cc
+++ b/src/arch/arm/linux/system.cc
@@ -151,7 +151,7 @@ LinuxArmSystem::initState()
"to DTB file: %s\n", params()->dtb_filename);
}
- dtb_file->setTextBase(params()->atags_addr + loadAddrOffset);
+ dtb_file->setLoadOffset(params()->atags_addr + loadAddrOffset);
dtb_file->loadSegments(physProxy);
delete dtb_file;
} else {
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
index 1a1d4a2a0..f98572690 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -75,8 +75,7 @@ ArmProcess32::ArmProcess32(ProcessParams *params, ObjectFile *objFile,
ObjectFile::Arch _arch)
: ArmProcess(params, objFile, _arch)
{
- Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize(), PageBytes);
+ Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
Addr stack_base = 0xbf000000L;
Addr max_stack_size = 8 * 1024 * 1024;
Addr next_thread_stack_base = stack_base - max_stack_size;
@@ -90,8 +89,7 @@ ArmProcess64::ArmProcess64(ProcessParams *params, ObjectFile *objFile,
ObjectFile::Arch _arch)
: ArmProcess(params, objFile, _arch)
{
- Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize(), PageBytes);
+ Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
Addr stack_base = 0x7fffff0000L;
Addr max_stack_size = 8 * 1024 * 1024;
Addr next_thread_stack_base = stack_base - max_stack_size;
diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc
index e3405fdaa..1808372d9 100644
--- a/src/arch/mips/process.cc
+++ b/src/arch/mips/process.cc
@@ -65,8 +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->dataBase() + objFile->dataSize() +
- objFile->bssSize();
+ Addr brk_point = objFile->maxSegmentAddr();
brk_point = roundUp(brk_point, PageBytes);
// Set up region for mmaps. Start it 1GB above the top of the heap.
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
index 467c820f2..b391773ee 100644
--- a/src/arch/power/process.cc
+++ b/src/arch/power/process.cc
@@ -56,8 +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->dataBase() + objFile->dataSize() +
- objFile->bssSize();
+ Addr brk_point = objFile->maxSegmentAddr();
brk_point = roundUp(brk_point, PageBytes);
Addr stack_base = 0xbf000000L;
diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc
index ca3f0e2b8..e15197d78 100644
--- a/src/arch/riscv/process.cc
+++ b/src/arch/riscv/process.cc
@@ -75,8 +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->bssBase() + objFile->bssSize(),
- PageBytes);
+ const Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
const Addr mmap_end = 0x4000000000000000L;
memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
next_thread_stack_base, mmap_end);
@@ -88,8 +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->bssBase() + objFile->bssSize(),
- PageBytes);
+ const Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
const Addr mmap_end = 0x40000000L;
memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
next_thread_stack_base, mmap_end);
diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh
index eeb267116..f8f19f290 100644
--- a/src/arch/sparc/process.hh
+++ b/src/arch/sparc/process.hh
@@ -78,8 +78,7 @@ class Sparc32Process : public SparcProcess
Sparc32Process(ProcessParams * params, ObjectFile *objFile)
: SparcProcess(params, objFile, 0)
{
- Addr brk_point = objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize();
+ Addr brk_point = objFile->maxSegmentAddr();
brk_point = roundUp(brk_point, SparcISA::PageBytes);
// Reserve 8M for main stack.
@@ -123,8 +122,7 @@ class Sparc64Process : public SparcProcess
Sparc64Process(ProcessParams * params, ObjectFile *objFile)
: SparcProcess(params, objFile, 2047)
{
- Addr brk_point = objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize();
+ Addr brk_point = objFile->maxSegmentAddr();
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 5896061a6..e9615b00c 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -137,22 +137,22 @@ SparcSystem::initState()
System::initState();
// Load reset binary into memory
- reset->setTextBase(params()->reset_addr);
+ reset->setLoadOffset(params()->reset_addr);
reset->loadSegments(physProxy);
// Load the openboot binary
- openboot->setTextBase(params()->openboot_addr);
+ openboot->setLoadOffset(params()->openboot_addr);
openboot->loadSegments(physProxy);
// Load the hypervisor binary
- hypervisor->setTextBase(params()->hypervisor_addr);
+ hypervisor->setLoadOffset(params()->hypervisor_addr);
hypervisor->loadSegments(physProxy);
// Load the nvram image
- nvram->setTextBase(params()->nvram_addr);
+ nvram->setLoadOffset(params()->nvram_addr);
nvram->loadSegments(physProxy);
// Load the hypervisor description image
- hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
+ hypervisor_desc->setLoadOffset(params()->hypervisor_desc_addr);
hypervisor_desc->loadSegments(physProxy);
// Load the partition description image
- partition_desc->setTextBase(params()->partition_desc_addr);
+ partition_desc->setLoadOffset(params()->partition_desc_addr);
partition_desc->loadSegments(physProxy);
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 60f4f474b..c743685d0 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -136,8 +136,7 @@ X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile,
vsyscallPage.vtimeOffset = 0x400;
vsyscallPage.vgettimeofdayOffset = 0x0;
- Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize(), PageBytes);
+ Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
Addr stack_base = 0x7FFFFFFFF000ULL;
Addr max_stack_size = 8 * 1024 * 1024;
Addr next_thread_stack_base = stack_base - max_stack_size;
@@ -176,8 +175,7 @@ I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
vsyscallPage.vsyscallOffset = 0x400;
vsyscallPage.vsysexitOffset = 0x410;
- Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
- objFile->bssSize(), PageBytes);
+ Addr brk_point = roundUp(objFile->maxSegmentAddr(), PageBytes);
Addr stack_base = _gdtStart;
Addr max_stack_size = 8 * 1024 * 1024;
Addr next_thread_stack_base = stack_base - max_stack_size;
diff --git a/src/base/loader/aout_object.cc b/src/base/loader/aout_object.cc
index e3f703e1d..97651586f 100644
--- a/src/base/loader/aout_object.cc
+++ b/src/base/loader/aout_object.cc
@@ -61,21 +61,14 @@ AoutObject::AoutObject(const string &_filename,
entry = execHdr->entry;
- text.base = N_TXTADDR(*execHdr);
- text.size = execHdr->tsize;
- text.data = fileData + N_TXTOFF(*execHdr);
-
- data.base = N_DATADDR(*execHdr);
- data.size = execHdr->dsize;
- data.data = fileData + N_DATOFF(*execHdr);
-
- bss.base = N_BSSADDR(*execHdr);
- bss.size = execHdr->bsize;
- bss.data = NULL;
-
- DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n",
- text.base, text.size, data.base, data.size,
- bss.base, bss.size);
+ 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);
+
+ for (auto &seg: segments)
+ DPRINTFR(Loader, "%s\n", *seg);
}
diff --git a/src/base/loader/dtb_object.cc b/src/base/loader/dtb_object.cc
index 92e305ffa..275139a8c 100644
--- a/src/base/loader/dtb_object.cc
+++ b/src/base/loader/dtb_object.cc
@@ -53,20 +53,10 @@ 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)
+ : ObjectFile(_filename, _len, _data, _arch, _opSys),
+ data(new Segment{ "data", 0, fileData, len })
{
- text.base = 0;
- text.size = len;
- text.data = fileData;
-
- data.base = 0;
- data.size = 0;
- data.data = nullptr;
-
- bss.base = 0;
- bss.size = 0;
- bss.data = nullptr;
-
+ segments.emplace_back(data);
fileDataMmapped = true;
}
@@ -92,10 +82,10 @@ DtbObject::addBootCmdLine(const char* _args, size_t len)
const char* property_name = "bootargs";
// Make a new buffer that has extra space to add nodes/properties
- int newLen = 2*this->len;
- uint8_t* fdt_buf_w_space = new uint8_t[newLen];
+ int newLen = 2 * this->len;
+ uint8_t *fdt_buf_w_space = new uint8_t[newLen];
// Copy and unpack flattened device tree into new buffer
- int ret = fdt_open_into((void*)fileData, (void*)fdt_buf_w_space, (newLen));
+ int ret = fdt_open_into((void *)fileData, (void *)fdt_buf_w_space, newLen);
if (ret < 0) {
warn("Error resizing buffer of flattened device tree, "
"errno: %d\n", ret);
@@ -104,14 +94,15 @@ DtbObject::addBootCmdLine(const char* _args, size_t len)
}
// First try finding the /chosen node in the dtb
- int offset = fdt_path_offset((void*)fdt_buf_w_space, full_path_node_name);
+ int offset = fdt_path_offset((void *)fdt_buf_w_space, full_path_node_name);
if (offset < 0) {
// try adding the node by walking dtb tree to proper insertion point
- offset = fdt_path_offset((void*)fdt_buf_w_space, root_path);
- offset = fdt_add_subnode((void*)fdt_buf_w_space, offset, node_name);
+ offset = fdt_path_offset((void *)fdt_buf_w_space, root_path);
+ offset = fdt_add_subnode((void *)fdt_buf_w_space, offset, node_name);
// if we successfully add the subnode, get the offset
if (offset >= 0)
- offset = fdt_path_offset((void*)fdt_buf_w_space, full_path_node_name);
+ offset = fdt_path_offset((void *)fdt_buf_w_space,
+ full_path_node_name);
if (offset < 0) {
warn("Error finding or adding \"chosen\" subnode to flattened "
@@ -122,8 +113,8 @@ DtbObject::addBootCmdLine(const char* _args, size_t len)
}
// Set the bootargs property in the /chosen node
- ret = fdt_setprop((void*)fdt_buf_w_space, offset, property_name,
- (const void*)_args, len+1);
+ ret = fdt_setprop((void *)fdt_buf_w_space, offset, property_name,
+ (const void *)_args, len+1);
if (ret < 0) {
warn("Error setting \"bootargs\" property to flattened device tree, "
"errno: %d\n", ret);
@@ -132,7 +123,7 @@ DtbObject::addBootCmdLine(const char* _args, size_t len)
}
// Repack the dtb for kernel use
- ret = fdt_pack((void*)fdt_buf_w_space);
+ ret = fdt_pack((void *)fdt_buf_w_space);
if (ret < 0) {
warn("Error re-packing flattened device tree structure, "
"errno: %d\n", ret);
@@ -140,8 +131,8 @@ DtbObject::addBootCmdLine(const char* _args, size_t len)
return false;
}
- text.size = newLen;
- text.data = fdt_buf_w_space;
+ data->size = newLen;
+ data->data = fdt_buf_w_space;
// clean up old buffer and set to new fdt blob
munmap(fileData, this->len);
@@ -155,7 +146,7 @@ DtbObject::addBootCmdLine(const char* _args, size_t len)
Addr
DtbObject::findReleaseAddr()
{
- void *fd = (void*)fileData;
+ void *fd = (void *)fileData;
int offset = fdt_path_offset(fd, "/cpus/cpu@0");
int len;
@@ -164,9 +155,11 @@ DtbObject::findReleaseAddr()
Addr rel_addr = 0;
if (len > 3)
- rel_addr = betoh(*static_cast<const uint32_t*>(temp));
- if (len == 8)
- rel_addr = (rel_addr << 32) | betoh(*(static_cast<const uint32_t*>(temp)+1));
+ rel_addr = betoh(*static_cast<const uint32_t *>(temp));
+ if (len == 8) {
+ rel_addr = (rel_addr << 32) |
+ betoh(*(static_cast<const uint32_t *>(temp) + 1));
+ }
return rel_addr;
}
diff --git a/src/base/loader/dtb_object.hh b/src/base/loader/dtb_object.hh
index c49b144ac..7cb842e43 100644
--- a/src/base/loader/dtb_object.hh
+++ b/src/base/loader/dtb_object.hh
@@ -49,6 +49,8 @@ class DtbObject : public ObjectFile
*/
bool fileDataMmapped;
+ Segment *data;
+
public:
virtual ~DtbObject();
diff --git a/src/base/loader/ecoff_object.cc b/src/base/loader/ecoff_object.cc
index 76b91dd66..56f9b35fc 100644
--- a/src/base/loader/ecoff_object.cc
+++ b/src/base/loader/ecoff_object.cc
@@ -73,21 +73,14 @@ EcoffObject::EcoffObject(const string &_filename, size_t _len, uint8_t *_data,
entry = aoutHdr->entry;
- text.base = aoutHdr->text_start;
- text.size = aoutHdr->tsize;
- text.data = fileData + ECOFF_TXTOFF(execHdr);
-
- data.base = aoutHdr->data_start;
- data.size = aoutHdr->dsize;
- data.data = fileData + ECOFF_DATOFF(execHdr);
-
- bss.base = aoutHdr->bss_start;
- bss.size = aoutHdr->bsize;
- bss.data = nullptr;
-
- DPRINTFR(Loader, "text: %#x %d\ndata: %#x %d\nbss: %#x %d\n",
- text.base, text.size, data.base, data.size,
- bss.base, bss.size);
+ 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);
}
bool
diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
index 327919540..4dee7d2c0 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -293,45 +293,8 @@ ElfObject::ElfObject(const std::string &_filename, size_t _len,
entry = ehdr.e_entry;
- // initialize segment sizes to 0 in case they're not present
- text.size = data.size = bss.size = 0;
- text.base = data.base = bss.base = 0;
-
int sec_idx = 1;
- // The first address of some important sections.
- Addr text_sec_start = 0;
- Addr data_sec_start = 0;
- Addr bss_sec_start = 0;
-
- // Get the first section
- Elf_Scn *section = elf_getscn(elf, sec_idx);
-
- // Find the beginning of the most interesting sections.
- while (section) {
- GElf_Shdr shdr;
- gelf_getshdr(section, &shdr);
- char *sec_name = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name);
-
- if (sec_name) {
- if (!strcmp(".text", sec_name)) {
- text_sec_start = shdr.sh_addr;
- } else if (!strcmp(".data", sec_name)) {
- data_sec_start = shdr.sh_addr;
- } else if (!strcmp(".bss", sec_name)) {
- bss_sec_start = shdr.sh_addr;
- }
- } else {
- Elf_Error errorNum = (Elf_Error)elf_errno();
- if (errorNum != ELF_E_NONE) {
- const char *errorMessage = elf_errmsg(errorNum);
- fatal("Error from libelf: %s.\n", errorMessage);
- }
- }
-
- section = elf_getscn(elf, ++sec_idx);
- }
-
// Go through all the segments in the program, record them, and scrape
// out information about the text, data, and bss areas needed by other
// code.
@@ -348,50 +311,54 @@ ElfObject::ElfObject(const std::string &_filename, size_t _len,
ldMin = std::min(ldMin, phdr.p_vaddr);
ldMax = std::max(ldMax, phdr.p_vaddr + phdr.p_memsz);
- // Check to see if this segment contains the bss section.
- if (phdr.p_paddr <= bss_sec_start &&
- phdr.p_paddr + phdr.p_memsz > bss_sec_start &&
- phdr.p_memsz - phdr.p_filesz > 0) {
- bss.base = phdr.p_paddr + phdr.p_filesz;
- bss.size = phdr.p_memsz - phdr.p_filesz;
- bss.data = nullptr;
+ std::string name;
+
+ // Get the first section
+ Elf_Scn *section = elf_getscn(elf, sec_idx);
+
+ // Name segments after the sections they contain.
+ while (section) {
+ GElf_Shdr shdr;
+ gelf_getshdr(section, &shdr);
+ char *sec_name = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name);
+
+ if (!sec_name) {
+ Elf_Error errorNum = (Elf_Error)elf_errno();
+ if (errorNum != ELF_E_NONE) {
+ const char *errorMessage = elf_errmsg(errorNum);
+ fatal("Error from libelf: %s.\n", errorMessage);
+ }
+ }
+
+ if (shdr.sh_addr >= ldMin && shdr.sh_addr < ldMax) {
+ if (name != "")
+ name += ",";
+ name += sec_name;
+ }
+
+ section = elf_getscn(elf, ++sec_idx);
}
- // Check to see if this is the text or data segment
- if (phdr.p_vaddr <= text_sec_start &&
- phdr.p_vaddr + phdr.p_filesz > text_sec_start) {
-
- // If this value is nonzero, we need to flip the relocate flag.
- if (phdr.p_vaddr != 0)
- relocate = false;
-
- text.base = phdr.p_paddr;
- text.size = phdr.p_filesz;
- text.data = fileData + phdr.p_offset;
- } else if (phdr.p_vaddr <= data_sec_start &&
- phdr.p_vaddr + phdr.p_filesz > data_sec_start) {
- data.base = phdr.p_paddr;
- data.size = phdr.p_filesz;
- data.data = fileData + phdr.p_offset;
- } else {
- // If it's none of the above but is loadable,
- // load the filesize worth of data
- Segment extra;
- extra.base = phdr.p_paddr;
- extra.size = phdr.p_filesz;
- extra.data = fileData + phdr.p_offset;
- extraSegments.push_back(extra);
+ 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);
}
}
// should have found at least one loadable segment
- warn_if(text.size == 0,
- "Empty .text segment in '%s'. ELF file corrupted?\n",
+ warn_if(segments.empty(),
+ "No loadable segments in '%s'. ELF file corrupted?\n",
filename);
- DPRINTFR(Loader, "text: %#x %d\ndata: %#x %d\nbss: %#x %d\n",
- text.base, text.size, data.base, data.size,
- bss.base, bss.size);
+ for (auto &seg: segments)
+ DPRINTFR(Loader, "%s\n", *seg);
elf_end(elf);
@@ -498,20 +465,13 @@ ElfObject::loadWeakSymbols(SymbolTable *symtab, Addr base, Addr offset,
}
bool
-ElfObject::loadSegments(const PortProxy& mem_proxy, Addr addr_mask,
- Addr offset)
+ElfObject::loadSegments(const PortProxy &mem_proxy)
{
- if (!ObjectFile::loadSegments(mem_proxy, addr_mask, offset))
+ if (!ObjectFile::loadSegments(mem_proxy))
return false;
- for (auto seg : extraSegments) {
- if (!loadSegment(&seg, mem_proxy, addr_mask, offset)) {
- return false;
- }
- }
-
if (interpreter)
- interpreter->loadSegments(mem_proxy, addr_mask, offset);
+ interpreter->loadSegments(mem_proxy);
return true;
}
@@ -570,9 +530,6 @@ ElfObject::updateBias(Addr bias_addr)
entry += bias_addr;
// Patch segments with the bias_addr.
- text.base += bias_addr;
- data.base += bias_addr;
- bss.base += bias_addr;
- for (auto &segment : extraSegments)
- segment.base += bias_addr;
+ for (auto &segment : segments)
+ segment->base += bias_addr;
}
diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh
index 244b9fc3f..f2af4142a 100644
--- a/src/base/loader/elf_object.hh
+++ b/src/base/loader/elf_object.hh
@@ -86,13 +86,10 @@ class ElfObject : public ObjectFile
void getSections();
bool sectionExists(std::string sec);
- std::vector<Segment> extraSegments;
-
public:
virtual ~ElfObject() {}
- bool loadSegments(const PortProxy& mem_proxy, Addr addr_mask = maxAddr,
- Addr offset = 0) override;
+ bool loadSegments(const PortProxy &mem_proxy) override;
virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0,
Addr offset = 0, Addr addr_mask = maxAddr)
diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc
index 8a6b063de..d63b2221b 100644
--- a/src/base/loader/object_file.cc
+++ b/src/base/loader/object_file.cc
@@ -57,10 +57,8 @@ ObjectFile::ObjectFile(const string &_filename,
size_t _len, uint8_t *_data,
Arch _arch, OpSys _op_sys)
: filename(_filename), fileData(_data), len(_len),
- arch(_arch), opSys(_op_sys), entry(0),
- text{0, nullptr, 0}, data{0, nullptr, 0}, bss{0, nullptr, 0}
-{
-}
+ arch(_arch), opSys(_op_sys), entry(0)
+{}
ObjectFile::~ObjectFile()
@@ -73,11 +71,10 @@ ObjectFile::~ObjectFile()
bool
-ObjectFile::loadSegment(Segment *seg, const PortProxy& mem_proxy,
- Addr addr_mask, Addr offset)
+ObjectFile::loadSegment(Segment *seg, const PortProxy &mem_proxy)
{
if (seg->size != 0) {
- Addr addr = (seg->base & addr_mask) + offset;
+ Addr addr = (seg->base & loadMask) + loadOffset;
if (seg->data) {
mem_proxy.writeBlob(addr, seg->data, seg->size);
} else {
@@ -90,12 +87,12 @@ ObjectFile::loadSegment(Segment *seg, const PortProxy& mem_proxy,
bool
-ObjectFile::loadSegments(const PortProxy& mem_proxy, Addr addr_mask,
- Addr offset)
+ObjectFile::loadSegments(const PortProxy &proxy)
{
- return (loadSegment(&text, mem_proxy, addr_mask, offset)
- && loadSegment(&data, mem_proxy, addr_mask, offset)
- && loadSegment(&bss, mem_proxy, addr_mask, offset));
+ 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 db995f5d7..e5053ad82 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -33,7 +33,9 @@
#define __OBJECT_FILE_HH__
#include <limits>
+#include <memory>
#include <string>
+#include <vector>
#include "base/logging.hh"
#include "base/types.hh"
@@ -72,10 +74,14 @@ 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;
@@ -86,10 +92,7 @@ class ObjectFile
public:
virtual ~ObjectFile();
- static const Addr maxAddr = std::numeric_limits<Addr>::max();
-
- virtual bool loadSegments(const PortProxy &mem_proxy,
- Addr mask=maxAddr, Addr offset=0);
+ virtual bool loadSegments(const PortProxy &mem_proxy);
virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0,
Addr offset=0, Addr mask=maxAddr) = 0;
@@ -114,41 +117,76 @@ class ObjectFile
Arch getArch() const { return arch; }
OpSys getOpSys() const { return opSys; }
- protected:
-
struct Segment
{
+ std::string name;
Addr base;
uint8_t *data;
size_t size;
};
+ protected:
Addr entry;
- Segment text;
- Segment data;
- Segment bss;
+ std::vector<std::unique_ptr<Segment>> segments;
- bool loadSegment(Segment *seg, const PortProxy &mem_proxy, Addr mask,
- Addr offset=0);
+ 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 textBase() const { return text.base; }
- Addr dataBase() const { return data.base; }
- Addr bssBase() const { return bss.base; }
-
- size_t textSize() const { return text.size; }
- size_t dataSize() const { return data.size; }
- size_t bssSize() const { return bss.size; }
+ 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 setTextBase(Addr a) { text.base = a; }
+ 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
@@ -183,6 +221,13 @@ 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 9662d8613..b0ece3ba2 100644
--- a/src/base/loader/raw_object.cc
+++ b/src/base/loader/raw_object.cc
@@ -43,23 +43,10 @@ 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)
+ : ObjectFile(_filename, _len, _data, _arch, _opSys),
+ data(new Segment{ "data", 0, fileData, len })
{
- text.base = 0;
- text.size = len;
- text.data = fileData;
-
- data.base = 0;
- data.size = 0;
- data.data = nullptr;
-
- bss.base = 0;
- bss.size = 0;
- bss.data = nullptr;
-
- DPRINTFR(Loader, "text: %#x %d\ndata: %#x %d\nbss: %#x %d\n",
- text.base, text.size, data.base, data.size,
- bss.base, bss.size);
+ segments.emplace_back(data);
}
bool
diff --git a/src/base/loader/raw_object.hh b/src/base/loader/raw_object.hh
index 6931a1321..9eb929107 100644
--- a/src/base/loader/raw_object.hh
+++ b/src/base/loader/raw_object.hh
@@ -38,6 +38,9 @@ class RawObject: public ObjectFile
protected:
RawObject(const std::string &_filename, size_t _len,
uint8_t *_data, Arch _arch, OpSys _opSys);
+
+ Segment *data;
+
public:
virtual ~RawObject() {}
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index fb6e9a168..6c3b172c2 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -1888,19 +1888,14 @@ mmapImpl(SyscallDesc *desc, int num, ThreadContext *tc, bool is_mmap2)
// 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) {
+ 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->textBase(), start);
+ lib->minSegmentAddr(), start);
}
}
}
diff --git a/src/sim/system.cc b/src/sim/system.cc
index 73f93a257..bf8b45239 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -152,14 +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);
// setup entry points
- kernelStart = kernel->textBase();
- kernelEnd = kernel->bssBase() + kernel->bssSize();
+ kernelStart = kernel->minSegmentAddr();
+ kernelEnd = kernel->maxSegmentAddr();
kernelEntry = kernel->entryPoint();
// If load_addr_mask is set to 0x0, then auto-calculate
@@ -168,6 +170,7 @@ System::System(Params *p)
if (loadAddrMask == 0) {
Addr shift_amt = findMsbSet(kernelEnd - kernelStart) + 1;
loadAddrMask = ((Addr)1 << shift_amt) - 1;
+ kernel->setLoadMask(loadAddrMask);
}
// load symbols
@@ -192,6 +195,8 @@ 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);
}
}
@@ -327,11 +332,9 @@ System::initState()
}
}
// Load program sections into memory
- kernel->loadSegments(physProxy, loadAddrMask, loadAddrOffset);
- for (const auto &extra_kernel : kernelExtras) {
- extra_kernel->loadSegments(physProxy, loadAddrMask,
- loadAddrOffset);
- }
+ kernel->loadSegments(physProxy);
+ for (const auto &extra_kernel : kernelExtras)
+ extra_kernel->loadSegments(physProxy);
DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd);