elf_object.cc revision 443
1/* 2 * Copyright (c) 2003 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <string> 30 31#include "base/loader/elf_object.hh" 32 33#include "mem/functional_mem/functional_memory.hh" 34#include "base/loader/symtab.hh" 35 36#include "base/trace.hh" // for DPRINTF 37 38 39using namespace std; 40 41ObjectFile * 42ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) 43{ 44 Elf *elf; 45 GElf_Ehdr ehdr; 46 47 48 /* check that header matches library version */ 49 assert(elf_version(EV_CURRENT) != EV_NONE); 50 51 /* get a pointer to elf structure */ 52 elf = elf_memory((char*)data,len); 53 /* will only fail if fd is invalid */ 54 assert(elf != NULL); 55 56 /* Check that we actually have a elf file */ 57 if(gelf_getehdr(elf, &ehdr) ==0) 58 { 59 DPRINTFR(Loader, "Not ELF\n"); 60 elf_end(elf); 61 return NULL; 62 } 63 else 64 { 65 if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) 66 panic("32 bit ELF Binary, Not Supported"); 67 if (ehdr.e_machine != EM_ALPHA) 68 panic("Non Alpha Binary, Not Supported"); 69 70 elf_end(elf); 71 72 return new ElfObject(fname, fd, len, data, 73 ObjectFile::Alpha, ObjectFile::Linux); 74 } 75} 76 77 78ElfObject::ElfObject(const string &_filename, int _fd, 79 size_t _len, uint8_t *_data, 80 Arch _arch, OpSys _opSys) 81 : ObjectFile(_filename, _fd, _len, _data, _arch, _opSys) 82 83{ 84 85 Elf *elf; 86 GElf_Ehdr ehdr; 87 88 /* check that header matches library version */ 89 assert(elf_version(EV_CURRENT) != EV_NONE); 90 91 /* get a pointer to elf structure */ 92 elf = elf_memory((char*)fileData,len); 93 /* will only fail if fd is invalid */ 94 assert(elf != NULL); 95 96 /* Check that we actually have a elf file */ 97 if(gelf_getehdr(elf, &ehdr) ==0) 98 { 99 panic("Not ELF, shouldn't be here"); 100 } 101 102 103 entry = ehdr.e_entry; 104 elf_end(elf); 105 106 /* We will actually read the sections when we need to load them*/ 107} 108 109 110bool 111ElfObject::loadSections(FunctionalMemory *mem, bool loadPhys) 112{ 113 Elf *elf; 114 int secidx = 1; /* there is a 0 but it is nothing, go figure*/ 115 Elf_Scn *section; 116 GElf_Shdr shdr; 117 GElf_Ehdr ehdr; 118 119 Addr address; 120 char *secname; 121 122 /* check that header matches library version */ 123 assert(elf_version(EV_CURRENT) != EV_NONE); 124 125 126 /* get a pointer to elf structure */ 127 elf = elf_memory((char*)fileData,len); 128 129 assert(elf != NULL); 130 131 /* Check that we actually have a elf file */ 132 if(gelf_getehdr(elf, &ehdr) ==0) 133 { 134 panic("Not ELF, shouldn't be here"); 135 } 136 137 138 139 /* Get the first section */ 140 section = elf_getscn(elf, secidx); 141 142 /* While there are no more sections */ 143 while (section != NULL) 144 { 145 gelf_getshdr(section, &shdr); 146 147 148 if (shdr.sh_flags & SHF_ALLOC) 149 { 150 /* we should load this */ 151 DPRINTF(Loader,"Name: %20s Address: 0x%016llx Size: 0x%08llx Offset: 0x%08llx Flags:0x%08llx %s\n", 152 elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name), shdr.sh_addr, 153 shdr.sh_size, shdr.sh_offset, shdr.sh_flags, shdr.sh_flags & SHF_ALLOC ? "ALLOC" : ""); 154 secname = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name); 155 if(secname) 156 { 157 if (strcmp(secname, ".text")==0) 158 { 159 text.baseAddr = shdr.sh_addr; 160 text.size = shdr.sh_size; 161 } 162 if (strcmp(secname, ".data")==0) 163 { 164 data.baseAddr = shdr.sh_addr; 165 data.size = shdr.sh_size; 166 } 167 if (strcmp(secname, ".bss")==0) 168 { 169 bss.baseAddr = shdr.sh_addr; 170 bss.size = shdr.sh_size; 171 } 172 } 173 if(shdr.sh_size != 0) 174 { 175 if (loadPhys) 176 { 177 address = shdr.sh_addr &= (ULL(1) << 40) - 1; 178 mem->prot_write(address, fileData + shdr.sh_offset, shdr.sh_size); 179 } 180 else 181 { 182 mem->prot_write(shdr.sh_addr, fileData + shdr.sh_offset, shdr.sh_size); 183 } 184 } 185 186 } 187 188 ++secidx; 189 section = elf_getscn(elf, secidx); 190 } 191 192 elf_end(elf); 193 194 return true; 195} 196 197 198bool 199ElfObject::loadGlobalSymbols(SymbolTable *symtab) 200{ 201 Elf *elf; 202 int secidx = 1; /* there is a 0 but it is nothing, go figure*/ 203 Elf_Scn *section; 204 GElf_Shdr shdr; 205 Elf_Data *data; 206 int count, ii; 207 bool found = false; 208 GElf_Sym sym; 209 210 if (!symtab) 211 return false; 212 213 /* check that header matches library version */ 214 assert(elf_version(EV_CURRENT) != EV_NONE); 215 216 /* get a pointer to elf structure */ 217 elf = elf_memory((char*)fileData,len); 218 219 assert(elf != NULL); 220 221 222 /* Get the first section */ 223 section = elf_getscn(elf, secidx); 224 225 /* While there are no more sections */ 226 while (section != NULL) 227 { 228 gelf_getshdr(section, &shdr); 229 230 231 if(shdr.sh_type == SHT_SYMTAB) 232 { 233 found = true; 234 data = elf_getdata(section, NULL); 235 count = shdr.sh_size / shdr.sh_entsize; 236 DPRINTF(Loader, "Found Symbol Table, %d symbols present\n", count); 237 238 /* loop through all the symbols, only loading global ones*/ 239 for (ii = 0; ii < count; ++ii) 240 { 241 gelf_getsym(data, ii, &sym); 242 if (GELF_ST_BIND(sym.st_info) & STB_GLOBAL) 243 { 244 symtab->insert(sym.st_value, elf_strptr(elf, shdr.sh_link, sym.st_name)); 245 } 246 } 247 } 248 ++secidx; 249 section = elf_getscn(elf, secidx); 250 } 251 252 elf_end(elf); 253 254 return found; 255} 256 257bool 258ElfObject::loadLocalSymbols(SymbolTable *symtab) 259{ 260 261 Elf *elf; 262 int secidx = 1; /* there is a 0 but it is nothing, go figure*/ 263 Elf_Scn *section; 264 GElf_Shdr shdr; 265 Elf_Data *data; 266 int count, ii; 267 bool found = false; 268 GElf_Sym sym; 269 270 if (!symtab) 271 return false; 272 273 /* check that header matches library version */ 274 assert(elf_version(EV_CURRENT) != EV_NONE); 275 276 /* get a pointer to elf structure */ 277 elf = elf_memory((char*)fileData,len); 278 279 assert(elf != NULL); 280 281 282 /* Get the first section */ 283 section = elf_getscn(elf, secidx); 284 285 /* While there are no more sections */ 286 while (section != NULL) 287 { 288 gelf_getshdr(section, &shdr); 289 290 291 if(shdr.sh_type == SHT_SYMTAB) 292 { 293 found = true; 294 data = elf_getdata(section, NULL); 295 count = shdr.sh_size / shdr.sh_entsize; 296 DPRINTF(Loader, "Found Symbol Table, %d symbols present\n", count); 297 298 /* loop through all the symbols, only loading global ones*/ 299 for (ii = 0; ii < count; ++ii) 300 { 301 gelf_getsym(data, ii, &sym); 302 if (GELF_ST_BIND(sym.st_info) & STB_LOCAL) 303 { 304 symtab->insert(sym.st_value, elf_strptr(elf, shdr.sh_link, sym.st_name)); 305 } 306 } 307 } 308 ++secidx; 309 section = elf_getscn(elf, secidx); 310 } 311 312 elf_end(elf); 313 314 return found; 315} 316