elf_object.cc revision 8706
112SN/A/* 21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 312SN/A * All rights reserved. 412SN/A * 512SN/A * Redistribution and use in source and binary forms, with or without 612SN/A * modification, are permitted provided that the following conditions are 712SN/A * met: redistributions of source code must retain the above copyright 812SN/A * notice, this list of conditions and the following disclaimer; 912SN/A * redistributions in binary form must reproduce the above copyright 1012SN/A * notice, this list of conditions and the following disclaimer in the 1112SN/A * documentation and/or other materials provided with the distribution; 1212SN/A * neither the name of the copyright holders nor the names of its 1312SN/A * contributors may be used to endorse or promote products derived from 1412SN/A * this software without specific prior written permission. 1512SN/A * 1612SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt 292665Ssaidi@eecs.umich.edu * Ali Saidi 3012SN/A */ 3112SN/A 325616Snate@binkert.org#include <cassert> 3312SN/A#include <string> 3412SN/A 3556SN/A#include "base/loader/elf_object.hh" 364484Sbinkertn@umich.edu#include "base/loader/symtab.hh" 378229Snate@binkert.org#include "base/bitfield.hh" 382439SN/A#include "base/misc.hh" 397676Snate@binkert.org#include "base/trace.hh" 408232Snate@binkert.org#include "debug/Loader.hh" 412423SN/A#include "sim/byteswap.hh" 428229Snate@binkert.org#include "gelf.h" 432423SN/A 4412SN/Ausing namespace std; 4512SN/A 4612SN/AObjectFile * 4712SN/AElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) 4812SN/A{ 49443SN/A Elf *elf; 50443SN/A GElf_Ehdr ehdr; 512207SN/A Arch arch = UnknownArch; 522207SN/A OpSys opSys = UnknownOpSys; 53443SN/A 54468SN/A // check that header matches library version 551708SN/A if (elf_version(EV_CURRENT) == EV_NONE) 561708SN/A panic("wrong elf version number!"); 57443SN/A 58468SN/A // get a pointer to elf structure 59443SN/A elf = elf_memory((char*)data,len); 60468SN/A // will only fail if fd is invalid 61443SN/A assert(elf != NULL); 62443SN/A 63468SN/A // Check that we actually have a elf file 64468SN/A if (gelf_getehdr(elf, &ehdr) ==0) { 65443SN/A DPRINTFR(Loader, "Not ELF\n"); 66443SN/A elf_end(elf); 67443SN/A return NULL; 682476SN/A } else { 692207SN/A //Detect the architecture 702207SN/A //Since we don't know how to check for alpha right now, we'll 712207SN/A //just assume if it wasn't something else and it's 64 bit, that's 722207SN/A //what it must be. 732207SN/A if (ehdr.e_machine == EM_SPARC64 || 744111Sgblack@eecs.umich.edu (ehdr.e_machine == EM_SPARC && 754111Sgblack@eecs.umich.edu ehdr.e_ident[EI_CLASS] == ELFCLASS64)|| 762620SN/A ehdr.e_machine == EM_SPARCV9) { 774111Sgblack@eecs.umich.edu arch = ObjectFile::SPARC64; 784111Sgblack@eecs.umich.edu } else if (ehdr.e_machine == EM_SPARC32PLUS || 794111Sgblack@eecs.umich.edu (ehdr.e_machine == EM_SPARC && 804111Sgblack@eecs.umich.edu ehdr.e_ident[EI_CLASS] == ELFCLASS32)) { 814111Sgblack@eecs.umich.edu arch = ObjectFile::SPARC32; 822207SN/A } else if (ehdr.e_machine == EM_MIPS 832207SN/A && ehdr.e_ident[EI_CLASS] == ELFCLASS32) { 845383Sgblack@eecs.umich.edu if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB) { 855383Sgblack@eecs.umich.edu arch = ObjectFile::Mips; 865383Sgblack@eecs.umich.edu } else { 875383Sgblack@eecs.umich.edu fatal("The binary you're trying to load is compiled for big " 885383Sgblack@eecs.umich.edu "endian MIPS. M5\nonly supports little endian MIPS. " 895383Sgblack@eecs.umich.edu "Please recompile your binary.\n"); 905383Sgblack@eecs.umich.edu } 914166Sgblack@eecs.umich.edu } else if (ehdr.e_machine == EM_X86_64 && 924166Sgblack@eecs.umich.edu ehdr.e_ident[EI_CLASS] == ELFCLASS64) { 935874Sgblack@eecs.umich.edu arch = ObjectFile::X86_64; 945874Sgblack@eecs.umich.edu } else if (ehdr.e_machine == EM_386 && 955874Sgblack@eecs.umich.edu ehdr.e_ident[EI_CLASS] == ELFCLASS32) { 965874Sgblack@eecs.umich.edu arch = ObjectFile::I386; 972207SN/A } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) { 982207SN/A arch = ObjectFile::Alpha; 995335Shines@cs.fsu.edu } else if (ehdr.e_machine == EM_ARM) { 1007095Sgblack@eecs.umich.edu if (bits(ehdr.e_entry, 0)) { 1017095Sgblack@eecs.umich.edu arch = ObjectFile::Thumb; 1027095Sgblack@eecs.umich.edu } else { 1037095Sgblack@eecs.umich.edu arch = ObjectFile::Arm; 1047095Sgblack@eecs.umich.edu } 1056691Stjones1@inf.ed.ac.uk } else if (ehdr.e_machine == EM_PPC && 1066691Stjones1@inf.ed.ac.uk ehdr.e_ident[EI_CLASS] == ELFCLASS32) { 1076691Stjones1@inf.ed.ac.uk if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) { 1086691Stjones1@inf.ed.ac.uk arch = ObjectFile::Power; 1096691Stjones1@inf.ed.ac.uk } else { 1106691Stjones1@inf.ed.ac.uk fatal("The binary you're trying to load is compiled for " 1116691Stjones1@inf.ed.ac.uk "little endian Power.\nM5 only supports big " 1126691Stjones1@inf.ed.ac.uk "endian Power. Please recompile your binary.\n"); 1136691Stjones1@inf.ed.ac.uk } 1146691Stjones1@inf.ed.ac.uk } else if (ehdr.e_machine == EM_PPC64) { 1156691Stjones1@inf.ed.ac.uk fatal("The binary you're trying to load is compiled for 64-bit " 1166691Stjones1@inf.ed.ac.uk "Power. M5\n only supports 32-bit Power. Please " 1176691Stjones1@inf.ed.ac.uk "recompile your binary.\n"); 1182207SN/A } else { 1192600SN/A warn("Unknown architecture: %d\n", ehdr.e_machine); 1202207SN/A arch = ObjectFile::UnknownArch; 1212207SN/A } 1222207SN/A 1232207SN/A //Detect the operating system 1242207SN/A switch (ehdr.e_ident[EI_OSABI]) 1252207SN/A { 1262238SN/A 1272207SN/A case ELFOSABI_LINUX: 1282207SN/A opSys = ObjectFile::Linux; 1292207SN/A break; 1302207SN/A case ELFOSABI_SOLARIS: 1312207SN/A opSys = ObjectFile::Solaris; 1322238SN/A break; 1332207SN/A case ELFOSABI_TRU64: 1342207SN/A opSys = ObjectFile::Tru64; 1352238SN/A break; 1366392Ssaidi@eecs.umich.edu case ELFOSABI_ARM: 1376392Ssaidi@eecs.umich.edu opSys = ObjectFile::LinuxArmOABI; 1386392Ssaidi@eecs.umich.edu break; 1392207SN/A default: 1402207SN/A opSys = ObjectFile::UnknownOpSys; 1412207SN/A } 1422207SN/A 1432238SN/A //take a look at the .note.ABI section 1442238SN/A //It can let us know what's what. 1452600SN/A if (opSys == ObjectFile::UnknownOpSys) { 1462238SN/A Elf_Scn *section; 1472238SN/A GElf_Shdr shdr; 1482238SN/A Elf_Data *data; 1492238SN/A uint32_t osAbi;; 1502238SN/A int secIdx = 1; 1512238SN/A 1522238SN/A // Get the first section 1532238SN/A section = elf_getscn(elf, secIdx); 1542238SN/A 1552238SN/A // While there are no more sections 1562600SN/A while (section != NULL && opSys == ObjectFile::UnknownOpSys) { 1572238SN/A gelf_getshdr(section, &shdr); 1582238SN/A if (shdr.sh_type == SHT_NOTE && !strcmp(".note.ABI-tag", 1592238SN/A elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) { 1602238SN/A // we have found a ABI note section 1612238SN/A // Check the 5th 32bit word for OS 0 == linux, 1 == hurd, 1622238SN/A // 2 == solaris, 3 == freebsd 1632238SN/A data = elf_rawdata(section, NULL); 1642238SN/A assert(data->d_buf); 1652238SN/A if(ehdr.e_ident[EI_DATA] == ELFDATA2LSB) 1662238SN/A osAbi = htole(((uint32_t*)data->d_buf)[4]); 1672238SN/A else 1682238SN/A osAbi = htobe(((uint32_t*)data->d_buf)[4]); 1692238SN/A 1702238SN/A switch(osAbi) { 1712238SN/A case 0: 1722238SN/A opSys = ObjectFile::Linux; 1732238SN/A break; 1742238SN/A case 2: 1752238SN/A opSys = ObjectFile::Solaris; 1762238SN/A break; 1772238SN/A } 1782238SN/A } // if section found 1792600SN/A if (!strcmp(".SUNW_version", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) 1802600SN/A opSys = ObjectFile::Solaris; 1812600SN/A if (!strcmp(".stab.index", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) 1822600SN/A opSys = ObjectFile::Solaris; 1832600SN/A 1842238SN/A section = elf_getscn(elf, ++secIdx); 1852238SN/A } // while sections 1862238SN/A } 1872472SN/A 1882976Sgblack@eecs.umich.edu ElfObject * result = new ElfObject(fname, fd, len, data, arch, opSys); 1892976Sgblack@eecs.umich.edu 1902976Sgblack@eecs.umich.edu //The number of headers in the file 1912976Sgblack@eecs.umich.edu result->_programHeaderCount = ehdr.e_phnum; 1922976Sgblack@eecs.umich.edu //Record the size of each entry 1932976Sgblack@eecs.umich.edu result->_programHeaderSize = ehdr.e_phentsize; 1942976Sgblack@eecs.umich.edu if(result->_programHeaderCount) //If there is a program header table 1952976Sgblack@eecs.umich.edu { 1962976Sgblack@eecs.umich.edu //Figure out the virtual address of the header table in the 1972976Sgblack@eecs.umich.edu //final memory image. We use the program headers themselves 1982976Sgblack@eecs.umich.edu //to translate from a file offset to the address in the image. 1992976Sgblack@eecs.umich.edu GElf_Phdr phdr; 2002976Sgblack@eecs.umich.edu uint64_t e_phoff = ehdr.e_phoff; 2012976Sgblack@eecs.umich.edu result->_programHeaderTable = 0; 2022976Sgblack@eecs.umich.edu for(int hdrnum = 0; hdrnum < result->_programHeaderCount; hdrnum++) 2032976Sgblack@eecs.umich.edu { 2042976Sgblack@eecs.umich.edu gelf_getphdr(elf, hdrnum, &phdr); 2052976Sgblack@eecs.umich.edu //Check if we've found the segment with the headers in it 2062976Sgblack@eecs.umich.edu if(phdr.p_offset <= e_phoff && 2072976Sgblack@eecs.umich.edu phdr.p_offset + phdr.p_filesz > e_phoff) 2082976Sgblack@eecs.umich.edu { 2095143Sgblack@eecs.umich.edu result->_programHeaderTable = phdr.p_paddr + e_phoff; 2102976Sgblack@eecs.umich.edu break; 2112976Sgblack@eecs.umich.edu } 2122976Sgblack@eecs.umich.edu } 2132976Sgblack@eecs.umich.edu } 2142976Sgblack@eecs.umich.edu else 2152976Sgblack@eecs.umich.edu result->_programHeaderTable = 0; 2162976Sgblack@eecs.umich.edu 2172976Sgblack@eecs.umich.edu 2182238SN/A elf_end(elf); 2192976Sgblack@eecs.umich.edu return result; 22012SN/A } 22112SN/A} 22212SN/A 22312SN/A 22412SN/AElfObject::ElfObject(const string &_filename, int _fd, 225360SN/A size_t _len, uint8_t *_data, 226360SN/A Arch _arch, OpSys _opSys) 227360SN/A : ObjectFile(_filename, _fd, _len, _data, _arch, _opSys) 228443SN/A 22912SN/A{ 230443SN/A Elf *elf; 231443SN/A GElf_Ehdr ehdr; 23212SN/A 233468SN/A // check that header matches library version 2341708SN/A if (elf_version(EV_CURRENT) == EV_NONE) 2351708SN/A panic("wrong elf version number!"); 23612SN/A 237468SN/A // get a pointer to elf structure 238443SN/A elf = elf_memory((char*)fileData,len); 239468SN/A // will only fail if fd is invalid 240443SN/A assert(elf != NULL); 24112SN/A 242468SN/A // Check that we actually have a elf file 243468SN/A if (gelf_getehdr(elf, &ehdr) ==0) { 244443SN/A panic("Not ELF, shouldn't be here"); 24512SN/A } 24612SN/A 247468SN/A entry = ehdr.e_entry; 24812SN/A 249468SN/A // initialize segment sizes to 0 in case they're not present 250468SN/A text.size = data.size = bss.size = 0; 251468SN/A 2525090Sgblack@eecs.umich.edu int secIdx = 1; 2535090Sgblack@eecs.umich.edu Elf_Scn *section; 2545090Sgblack@eecs.umich.edu GElf_Shdr shdr; 2555090Sgblack@eecs.umich.edu 2565090Sgblack@eecs.umich.edu // The first address of some important sections. 2575090Sgblack@eecs.umich.edu Addr textSecStart = 0; 2585090Sgblack@eecs.umich.edu Addr dataSecStart = 0; 2595090Sgblack@eecs.umich.edu Addr bssSecStart = 0; 2605090Sgblack@eecs.umich.edu 2615090Sgblack@eecs.umich.edu // Get the first section 2625090Sgblack@eecs.umich.edu section = elf_getscn(elf, secIdx); 2635090Sgblack@eecs.umich.edu 2645090Sgblack@eecs.umich.edu // Find the beginning of the most interesting sections. 2655090Sgblack@eecs.umich.edu while (section != NULL) { 2665090Sgblack@eecs.umich.edu gelf_getshdr(section, &shdr); 2675090Sgblack@eecs.umich.edu char * secName = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name); 2685090Sgblack@eecs.umich.edu 2698350Sgblack@eecs.umich.edu if (secName) { 2708350Sgblack@eecs.umich.edu if (!strcmp(".text", secName)) { 2718350Sgblack@eecs.umich.edu textSecStart = shdr.sh_addr; 2728350Sgblack@eecs.umich.edu } else if (!strcmp(".data", secName)) { 2738350Sgblack@eecs.umich.edu dataSecStart = shdr.sh_addr; 2748350Sgblack@eecs.umich.edu } else if (!strcmp(".bss", secName)) { 2758350Sgblack@eecs.umich.edu bssSecStart = shdr.sh_addr; 2768350Sgblack@eecs.umich.edu } 2778350Sgblack@eecs.umich.edu } else { 2788350Sgblack@eecs.umich.edu Elf_Error errorNum = (Elf_Error)elf_errno(); 2798350Sgblack@eecs.umich.edu if (errorNum != ELF_E_NONE) { 2808350Sgblack@eecs.umich.edu const char *errorMessage = elf_errmsg(errorNum); 2818350Sgblack@eecs.umich.edu fatal("Error from libelf: %s.\n", errorMessage); 2828350Sgblack@eecs.umich.edu } 2835090Sgblack@eecs.umich.edu } 2845090Sgblack@eecs.umich.edu 2855090Sgblack@eecs.umich.edu section = elf_getscn(elf, ++secIdx); 2865090Sgblack@eecs.umich.edu } 2875090Sgblack@eecs.umich.edu 2885090Sgblack@eecs.umich.edu // Go through all the segments in the program, record them, and scrape 2895090Sgblack@eecs.umich.edu // out information about the text, data, and bss areas needed by other 2905090Sgblack@eecs.umich.edu // code. 291468SN/A for (int i = 0; i < ehdr.e_phnum; ++i) { 292468SN/A GElf_Phdr phdr; 293468SN/A if (gelf_getphdr(elf, i, &phdr) == 0) { 2945090Sgblack@eecs.umich.edu panic("gelf_getphdr failed for segment %d.", i); 295468SN/A } 296468SN/A 297468SN/A // for now we don't care about non-loadable segments 298468SN/A if (!(phdr.p_type & PT_LOAD)) 299468SN/A continue; 300468SN/A 3015090Sgblack@eecs.umich.edu // Check to see if this segment contains the bss section. 3025143Sgblack@eecs.umich.edu if (phdr.p_paddr <= bssSecStart && 3035143Sgblack@eecs.umich.edu phdr.p_paddr + phdr.p_memsz > bssSecStart && 3045090Sgblack@eecs.umich.edu phdr.p_memsz - phdr.p_filesz > 0) { 3055143Sgblack@eecs.umich.edu bss.baseAddr = phdr.p_paddr + phdr.p_filesz; 3065090Sgblack@eecs.umich.edu bss.size = phdr.p_memsz - phdr.p_filesz; 3075090Sgblack@eecs.umich.edu bss.fileImage = NULL; 3085090Sgblack@eecs.umich.edu } 3095090Sgblack@eecs.umich.edu 3105090Sgblack@eecs.umich.edu // Check to see if this is the text or data segment 3115152Sgblack@eecs.umich.edu if (phdr.p_vaddr <= textSecStart && 3125152Sgblack@eecs.umich.edu phdr.p_vaddr + phdr.p_filesz > textSecStart) { 3135143Sgblack@eecs.umich.edu text.baseAddr = phdr.p_paddr; 314468SN/A text.size = phdr.p_filesz; 3152420SN/A text.fileImage = fileData + phdr.p_offset; 3165152Sgblack@eecs.umich.edu } else if (phdr.p_vaddr <= dataSecStart && 3175152Sgblack@eecs.umich.edu phdr.p_vaddr + phdr.p_filesz > dataSecStart) { 3185143Sgblack@eecs.umich.edu data.baseAddr = phdr.p_paddr; 319468SN/A data.size = phdr.p_filesz; 3202420SN/A data.fileImage = fileData + phdr.p_offset; 3212476SN/A } else { 3225759Shsul@eecs.umich.edu // If it's none of the above but is loadable, 3235759Shsul@eecs.umich.edu // load the filesize worth of data 3245090Sgblack@eecs.umich.edu Segment extra; 3255143Sgblack@eecs.umich.edu extra.baseAddr = phdr.p_paddr; 3265090Sgblack@eecs.umich.edu extra.size = phdr.p_filesz; 3275090Sgblack@eecs.umich.edu extra.fileImage = fileData + phdr.p_offset; 3285090Sgblack@eecs.umich.edu extraSegments.push_back(extra); 329468SN/A } 330468SN/A } 331468SN/A 332468SN/A // should have found at least one loadable segment 333468SN/A assert(text.size != 0); 334468SN/A 335468SN/A DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n", 336468SN/A text.baseAddr, text.size, data.baseAddr, data.size, 337468SN/A bss.baseAddr, bss.size); 338468SN/A 339443SN/A elf_end(elf); 340443SN/A 341468SN/A // We will actually read the sections when we need to load them 34212SN/A} 34312SN/A 34412SN/A 34512SN/Abool 3467581SAli.Saidi@arm.comElfObject::loadSomeSymbols(SymbolTable *symtab, int binding, Addr mask) 34712SN/A{ 348443SN/A Elf *elf; 349766SN/A int sec_idx = 1; // there is a 0 but it is nothing, go figure 350443SN/A Elf_Scn *section; 351443SN/A GElf_Shdr shdr; 352443SN/A Elf_Data *data; 353443SN/A int count, ii; 354443SN/A bool found = false; 355443SN/A GElf_Sym sym; 356443SN/A 357443SN/A if (!symtab) 358443SN/A return false; 359443SN/A 360468SN/A // check that header matches library version 3611708SN/A if (elf_version(EV_CURRENT) == EV_NONE) 3621708SN/A panic("wrong elf version number!"); 363443SN/A 364468SN/A // get a pointer to elf structure 365443SN/A elf = elf_memory((char*)fileData,len); 366443SN/A 367443SN/A assert(elf != NULL); 368443SN/A 369468SN/A // Get the first section 370454SN/A section = elf_getscn(elf, sec_idx); 371443SN/A 372468SN/A // While there are no more sections 373468SN/A while (section != NULL) { 374443SN/A gelf_getshdr(section, &shdr); 375443SN/A 376468SN/A if (shdr.sh_type == SHT_SYMTAB) { 377443SN/A found = true; 378443SN/A data = elf_getdata(section, NULL); 379443SN/A count = shdr.sh_size / shdr.sh_entsize; 380443SN/A DPRINTF(Loader, "Found Symbol Table, %d symbols present\n", count); 381443SN/A 382468SN/A // loop through all the symbols, only loading global ones 383468SN/A for (ii = 0; ii < count; ++ii) { 384443SN/A gelf_getsym(data, ii, &sym); 385836SN/A if (GELF_ST_BIND(sym.st_info) == binding) { 3867589SAli.Saidi@arm.com char *sym_name = elf_strptr(elf, shdr.sh_link, sym.st_name); 3877589SAli.Saidi@arm.com if (sym_name && sym_name[0] != '$') { 3887589SAli.Saidi@arm.com DPRINTF(Loader, "Symbol: %-40s value %#x\n", 3897589SAli.Saidi@arm.com sym_name, sym.st_value); 3907589SAli.Saidi@arm.com symtab->insert(sym.st_value & mask, sym_name); 3917589SAli.Saidi@arm.com } 392443SN/A } 393443SN/A } 394443SN/A } 395454SN/A ++sec_idx; 396454SN/A section = elf_getscn(elf, sec_idx); 397443SN/A } 398443SN/A 399443SN/A elf_end(elf); 400443SN/A 401443SN/A return found; 40212SN/A} 40312SN/A 40412SN/Abool 4053812Ssaidi@eecs.umich.eduElfObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask) 406468SN/A{ 4077581SAli.Saidi@arm.com return loadSomeSymbols(symtab, STB_GLOBAL, addrMask); 408468SN/A} 409468SN/A 410468SN/Abool 4113812Ssaidi@eecs.umich.eduElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask) 41212SN/A{ 4137581SAli.Saidi@arm.com return loadSomeSymbols(symtab, STB_LOCAL, addrMask); 41412SN/A} 4153917Ssaidi@eecs.umich.edu 4165090Sgblack@eecs.umich.edubool 4178706Sandreas.hansson@arm.comElfObject::loadSections(PortProxy* memProxy, Addr addrMask) 4185090Sgblack@eecs.umich.edu{ 4198706Sandreas.hansson@arm.com if (!ObjectFile::loadSections(memProxy, addrMask)) 4205090Sgblack@eecs.umich.edu return false; 4215090Sgblack@eecs.umich.edu 4225090Sgblack@eecs.umich.edu vector<Segment>::iterator extraIt; 4235090Sgblack@eecs.umich.edu for (extraIt = extraSegments.begin(); 4245090Sgblack@eecs.umich.edu extraIt != extraSegments.end(); extraIt++) { 4258706Sandreas.hansson@arm.com if (!loadSection(&(*extraIt), memProxy, addrMask)) { 4265090Sgblack@eecs.umich.edu return false; 4275090Sgblack@eecs.umich.edu } 4285090Sgblack@eecs.umich.edu } 4295090Sgblack@eecs.umich.edu return true; 4305090Sgblack@eecs.umich.edu} 4315090Sgblack@eecs.umich.edu 4325070Ssaidi@eecs.umich.eduvoid 4335070Ssaidi@eecs.umich.eduElfObject::getSections() 4343917Ssaidi@eecs.umich.edu{ 4353917Ssaidi@eecs.umich.edu Elf *elf; 4363917Ssaidi@eecs.umich.edu int sec_idx = 1; // there is a 0 but it is nothing, go figure 4373917Ssaidi@eecs.umich.edu Elf_Scn *section; 4383917Ssaidi@eecs.umich.edu GElf_Shdr shdr; 4393917Ssaidi@eecs.umich.edu 4403917Ssaidi@eecs.umich.edu GElf_Ehdr ehdr; 4413917Ssaidi@eecs.umich.edu 4425070Ssaidi@eecs.umich.edu assert(!sectionNames.size()); 4435070Ssaidi@eecs.umich.edu 4443917Ssaidi@eecs.umich.edu // check that header matches library version 4453917Ssaidi@eecs.umich.edu if (elf_version(EV_CURRENT) == EV_NONE) 4463917Ssaidi@eecs.umich.edu panic("wrong elf version number!"); 4473917Ssaidi@eecs.umich.edu 4483917Ssaidi@eecs.umich.edu // get a pointer to elf structure 4493917Ssaidi@eecs.umich.edu elf = elf_memory((char*)fileData,len); 4503917Ssaidi@eecs.umich.edu assert(elf != NULL); 4513917Ssaidi@eecs.umich.edu 4523917Ssaidi@eecs.umich.edu // Check that we actually have a elf file 4533917Ssaidi@eecs.umich.edu if (gelf_getehdr(elf, &ehdr) ==0) { 4543917Ssaidi@eecs.umich.edu panic("Not ELF, shouldn't be here"); 4553917Ssaidi@eecs.umich.edu } 4563917Ssaidi@eecs.umich.edu 4573917Ssaidi@eecs.umich.edu // Get the first section 4583917Ssaidi@eecs.umich.edu section = elf_getscn(elf, sec_idx); 4593917Ssaidi@eecs.umich.edu 4603917Ssaidi@eecs.umich.edu // While there are no more sections 4613917Ssaidi@eecs.umich.edu while (section != NULL) { 4623917Ssaidi@eecs.umich.edu gelf_getshdr(section, &shdr); 4635070Ssaidi@eecs.umich.edu sectionNames.insert(elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name)); 4643917Ssaidi@eecs.umich.edu section = elf_getscn(elf, ++sec_idx); 4653917Ssaidi@eecs.umich.edu } // while sections 4663917Ssaidi@eecs.umich.edu} 4673917Ssaidi@eecs.umich.edu 4685070Ssaidi@eecs.umich.edubool 4695070Ssaidi@eecs.umich.eduElfObject::sectionExists(string sec) 4705070Ssaidi@eecs.umich.edu{ 4715070Ssaidi@eecs.umich.edu if (!sectionNames.size()) 4725070Ssaidi@eecs.umich.edu getSections(); 4735070Ssaidi@eecs.umich.edu return sectionNames.find(sec) != sectionNames.end(); 4745070Ssaidi@eecs.umich.edu} 4753917Ssaidi@eecs.umich.edu 4765070Ssaidi@eecs.umich.edu 477