From 612f8f074fa1099cf70faf495d46cc647762a031 Mon Sep 17 00:00:00 2001 From: ARM gem5 Developers Date: Fri, 24 Jan 2014 15:29:34 -0600 Subject: arm: Add support for ARMv8 (AArch64 & AArch32) Note: AArch64 and AArch32 interworking is not supported. If you use an AArch64 kernel you are restricted to AArch64 user-mode binaries. This will be addressed in a later patch. Note: Virtualization is only supported in AArch32 mode. This will also be fixed in a later patch. Contributors: Giacomo Gabrielli (TrustZone, LPAE, system-level AArch64, AArch64 NEON, validation) Thomas Grocutt (AArch32 Virtualization, AArch64 FP, validation) Mbou Eyole (AArch64 NEON, validation) Ali Saidi (AArch64 Linux support, code integration, validation) Edmund Grimley-Evans (AArch64 FP) William Wang (AArch64 Linux support) Rene De Jong (AArch64 Linux support, performance opt.) Matt Horsnell (AArch64 MP, validation) Matt Evans (device models, code integration, validation) Chris Adeniyi-Jones (AArch64 syscall-emulation) Prakash Ramrakhyani (validation) Dam Sunwoo (validation) Chander Sudanthi (validation) Stephan Diestelhorst (validation) Andreas Hansson (code integration, performance opt.) Eric Van Hensbergen (performance opt.) Gabe Black --- src/base/loader/elf_object.cc | 47 ++++++++++++++++++++++++++++-------------- src/base/loader/elf_object.hh | 15 +++++++++++++- src/base/loader/object_file.cc | 12 +++++------ src/base/loader/object_file.hh | 7 +++++-- 4 files changed, 56 insertions(+), 25 deletions(-) (limited to 'src/base/loader') 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::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::max()); + Addr addrMask = std::numeric_limits::max(), + Addr offset = 0); virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask = std::numeric_limits::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::max()); + std::numeric_limits::max(), + Addr offset = 0); virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask = std::numeric_limits::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: -- cgit v1.2.3