diff options
Diffstat (limited to 'src/base/loader')
-rw-r--r-- | src/base/loader/elf_object.cc | 47 | ||||
-rw-r--r-- | src/base/loader/elf_object.hh | 15 | ||||
-rw-r--r-- | src/base/loader/object_file.cc | 12 | ||||
-rw-r--r-- | src/base/loader/object_file.hh | 7 |
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: |