ltrace-elf.c revision 9120e5f4dbfef8f0354df0876ca0e3af3c6ac179
1#include "config.h" 2 3#include <endian.h> 4#include <errno.h> 5#include <error.h> 6#include <fcntl.h> 7#include <gelf.h> 8#include <inttypes.h> 9#include <stdint.h> 10#include <stdlib.h> 11#include <string.h> 12#include <unistd.h> 13#include <assert.h> 14 15#include "common.h" 16 17void do_close_elf(struct ltelf *lte); 18void add_library_symbol(GElf_Addr addr, const char *name, 19 struct library_symbol **library_symbolspp, 20 enum toplt type_of_plt, int is_weak); 21int in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym); 22static GElf_Addr opd2addr(struct ltelf *ltc, GElf_Addr addr); 23 24struct library_symbol *library_symbols = NULL; 25struct ltelf main_lte; 26 27#ifdef PLT_REINITALISATION_BP 28extern char *PLTs_initialized_by_here; 29#endif 30 31#ifndef DT_PPC_GOT 32# define DT_PPC_GOT (DT_LOPROC + 0) 33#endif 34 35#define PPC_PLT_STUB_SIZE 16 36 37static Elf_Data *loaddata(Elf_Scn *scn, GElf_Shdr *shdr) 38{ 39 Elf_Data *data = elf_getdata(scn, NULL); 40 if (data == NULL || elf_getdata(scn, data) != NULL 41 || data->d_off || data->d_size != shdr->sh_size) 42 return NULL; 43 return data; 44} 45 46static int inside(GElf_Addr addr, GElf_Shdr *shdr) 47{ 48 return addr >= shdr->sh_addr 49 && addr < shdr->sh_addr + shdr->sh_size; 50} 51 52static int maybe_pick_section(GElf_Addr addr, 53 Elf_Scn *in_sec, GElf_Shdr *in_shdr, 54 Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr) 55{ 56 if (inside (addr, in_shdr)) { 57 *tgt_sec = in_sec; 58 *tgt_shdr = *in_shdr; 59 return 1; 60 } 61 return 0; 62} 63 64static int get_section_covering(struct ltelf *lte, GElf_Addr addr, 65 Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr) 66{ 67 int i; 68 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 69 Elf_Scn *scn; 70 GElf_Shdr shdr; 71 72 scn = elf_getscn(lte->elf, i); 73 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) { 74 debug(1, "Couldn't read section or header."); 75 return 0; 76 } 77 78 if (maybe_pick_section(addr, scn, &shdr, tgt_sec, tgt_shdr)) 79 return 1; 80 } 81 82 return 0; 83} 84 85static GElf_Addr read32be(Elf_Data *data, size_t offset) 86{ 87 if (data->d_size < offset + 4) { 88 debug(1, "Not enough data to read 32bit value at offset %zd.", 89 offset); 90 return 0; 91 } 92 93 unsigned char const *buf = data->d_buf + offset; 94 return ((Elf32_Word)buf[0] << 24) 95 | ((Elf32_Word)buf[1] << 16) 96 | ((Elf32_Word)buf[2] << 8) 97 | ((Elf32_Word)buf[3]); 98} 99 100static GElf_Addr get_glink_vma(struct ltelf *lte, GElf_Addr ppcgot, 101 Elf_Data *plt_data) 102{ 103 Elf_Scn *ppcgot_sec = NULL; 104 GElf_Shdr ppcgot_shdr; 105 if (ppcgot != 0 106 && !get_section_covering(lte, ppcgot, &ppcgot_sec, &ppcgot_shdr)) 107 // xxx should be the log out 108 fprintf(stderr, 109 "DT_PPC_GOT=%#" PRIx64 ", but no such section found.\n", 110 ppcgot); 111 112 if (ppcgot_sec != NULL) { 113 Elf_Data *data = loaddata(ppcgot_sec, &ppcgot_shdr); 114 if (data == NULL 115 || data->d_size < 8 ) 116 debug(1, "Couldn't read GOT data."); 117 else { 118 // where PPCGOT begins in .got 119 size_t offset = ppcgot - ppcgot_shdr.sh_addr; 120 GElf_Addr glink_vma = read32be(data, offset + 4); 121 if (glink_vma != 0) { 122 debug(1, "PPC GOT glink_vma address: %#" PRIx64, 123 glink_vma); 124 return glink_vma; 125 } 126 } 127 } 128 129 if (plt_data != NULL) { 130 GElf_Addr glink_vma = read32be(plt_data, 0); 131 debug(1, ".plt glink_vma address: %#" PRIx64, glink_vma); 132 return glink_vma; 133 } 134 135 return 0; 136} 137 138int 139open_elf(struct ltelf *lte, const char *filename) 140{ 141 lte->fd = open(filename, O_RDONLY); 142 if (lte->fd == -1) 143 return 1; 144 145 elf_version(EV_CURRENT); 146 147#ifdef HAVE_ELF_C_READ_MMAP 148 lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL); 149#else 150 lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL); 151#endif 152 153 if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF) 154 error(EXIT_FAILURE, 0, "Can't open ELF file \"%s\"", filename); 155 156 if (gelf_getehdr(lte->elf, <e->ehdr) == NULL) 157 error(EXIT_FAILURE, 0, "Can't read ELF header of \"%s\"", 158 filename); 159 160 if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN) 161 error(EXIT_FAILURE, 0, 162 "\"%s\" is not an ELF executable nor shared library", 163 filename); 164 165 if ((lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS 166 || lte->ehdr.e_machine != LT_ELF_MACHINE) 167#ifdef LT_ELF_MACHINE2 168 && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2 169 || lte->ehdr.e_machine != LT_ELF_MACHINE2) 170#endif 171#ifdef LT_ELF_MACHINE3 172 && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3 173 || lte->ehdr.e_machine != LT_ELF_MACHINE3) 174#endif 175 ) 176 error(EXIT_FAILURE, 0, 177 "\"%s\" is ELF from incompatible architecture", filename); 178 179 return 0; 180} 181 182int 183do_init_elf(struct ltelf *lte, const char *filename) { 184 int i; 185 GElf_Addr relplt_addr = 0; 186 size_t relplt_size = 0; 187 188 debug(DEBUG_FUNCTION, "do_init_elf(filename=%s)", filename); 189 debug(1, "Reading ELF from %s...", filename); 190 191 if (open_elf(lte, filename) < 0) 192 return -1; 193 194 Elf_Data *plt_data = NULL; 195 GElf_Addr ppcgot = 0; 196 197 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 198 Elf_Scn *scn; 199 GElf_Shdr shdr; 200 const char *name; 201 202 scn = elf_getscn(lte->elf, i); 203 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 204 error(EXIT_FAILURE, 0, 205 "Couldn't get section header from \"%s\"", 206 filename); 207 208 name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name); 209 if (name == NULL) 210 error(EXIT_FAILURE, 0, 211 "Couldn't get section header from \"%s\"", 212 filename); 213 214 if (shdr.sh_type == SHT_SYMTAB) { 215 Elf_Data *data; 216 217 lte->symtab = elf_getdata(scn, NULL); 218 lte->symtab_count = shdr.sh_size / shdr.sh_entsize; 219 if ((lte->symtab == NULL 220 || elf_getdata(scn, lte->symtab) != NULL) 221 && opt_x != NULL) 222 error(EXIT_FAILURE, 0, 223 "Couldn't get .symtab data from \"%s\"", 224 filename); 225 226 scn = elf_getscn(lte->elf, shdr.sh_link); 227 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 228 error(EXIT_FAILURE, 0, 229 "Couldn't get section header from \"%s\"", 230 filename); 231 232 data = elf_getdata(scn, NULL); 233 if (data == NULL || elf_getdata(scn, data) != NULL 234 || shdr.sh_size != data->d_size || data->d_off) 235 error(EXIT_FAILURE, 0, 236 "Couldn't get .strtab data from \"%s\"", 237 filename); 238 239 lte->strtab = data->d_buf; 240 } else if (shdr.sh_type == SHT_DYNSYM) { 241 Elf_Data *data; 242 243 lte->dynsym = elf_getdata(scn, NULL); 244 lte->dynsym_count = shdr.sh_size / shdr.sh_entsize; 245 if (lte->dynsym == NULL 246 || elf_getdata(scn, lte->dynsym) != NULL) 247 error(EXIT_FAILURE, 0, 248 "Couldn't get .dynsym data from \"%s\"", 249 filename); 250 251 scn = elf_getscn(lte->elf, shdr.sh_link); 252 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 253 error(EXIT_FAILURE, 0, 254 "Couldn't get section header from \"%s\"", 255 filename); 256 257 data = elf_getdata(scn, NULL); 258 if (data == NULL || elf_getdata(scn, data) != NULL 259 || shdr.sh_size != data->d_size || data->d_off) 260 error(EXIT_FAILURE, 0, 261 "Couldn't get .dynstr data from \"%s\"", 262 filename); 263 264 lte->dynstr = data->d_buf; 265 } else if (shdr.sh_type == SHT_DYNAMIC) { 266 Elf_Data *data; 267 size_t j; 268 269 lte->dyn_addr = shdr.sh_addr; 270 lte->dyn_sz = shdr.sh_size; 271 272 data = elf_getdata(scn, NULL); 273 if (data == NULL || elf_getdata(scn, data) != NULL) 274 error(EXIT_FAILURE, 0, 275 "Couldn't get .dynamic data from \"%s\"", 276 filename); 277 278 for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { 279 GElf_Dyn dyn; 280 281 if (gelf_getdyn(data, j, &dyn) == NULL) 282 error(EXIT_FAILURE, 0, 283 "Couldn't get .dynamic data from \"%s\"", 284 filename); 285#ifdef __mips__ 286/** 287 MIPS ABI Supplement: 288 289 DT_PLTGOT This member holds the address of the .got section. 290 291 DT_MIPS_SYMTABNO This member holds the number of entries in the 292 .dynsym section. 293 294 DT_MIPS_LOCAL_GOTNO This member holds the number of local global 295 offset table entries. 296 297 DT_MIPS_GOTSYM This member holds the index of the first dyamic 298 symbol table entry that corresponds to an entry in the gobal offset 299 table. 300 301 */ 302 if(dyn.d_tag==DT_PLTGOT){ 303 lte->pltgot_addr=dyn.d_un.d_ptr; 304 } 305 if(dyn.d_tag==DT_MIPS_LOCAL_GOTNO){ 306 lte->mips_local_gotno=dyn.d_un.d_val; 307 } 308 if(dyn.d_tag==DT_MIPS_GOTSYM){ 309 lte->mips_gotsym=dyn.d_un.d_val; 310 } 311#endif // __mips__ 312 if (dyn.d_tag == DT_JMPREL) 313 relplt_addr = dyn.d_un.d_ptr; 314 else if (dyn.d_tag == DT_PLTRELSZ) 315 relplt_size = dyn.d_un.d_val; 316 else if (dyn.d_tag == DT_PPC_GOT) { 317 ppcgot = dyn.d_un.d_val; 318 debug(1, "ppcgot %#" PRIx64, ppcgot); 319 } 320 } 321 } else if (shdr.sh_type == SHT_HASH) { 322 Elf_Data *data; 323 size_t j; 324 325 lte->hash_type = SHT_HASH; 326 327 data = elf_getdata(scn, NULL); 328 if (data == NULL || elf_getdata(scn, data) != NULL 329 || data->d_off || data->d_size != shdr.sh_size) 330 error(EXIT_FAILURE, 0, 331 "Couldn't get .hash data from \"%s\"", 332 filename); 333 334 if (shdr.sh_entsize == 4) { 335 /* Standard conforming ELF. */ 336 if (data->d_type != ELF_T_WORD) 337 error(EXIT_FAILURE, 0, 338 "Couldn't get .hash data from \"%s\"", 339 filename); 340 lte->hash = (Elf32_Word *) data->d_buf; 341 } else if (shdr.sh_entsize == 8) { 342 /* Alpha or s390x. */ 343 Elf32_Word *dst, *src; 344 size_t hash_count = data->d_size / 8; 345 346 lte->hash = (Elf32_Word *) 347 malloc(hash_count * sizeof(Elf32_Word)); 348 if (lte->hash == NULL) 349 error(EXIT_FAILURE, 0, 350 "Couldn't convert .hash section from \"%s\"", 351 filename); 352 lte->lte_flags |= LTE_HASH_MALLOCED; 353 dst = lte->hash; 354 src = (Elf32_Word *) data->d_buf; 355 if ((data->d_type == ELF_T_WORD 356 && __BYTE_ORDER == __BIG_ENDIAN) 357 || (data->d_type == ELF_T_XWORD 358 && lte->ehdr.e_ident[EI_DATA] == 359 ELFDATA2MSB)) 360 ++src; 361 for (j = 0; j < hash_count; ++j, src += 2) 362 *dst++ = *src; 363 } else 364 error(EXIT_FAILURE, 0, 365 "Unknown .hash sh_entsize in \"%s\"", 366 filename); 367 } else if (shdr.sh_type == SHT_GNU_HASH 368 && lte->hash == NULL) { 369 Elf_Data *data; 370 371 lte->hash_type = SHT_GNU_HASH; 372 373 if (shdr.sh_entsize != 0 374 && shdr.sh_entsize != 4) { 375 error(EXIT_FAILURE, 0, 376 ".gnu.hash sh_entsize in \"%s\" " 377 "should be 4, but is %#" PRIx64, 378 filename, shdr.sh_entsize); 379 } 380 381 data = loaddata(scn, &shdr); 382 if (data == NULL) 383 error(EXIT_FAILURE, 0, 384 "Couldn't get .gnu.hash data from \"%s\"", 385 filename); 386 387 lte->hash = (Elf32_Word *) data->d_buf; 388 } else if (shdr.sh_type == SHT_PROGBITS 389 || shdr.sh_type == SHT_NOBITS) { 390 if (strcmp(name, ".plt") == 0) { 391 lte->plt_addr = shdr.sh_addr; 392 lte->plt_size = shdr.sh_size; 393 if (shdr.sh_flags & SHF_EXECINSTR) { 394 lte->lte_flags |= LTE_PLT_EXECUTABLE; 395 } 396 if (lte->ehdr.e_machine == EM_PPC) { 397 plt_data = loaddata(scn, &shdr); 398 if (plt_data == NULL) 399 fprintf(stderr, 400 "Can't load .plt data\n"); 401 } 402 } 403#ifdef ARCH_SUPPORTS_OPD 404 else if (strcmp(name, ".opd") == 0) { 405 lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr; 406 lte->opd_size = shdr.sh_size; 407 lte->opd = elf_rawdata(scn, NULL); 408 } 409#endif 410 } 411 } 412 413 if (lte->dynsym == NULL || lte->dynstr == NULL) 414 error(EXIT_FAILURE, 0, 415 "Couldn't find .dynsym or .dynstr in \"%s\"", filename); 416 417 if (!relplt_addr || !lte->plt_addr) { 418 debug(1, "%s has no PLT relocations", filename); 419 lte->relplt = NULL; 420 lte->relplt_count = 0; 421 } else if (relplt_size == 0) { 422 debug(1, "%s has unknown PLT size", filename); 423 lte->relplt = NULL; 424 lte->relplt_count = 0; 425 } else { 426 if (lte->ehdr.e_machine == EM_PPC) { 427 GElf_Addr glink_vma 428 = get_glink_vma(lte, ppcgot, plt_data); 429 430 assert (relplt_size % 12 == 0); 431 size_t count = relplt_size / 12; // size of RELA entry 432 lte->plt_stub_vma = glink_vma 433 - (GElf_Addr)count * PPC_PLT_STUB_SIZE; 434 debug(1, "stub_vma is %#" PRIx64, lte->plt_stub_vma); 435 } 436 437 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 438 Elf_Scn *scn; 439 GElf_Shdr shdr; 440 441 scn = elf_getscn(lte->elf, i); 442 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 443 error(EXIT_FAILURE, 0, 444 "Couldn't get section header from \"%s\"", 445 filename); 446 if (shdr.sh_addr == relplt_addr 447 && shdr.sh_size == relplt_size) { 448 lte->relplt = elf_getdata(scn, NULL); 449 lte->relplt_count = 450 shdr.sh_size / shdr.sh_entsize; 451 if (lte->relplt == NULL 452 || elf_getdata(scn, lte->relplt) != NULL) 453 error(EXIT_FAILURE, 0, 454 "Couldn't get .rel*.plt data from \"%s\"", 455 filename); 456 break; 457 } 458 } 459 460 if (i == lte->ehdr.e_shnum) 461 error(EXIT_FAILURE, 0, 462 "Couldn't find .rel*.plt section in \"%s\"", 463 filename); 464 465 debug(1, "%s %zd PLT relocations", filename, lte->relplt_count); 466 } 467 return 0; 468} 469 470void 471do_close_elf(struct ltelf *lte) { 472 debug(DEBUG_FUNCTION, "do_close_elf()"); 473 if (lte->lte_flags & LTE_HASH_MALLOCED) 474 free((char *)lte->hash); 475 elf_end(lte->elf); 476 close(lte->fd); 477} 478 479static struct library_symbol * 480create_library_symbol(const char * name, GElf_Addr addr) 481{ 482 size_t namel = strlen(name) + 1; 483 struct library_symbol * sym = calloc(sizeof(*sym) + namel, 1); 484 if (sym == NULL) { 485 perror("create_library_symbol"); 486 return NULL; 487 } 488 sym->name = (char *)(sym + 1); 489 memcpy(sym->name, name, namel); 490 sym->enter_addr = (void *)(uintptr_t) addr; 491 return sym; 492} 493 494void 495add_library_symbol(GElf_Addr addr, const char *name, 496 struct library_symbol **library_symbolspp, 497 enum toplt type_of_plt, int is_weak) 498{ 499 struct library_symbol *s; 500 501 debug(DEBUG_FUNCTION, "add_library_symbol()"); 502 503 s = create_library_symbol(name, addr); 504 if (s == NULL) 505 error(EXIT_FAILURE, errno, "add_library_symbol failed"); 506 507 s->needs_init = 1; 508 s->is_weak = is_weak; 509 s->plt_type = type_of_plt; 510 511 s->next = *library_symbolspp; 512 *library_symbolspp = s; 513 514 debug(2, "addr: %p, symbol: \"%s\"", (void *)(uintptr_t) addr, name); 515} 516 517struct library_symbol * 518clone_library_symbol(struct library_symbol * sym) 519{ 520 struct library_symbol * copy 521 = create_library_symbol(sym->name, 522 (GElf_Addr)(uintptr_t)sym->enter_addr); 523 if (copy == NULL) 524 return NULL; 525 526 copy->needs_init = sym->needs_init; 527 copy->is_weak = sym->is_weak; 528 copy->plt_type = sym->plt_type; 529 530 return copy; 531} 532 533void 534destroy_library_symbol(struct library_symbol * sym) 535{ 536 free(sym); 537} 538 539void 540destroy_library_symbol_chain(struct library_symbol * sym) 541{ 542 while (sym != NULL) { 543 struct library_symbol * next = sym->next; 544 destroy_library_symbol(sym); 545 sym = next; 546 } 547} 548 549/* stolen from elfutils-0.123 */ 550static unsigned long 551private_elf_gnu_hash(const char *name) { 552 unsigned long h = 5381; 553 const unsigned char *string = (const unsigned char *)name; 554 unsigned char c; 555 for (c = *string; c; c = *++string) 556 h = h * 33 + c; 557 return h & 0xffffffff; 558} 559 560static int 561symbol_matches(struct ltelf *lte, size_t lte_i, GElf_Sym *sym, 562 size_t symidx, const char *name) 563{ 564 GElf_Sym tmp_sym; 565 GElf_Sym *tmp; 566 567 tmp = (sym) ? (sym) : (&tmp_sym); 568 569 if (gelf_getsym(lte[lte_i].dynsym, symidx, tmp) == NULL) 570 error(EXIT_FAILURE, 0, "Couldn't get symbol from .dynsym"); 571 else { 572 tmp->st_value += lte[lte_i].base_addr; 573 debug(2, "symbol found: %s, %zd, %#" PRIx64, 574 name, lte_i, tmp->st_value); 575 } 576 return tmp->st_value != 0 577 && tmp->st_shndx != SHN_UNDEF 578 && strcmp(name, lte[lte_i].dynstr + tmp->st_name) == 0; 579} 580 581int 582in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym) { 583 size_t i; 584 unsigned long hash; 585 unsigned long gnu_hash; 586 587 if (!count) 588 return 1; 589 590#ifdef ELF_HASH_TAKES_SIGNED_CHAR 591 hash = elf_hash(name); 592#else 593 hash = elf_hash((const unsigned char *)name); 594#endif 595 gnu_hash = private_elf_gnu_hash(name); 596 597 for (i = 0; i < count; ++i) { 598 if (lte[i].hash == NULL) 599 continue; 600 601 if (lte[i].hash_type == SHT_GNU_HASH) { 602 Elf32_Word * hashbase = lte[i].hash; 603 Elf32_Word nbuckets = *hashbase++; 604 Elf32_Word symbias = *hashbase++; 605 Elf32_Word bitmask_nwords = *hashbase++; 606 Elf32_Word * buckets; 607 Elf32_Word * chain_zero; 608 Elf32_Word bucket; 609 610 // +1 for skipped `shift' 611 hashbase += lte[i].ehdr.e_ident[EI_CLASS] * bitmask_nwords + 1; 612 buckets = hashbase; 613 hashbase += nbuckets; 614 chain_zero = hashbase - symbias; 615 bucket = buckets[gnu_hash % nbuckets]; 616 617 if (bucket != 0) { 618 const Elf32_Word *hasharr = &chain_zero[bucket]; 619 do 620 if ((*hasharr & ~1u) == (gnu_hash & ~1u)) { 621 int symidx = hasharr - chain_zero; 622 if (symbol_matches(lte, i, 623 sym, symidx, 624 name)) 625 return 1; 626 } 627 while ((*hasharr++ & 1u) == 0); 628 } 629 } else { 630 Elf32_Word nbuckets, symndx; 631 Elf32_Word *buckets, *chain; 632 nbuckets = lte[i].hash[0]; 633 buckets = <e[i].hash[2]; 634 chain = <e[i].hash[2 + nbuckets]; 635 636 for (symndx = buckets[hash % nbuckets]; 637 symndx != STN_UNDEF; symndx = chain[symndx]) 638 if (symbol_matches(lte, i, sym, symndx, name)) 639 return 1; 640 } 641 } 642 return 0; 643} 644 645static GElf_Addr 646opd2addr(struct ltelf *lte, GElf_Addr addr) { 647#ifdef ARCH_SUPPORTS_OPD 648 unsigned long base, offset; 649 650 if (!lte->opd) 651 return addr; 652 653 base = (unsigned long)lte->opd->d_buf; 654 offset = (unsigned long)addr - (unsigned long)lte->opd_addr; 655 if (offset > lte->opd_size) 656 error(EXIT_FAILURE, 0, "static plt not in .opd"); 657 658 return *(GElf_Addr*)(base + offset); 659#else //!ARCH_SUPPORTS_OPD 660 return addr; 661#endif 662} 663 664struct library_symbol * 665read_elf(Process *proc) { 666 struct ltelf lte[MAX_LIBRARIES + 1]; 667 size_t i; 668 struct opt_x_t *xptr; 669 struct opt_x_t *opt_x_loc = opt_x; 670 struct library_symbol **lib_tail = NULL; 671 int exit_out = 0; 672 int count = 0; 673 674 debug(DEBUG_FUNCTION, "read_elf(file=%s)", proc->filename); 675 676 memset(lte, 0, sizeof(lte)); 677 library_symbols = NULL; 678 library_num = 0; 679 proc->libdl_hooked = 0; 680 681 if (do_init_elf(lte, proc->filename)) 682 return NULL; 683 684 memcpy(&main_lte, lte, sizeof(struct ltelf)); 685 686 if (opt_p && opt_p->pid > 0) { 687 linkmap_init(proc, lte); 688 proc->libdl_hooked = 1; 689 } 690 691 proc->e_machine = lte->ehdr.e_machine; 692 693 for (i = 0; i < library_num; ++i) { 694 if (do_init_elf(<e[i + 1], library[i])) 695 error(EXIT_FAILURE, errno, "Can't open \"%s\"", 696 library[i]); 697 } 698 699 if (!options.no_plt) { 700#ifdef __mips__ 701 // MIPS doesn't use the PLT and the GOT entries get changed 702 // on startup. 703 proc->need_to_reinitialize_breakpoints = 1; 704 for(i=lte->mips_gotsym; i<lte->dynsym_count;i++){ 705 GElf_Sym sym; 706 const char *name; 707 GElf_Addr addr = arch_plt_sym_val(lte, i, 0); 708 if (gelf_getsym(lte->dynsym, i, &sym) == NULL){ 709 error(EXIT_FAILURE, 0, 710 "Couldn't get relocation from \"%s\"", 711 proc->filename); 712 } 713 name=lte->dynstr+sym.st_name; 714 if(ELF64_ST_TYPE(sym.st_info) != STT_FUNC){ 715 debug(2,"sym %s not a function",name); 716 continue; 717 } 718 add_library_symbol(addr, name, &library_symbols, 0, 719 ELF64_ST_BIND(sym.st_info) != 0); 720 if (!lib_tail) 721 lib_tail = &(library_symbols->next); 722 } 723#else 724 for (i = 0; i < lte->relplt_count; ++i) { 725 GElf_Rel rel; 726 GElf_Rela rela; 727 GElf_Sym sym; 728 GElf_Addr addr; 729 void *ret; 730 const char *name; 731 732 if (lte->relplt->d_type == ELF_T_REL) { 733 ret = gelf_getrel(lte->relplt, i, &rel); 734 rela.r_offset = rel.r_offset; 735 rela.r_info = rel.r_info; 736 rela.r_addend = 0; 737 } else 738 ret = gelf_getrela(lte->relplt, i, &rela); 739 740 if (ret == NULL 741 || ELF64_R_SYM(rela.r_info) >= lte->dynsym_count 742 || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela.r_info), 743 &sym) == NULL) 744 error(EXIT_FAILURE, 0, 745 "Couldn't get relocation from \"%s\"", 746 proc->filename); 747 748#ifdef PLT_REINITALISATION_BP 749 if (!sym.st_value && PLTs_initialized_by_here) 750 proc->need_to_reinitialize_breakpoints = 1; 751#endif 752 753 name = lte->dynstr + sym.st_name; 754 count = library_num ? library_num+1 : 0; 755 756 if (in_load_libraries(name, lte, count, NULL)) { 757 enum toplt pltt; 758 if (sym.st_value == 0 && lte->plt_stub_vma != 0) { 759 pltt = LS_TOPLT_EXEC; 760 addr = lte->plt_stub_vma + PPC_PLT_STUB_SIZE * i; 761 } 762 else { 763 pltt = PLTS_ARE_EXECUTABLE(lte) 764 ? LS_TOPLT_EXEC : LS_TOPLT_POINT; 765 addr = arch_plt_sym_val(lte, i, &rela); 766 } 767 768 add_library_symbol(addr, name, &library_symbols, pltt, 769 ELF64_ST_BIND(sym.st_info) == STB_WEAK); 770 if (!lib_tail) 771 lib_tail = &(library_symbols->next); 772 } 773 } 774#endif // !__mips__ 775#ifdef PLT_REINITALISATION_BP 776 struct opt_x_t *main_cheat; 777 778 if (proc->need_to_reinitialize_breakpoints) { 779 /* Add "PLTs_initialized_by_here" to opt_x list, if not 780 already there. */ 781 main_cheat = (struct opt_x_t *)malloc(sizeof(struct opt_x_t)); 782 if (main_cheat == NULL) 783 error(EXIT_FAILURE, 0, "Couldn't allocate memory"); 784 main_cheat->next = opt_x_loc; 785 main_cheat->found = 0; 786 main_cheat->name = PLTs_initialized_by_here; 787 788 for (xptr = opt_x_loc; xptr; xptr = xptr->next) 789 if (strcmp(xptr->name, PLTs_initialized_by_here) == 0 790 && main_cheat) { 791 free(main_cheat); 792 main_cheat = NULL; 793 break; 794 } 795 if (main_cheat) 796 opt_x_loc = main_cheat; 797 } 798#endif 799 } else { 800 lib_tail = &library_symbols; 801 } 802 803 for (i = 0; i < lte->symtab_count; ++i) { 804 GElf_Sym sym; 805 GElf_Addr addr; 806 const char *name; 807 808 if (gelf_getsym(lte->symtab, i, &sym) == NULL) 809 error(EXIT_FAILURE, 0, 810 "Couldn't get symbol from \"%s\"", 811 proc->filename); 812 813 name = lte->strtab + sym.st_name; 814 addr = sym.st_value; 815 if (!addr) 816 continue; 817 818 for (xptr = opt_x_loc; xptr; xptr = xptr->next) 819 if (xptr->name && strcmp(xptr->name, name) == 0) { 820 /* FIXME: Should be able to use &library_symbols as above. But 821 when you do, none of the real library symbols cause breaks. */ 822 add_library_symbol(opd2addr(lte, addr), 823 name, lib_tail, LS_TOPLT_NONE, 0); 824 xptr->found = 1; 825 break; 826 } 827 } 828 829 unsigned found_count = 0; 830 831 for (xptr = opt_x_loc; xptr; xptr = xptr->next) { 832 if (xptr->found) 833 continue; 834 835 GElf_Sym sym; 836 GElf_Addr addr; 837 if (in_load_libraries(xptr->name, lte, library_num+1, &sym)) { 838 debug(2, "found symbol %s @ %#" PRIx64 ", adding it.", 839 xptr->name, sym.st_value); 840 addr = sym.st_value; 841 if (ELF32_ST_TYPE (sym.st_info) == STT_FUNC) { 842 add_library_symbol(addr, xptr->name, lib_tail, LS_TOPLT_NONE, 0); 843 xptr->found = 1; 844 found_count++; 845 } 846 } 847 if (found_count == opt_x_cnt){ 848 debug(2, "done, found everything: %d\n", found_count); 849 break; 850 } 851 } 852 853 for (xptr = opt_x_loc; xptr; xptr = xptr->next) 854 if ( ! xptr->found) { 855 char *badthing = "WARNING"; 856#ifdef PLT_REINITALISATION_BP 857 if (strcmp(xptr->name, PLTs_initialized_by_here) == 0) { 858 if (lte->ehdr.e_entry) { 859 add_library_symbol ( 860 opd2addr (lte, lte->ehdr.e_entry), 861 PLTs_initialized_by_here, 862 lib_tail, 1, 0); 863 fprintf (stderr, "WARNING: Using e_ent" 864 "ry from elf header (%p) for " 865 "address of \"%s\"\n", (void*) 866 (long) lte->ehdr.e_entry, 867 PLTs_initialized_by_here); 868 continue; 869 } 870 badthing = "ERROR"; 871 exit_out = 1; 872 } 873#endif 874 fprintf (stderr, 875 "%s: Couldn't find symbol \"%s\" in file \"%s\" assuming it will be loaded by libdl!" 876 "\n", badthing, xptr->name, proc->filename); 877 } 878 if (exit_out) { 879 exit (1); 880 } 881 882 for (i = 0; i < library_num + 1; ++i) 883 do_close_elf(<e[i]); 884 885 return library_symbols; 886} 887