| 420 | } |
| 421 | |
| 422 | static int |
| 423 | symtab_read(const struct buffer *in, struct parsed_elf *pelf, |
| 424 | struct xdr *xdr, int bit64) |
| 425 | { |
| 426 | Elf64_Ehdr *ehdr; |
| 427 | Elf64_Shdr *shdr; |
| 428 | Elf64_Half shnum; |
| 429 | Elf64_Xword i; |
| 430 | Elf64_Xword nsyms; |
| 431 | Elf64_Sym *sym; |
| 432 | struct buffer b; |
| 433 | |
| 434 | ehdr = &pelf->ehdr; |
| 435 | |
| 436 | shdr = NULL; |
| 437 | for (shnum = 0; shnum < ehdr->e_shnum; shnum++) { |
| 438 | if (pelf->shdr[shnum].sh_type != SHT_SYMTAB) |
| 439 | continue; |
| 440 | |
| 441 | if (shdr != NULL) { |
| 442 | ERROR("Multiple symbol sections found. %u and %u\n", |
| 443 | (unsigned int)(shdr - pelf->shdr), shnum); |
| 444 | return -1; |
| 445 | } |
| 446 | |
| 447 | shdr = &pelf->shdr[shnum]; |
| 448 | } |
| 449 | |
| 450 | if (shdr == NULL) { |
| 451 | ERROR("No symbol table found.\n"); |
| 452 | return -1; |
| 453 | } |
| 454 | |
| 455 | buffer_splice(&b, in, shdr->sh_offset, shdr->sh_size); |
| 456 | if (check_size(in, shdr->sh_offset, buffer_size(&b), "symtab")) |
| 457 | return -1; |
| 458 | |
| 459 | nsyms = shdr->sh_size / shdr->sh_entsize; |
| 460 | |
| 461 | pelf->syms = calloc(nsyms, sizeof(Elf64_Sym)); |
| 462 | |
| 463 | for (i = 0; i < nsyms; i++) { |
| 464 | sym = &pelf->syms[i]; |
| 465 | |
| 466 | if (bit64) { |
| 467 | sym->st_name = xdr->get32(&b); |
| 468 | sym->st_info = xdr->get8(&b); |
| 469 | sym->st_other = xdr->get8(&b); |
| 470 | sym->st_shndx = xdr->get16(&b); |
| 471 | sym->st_value = xdr->get64(&b); |
| 472 | sym->st_size = xdr->get64(&b); |
| 473 | } else { |
| 474 | sym->st_name = xdr->get32(&b); |
| 475 | sym->st_value = xdr->get32(&b); |
| 476 | sym->st_size = xdr->get32(&b); |
| 477 | sym->st_info = xdr->get8(&b); |
| 478 | sym->st_other = xdr->get8(&b); |
| 479 | sym->st_shndx = xdr->get16(&b); |
no test coverage detected