diff options
Diffstat (limited to 'base/loader/elf_object.cc')
-rw-r--r-- | base/loader/elf_object.cc | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc index 2925817cd..b9636b454 100644 --- a/base/loader/elf_object.cc +++ b/base/loader/elf_object.cc @@ -92,7 +92,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) arch = ObjectFile::SPARC; } else if (ehdr.e_machine == EM_MIPS && ehdr.e_ident[EI_CLASS] == ELFCLASS32) { - arch = ObjectFile::MIPS; + arch = ObjectFile::Mips; } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) { arch = ObjectFile::Alpha; } else { @@ -156,14 +156,49 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) section = elf_getscn(elf, ++secIdx); } // while sections } + + int32_t global_ptr; + if (arch == ObjectFile::Mips) { + Elf_Scn *section; + GElf_Shdr shdr; + Elf_Data *rdata; + 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); + /*shdr.sh_type == SHT_MIPS_REGINFO && */ + if (!strcmp(".reginfo",elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) { + // We have found MIPS reginfo section: + // ------------------------------- + // Check the 6th 32bit word for the initialized global pointer value + // ------------------------------- + rdata = elf_rawdata(section, NULL); + assert(rdata->d_buf); + + if(ehdr.e_ident[EI_DATA] == ELFDATA2LSB) + global_ptr = htole(((int32_t*)rdata->d_buf)[5]); + else + global_ptr = htobe(((int32_t*)rdata->d_buf)[5]); + break; + } + + section = elf_getscn(elf, ++secIdx); + } // if section found + + } + elf_end(elf); - return new ElfObject(fname, fd, len, data, arch, opSys); + return new ElfObject(fname, fd, len, data, global_ptr,arch, opSys); } } ElfObject::ElfObject(const string &_filename, int _fd, - size_t _len, uint8_t *_data, + size_t _len, uint8_t *_data,Addr global_ptr, Arch _arch, OpSys _opSys) : ObjectFile(_filename, _fd, _len, _data, _arch, _opSys) @@ -187,6 +222,8 @@ ElfObject::ElfObject(const string &_filename, int _fd, entry = ehdr.e_entry; + globalPtr = global_ptr; + // initialize segment sizes to 0 in case they're not present text.size = data.size = bss.size = 0; |