diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2006-03-09 18:35:28 -0500 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2006-03-09 18:35:28 -0500 |
commit | 872bbdfc33cb82bf32576db3a57d3055a04acbac (patch) | |
tree | 837dd214bd682ac7efa515b18857bec7d4d35bef /base/loader/elf_object.cc | |
parent | 3adb45144aca819c9796168ecde7a263169d9d4d (diff) | |
parent | 7b283dbc090d1197593b00fd1279b92f7c2e693e (diff) | |
download | gem5-872bbdfc33cb82bf32576db3a57d3055a04acbac.tar.xz |
Hand merge. Stuff probably doesn't compile.
--HG--
rename : arch/alpha/isa_desc => arch/alpha/isa/main.isa
rename : arch/alpha/alpha_linux_process.cc => arch/alpha/linux/process.cc
rename : arch/alpha/alpha_linux_process.hh => arch/alpha/linux/process.hh
rename : arch/alpha/alpha_tru64_process.cc => arch/alpha/tru64/process.cc
rename : arch/alpha/alpha_tru64_process.hh => arch/alpha/tru64/process.hh
rename : cpu/exec_context.cc => cpu/cpu_exec_context.cc
rename : cpu/exec_context.hh => cpu/cpu_exec_context.hh
extra : convert_revision : 7d1efcedd708815d985a951f6f010fbd83dc27e8
Diffstat (limited to 'base/loader/elf_object.cc')
-rw-r--r-- | base/loader/elf_object.cc | 94 |
1 files changed, 83 insertions, 11 deletions
diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc index 52f236fef..1136686f0 100644 --- a/base/loader/elf_object.cc +++ b/base/loader/elf_object.cc @@ -38,8 +38,8 @@ #define __LIBELF_NEED_LINK_H 0 #define __LIBELF_SYMBOL_VERSIONS 0 -#include <libelf/libelf.h> -#include <libelf/gelf.h> +#include "libelf/libelf.h" +#include "libelf/gelf.h" #include "base/loader/elf_object.hh" @@ -55,6 +55,8 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) { Elf *elf; GElf_Ehdr ehdr; + Arch arch = UnknownArch; + OpSys opSys = UnknownOpSys; // check that header matches library version if (elf_version(EV_CURRENT) == EV_NONE) @@ -72,17 +74,87 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) return NULL; } else { - if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) - panic("32 bit ELF Binary, Not Supported"); - /* @todo this emachine value isn't offical yet. - * so we probably shouldn't check it. */ -// if (ehdr.e_machine != EM_ALPHA) -// panic("Non Alpha Binary, Not Supported"); + //Detect the architecture + //Versioning issues in libelf need to be resolved to get the correct + //SPARC constants. + //If MIPS supports 32 bit executables, this may need to be changed. + //Also, there are other MIPS constants which may be used, like + //EM_MIPS_RS3_LE and EM_MIPS_X + //Since we don't know how to check for alpha right now, we'll + //just assume if it wasn't something else and it's 64 bit, that's + //what it must be. + if (ehdr.e_machine == EM_SPARC64 || + ehdr.e_machine == EM_SPARC || + ehdr.e_machine == EM_SPARCV9) { + arch = ObjectFile::SPARC; + } else if (ehdr.e_machine == EM_MIPS + && ehdr.e_ident[EI_CLASS] == ELFCLASS32) { + arch = ObjectFile::MIPS; + } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) { + arch = ObjectFile::Alpha; + } else { + arch = ObjectFile::UnknownArch; + } - elf_end(elf); + //Detect the operating system + switch (ehdr.e_ident[EI_OSABI]) + { + + case ELFOSABI_LINUX: + opSys = ObjectFile::Linux; + break; + case ELFOSABI_SOLARIS: + opSys = ObjectFile::Solaris; + break; + case ELFOSABI_TRU64: + opSys = ObjectFile::Tru64; + break; + default: + opSys = ObjectFile::UnknownOpSys; + } - return new ElfObject(fname, fd, len, data, - ObjectFile::Alpha, ObjectFile::Linux); + //take a look at the .note.ABI section + //It can let us know what's what. + if (opSys == ObjectFile::UnknownOpSys) + { + Elf_Scn *section; + GElf_Shdr shdr; + Elf_Data *data; + uint32_t osAbi;; + int secIdx = 1; + + // Get the first section + section = elf_getscn(elf, secIdx); + + // While there are no more sections + while (section != NULL) { + gelf_getshdr(section, &shdr); + if (shdr.sh_type == SHT_NOTE && !strcmp(".note.ABI-tag", + elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) { + // we have found a ABI note section + // Check the 5th 32bit word for OS 0 == linux, 1 == hurd, + // 2 == solaris, 3 == freebsd + data = elf_rawdata(section, NULL); + assert(data->d_buf); + if(ehdr.e_ident[EI_DATA] == ELFDATA2LSB) + osAbi = htole(((uint32_t*)data->d_buf)[4]); + else + osAbi = htobe(((uint32_t*)data->d_buf)[4]); + + switch(osAbi) { + case 0: + opSys = ObjectFile::Linux; + break; + case 2: + opSys = ObjectFile::Solaris; + break; + } + } // if section found + section = elf_getscn(elf, ++secIdx); + } // while sections + } + elf_end(elf); + return new ElfObject(fname, fd, len, data, arch, opSys); } } |