summaryrefslogtreecommitdiff
path: root/src/base/loader
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/loader')
-rw-r--r--src/base/loader/elf_object.cc47
-rw-r--r--src/base/loader/elf_object.hh15
-rw-r--r--src/base/loader/object_file.cc12
-rw-r--r--src/base/loader/object_file.hh7
4 files changed, 56 insertions, 25 deletions
diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
index 6d4c29776..9445f1df9 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011-2013 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -61,7 +73,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
assert(elf != NULL);
// Check that we actually have a elf file
- if (gelf_getehdr(elf, &ehdr) ==0) {
+ if (gelf_getehdr(elf, &ehdr) == 0) {
DPRINTFR(Loader, "Not ELF\n");
elf_end(elf);
return NULL;
@@ -94,23 +106,27 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
} else if (ehdr.e_machine == EM_386 &&
ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
arch = ObjectFile::I386;
- } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
- arch = ObjectFile::Alpha;
- } else if (ehdr.e_machine == EM_ARM) {
+ } else if (ehdr.e_machine == EM_ARM &&
+ ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
if (bits(ehdr.e_entry, 0)) {
arch = ObjectFile::Thumb;
} else {
arch = ObjectFile::Arm;
}
+ } else if ((ehdr.e_machine == EM_AARCH64) &&
+ ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
+ arch = ObjectFile::Arm64;
+ } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
+ arch = ObjectFile::Alpha;
} else if (ehdr.e_machine == EM_PPC &&
ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
- if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) {
- arch = ObjectFile::Power;
- } else {
- fatal("The binary you're trying to load is compiled for "
+ if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) {
+ arch = ObjectFile::Power;
+ } else {
+ fatal("The binary you're trying to load is compiled for "
"little endian Power.\nM5 only supports big "
"endian Power. Please recompile your binary.\n");
- }
+ }
} else if (ehdr.e_machine == EM_PPC64) {
fatal("The binary you're trying to load is compiled for 64-bit "
"Power. M5\n only supports 32-bit Power. Please "
@@ -121,9 +137,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
}
//Detect the operating system
- switch (ehdr.e_ident[EI_OSABI])
- {
-
+ switch (ehdr.e_ident[EI_OSABI]) {
case ELFOSABI_LINUX:
opSys = ObjectFile::Linux;
break;
@@ -206,7 +220,8 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
if(phdr.p_offset <= e_phoff &&
phdr.p_offset + phdr.p_filesz > e_phoff)
{
- result->_programHeaderTable = phdr.p_paddr + e_phoff;
+ result->_programHeaderTable =
+ phdr.p_paddr + (e_phoff - phdr.p_offset);
break;
}
}
@@ -423,15 +438,15 @@ ElfObject::loadWeakSymbols(SymbolTable *symtab, Addr addrMask)
}
bool
-ElfObject::loadSections(PortProxy& memProxy, Addr addrMask)
+ElfObject::loadSections(PortProxy& memProxy, Addr addrMask, Addr offset)
{
- if (!ObjectFile::loadSections(memProxy, addrMask))
+ if (!ObjectFile::loadSections(memProxy, addrMask, offset))
return false;
vector<Segment>::iterator extraIt;
for (extraIt = extraSegments.begin();
extraIt != extraSegments.end(); extraIt++) {
- if (!loadSection(&(*extraIt), memProxy, addrMask)) {
+ if (!loadSection(&(*extraIt), memProxy, addrMask, offset)) {
return false;
}
}
diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh
index d3d3e5197..84b73b0a8 100644
--- a/src/base/loader/elf_object.hh
+++ b/src/base/loader/elf_object.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2013 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -66,7 +78,8 @@ class ElfObject : public ObjectFile
virtual ~ElfObject() {}
bool loadSections(PortProxy& memProxy,
- Addr addrMask = std::numeric_limits<Addr>::max());
+ Addr addrMask = std::numeric_limits<Addr>::max(),
+ Addr offset = 0);
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max());
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc
index b9f84283b..170e18d5e 100644
--- a/src/base/loader/object_file.cc
+++ b/src/base/loader/object_file.cc
@@ -66,10 +66,10 @@ ObjectFile::~ObjectFile()
bool
-ObjectFile::loadSection(Section *sec, PortProxy& memProxy, Addr addrMask)
+ObjectFile::loadSection(Section *sec, PortProxy& memProxy, Addr addrMask, Addr offset)
{
if (sec->size != 0) {
- Addr addr = sec->baseAddr & addrMask;
+ Addr addr = (sec->baseAddr & addrMask) + offset;
if (sec->fileImage) {
memProxy.writeBlob(addr, sec->fileImage, sec->size);
}
@@ -83,11 +83,11 @@ ObjectFile::loadSection(Section *sec, PortProxy& memProxy, Addr addrMask)
bool
-ObjectFile::loadSections(PortProxy& memProxy, Addr addrMask)
+ObjectFile::loadSections(PortProxy& memProxy, Addr addrMask, Addr offset)
{
- return (loadSection(&text, memProxy, addrMask)
- && loadSection(&data, memProxy, addrMask)
- && loadSection(&bss, memProxy, addrMask));
+ return (loadSection(&text, memProxy, addrMask, offset)
+ && loadSection(&data, memProxy, addrMask, offset)
+ && loadSection(&bss, memProxy, addrMask, offset));
}
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
index bdc9a31a1..09cde5b53 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -52,6 +52,7 @@ class ObjectFile
Mips,
X86_64,
I386,
+ Arm64,
Arm,
Thumb,
Power
@@ -84,7 +85,8 @@ class ObjectFile
void close();
virtual bool loadSections(PortProxy& memProxy, Addr addrMask =
- std::numeric_limits<Addr>::max());
+ 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 =
@@ -114,7 +116,8 @@ class ObjectFile
Section data;
Section bss;
- bool loadSection(Section *sec, PortProxy& memProxy, Addr addrMask);
+ bool loadSection(Section *sec, PortProxy& memProxy, Addr addrMask,
+ Addr offset = 0);
void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
public: