1 /* Copyright (C) 2021 Free Software Foundation, Inc. 2 Contributed by Oracle. 3 4 This file is part of GNU Binutils. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. */ 20 21 #include "config.h" 22 #include <unistd.h> 23 24 #include "util.h" 25 #include "bfd.h" 26 #include "elf-bfd.h" 27 #include "Elf.h" 28 #include "Map.h" 29 #include "StringBuilder.h" 30 #include "DbeFile.h" 31 32 typedef uint32_t Elf32_Word; 33 typedef uint32_t Elf64_Word; 34 typedef uint32_t Elf32_Addr; 35 typedef uint64_t Elf64_Addr; 36 typedef uint64_t Elf64_Xword; 37 typedef int32_t Elf32_Sword; 38 typedef int64_t Elf64_Sxword; 39 typedef uint16_t Elf32_Half; 40 typedef uint16_t Elf64_Half; 41 42 // Ancillary entry 43 typedef struct 44 { 45 Elf32_Word a_tag; /* how to interpret value */ 46 union 47 { 48 Elf32_Word a_val; 49 Elf32_Addr a_ptr; 50 } a_un; 51 } Elf32_Ancillary; 52 53 struct S_Elf64_Ancillary 54 { 55 Elf64_Xword a_tag; /* how to interpret value */ 56 union 57 { 58 Elf64_Xword a_val; 59 Elf64_Addr a_ptr; 60 } a_un; 61 }; 62 63 /* Dynamic section entry. */ 64 typedef struct 65 { 66 Elf32_Sword d_tag; /* Dynamic entry type */ 67 68 union 69 { 70 Elf32_Word d_val; /* Integer value */ 71 Elf32_Addr d_ptr; /* Address value */ 72 } d_un; 73 } Elf32_Dyn; 74 75 struct S_Elf64_Dyn 76 { 77 Elf64_Sxword d_tag; /* Dynamic entry type */ 78 79 union 80 { 81 Elf64_Xword d_val; /* Integer value */ 82 Elf64_Addr d_ptr; /* Address value */ 83 } d_un; 84 }; 85 86 87 // Symbol table 88 typedef struct 89 { 90 Elf32_Word st_name; 91 Elf32_Addr st_value; 92 Elf32_Word st_size; 93 unsigned char st_info; /* bind, type: ELF_32_ST_... */ 94 unsigned char st_other; 95 Elf32_Half st_shndx; /* SHN_... */ 96 } Elf32_Sym; 97 98 typedef struct 99 { 100 Elf64_Word st_name; 101 unsigned char st_info; /* bind, type: ELF_64_ST_... */ 102 unsigned char st_other; 103 Elf64_Half st_shndx; /* SHN_... */ 104 Elf64_Addr st_value; 105 Elf64_Xword st_size; 106 } Elf64_Sym; 107 108 109 // Relocation 110 typedef struct 111 { 112 Elf32_Addr r_offset; 113 Elf32_Word r_info; /* sym, type: ELF32_R_... */ 114 } Elf32_Rel; 115 116 typedef struct 117 { 118 Elf32_Addr r_offset; 119 Elf32_Word r_info; /* sym, type: ELF32_R_... */ 120 Elf32_Sword r_addend; 121 } Elf32_Rela; 122 123 typedef struct 124 { 125 Elf64_Addr r_offset; 126 Elf64_Xword r_info; /* sym, type: ELF64_R_... */ 127 } Elf64_Rel; 128 129 typedef struct 130 { 131 Elf64_Addr r_offset; 132 Elf64_Xword r_info; /* sym, type: ELF64_R_... */ 133 Elf64_Sxword r_addend; 134 } Elf64_Rela; 135 136 int Elf::bfd_status = -1; 137 138 void 139 Elf::elf_init () 140 { 141 if (bfd_status == -1) 142 bfd_status = bfd_init (); 143 } 144 145 Elf::Elf (char *filename) : DbeMessages (), Data_window (filename) 146 { 147 ehdrp = NULL; 148 data = NULL; 149 ancillary_files = NULL; 150 elfSymbols = NULL; 151 gnu_debug_file = NULL; 152 dbeFile = NULL; 153 abfd = NULL; 154 if (bfd_status != BFD_INIT_MAGIC) 155 { 156 status = ELF_ERR_CANT_OPEN_FILE; 157 return; 158 } 159 abfd = bfd_openr (filename, NULL); 160 if (abfd == NULL) 161 { 162 status = ELF_ERR_CANT_OPEN_FILE; 163 return; 164 } 165 if (!bfd_check_format (abfd, bfd_object)) 166 { 167 bfd_close (abfd); 168 abfd = NULL; 169 status = ELF_ERR_CANT_OPEN_FILE; 170 return; 171 } 172 ehdrp = elf_getehdr (); 173 if (ehdrp == NULL) 174 { 175 bfd_close (abfd); 176 abfd = NULL; 177 status = ELF_ERR_BAD_ELF_FORMAT; 178 return; 179 } 180 elf_class = ehdrp->e_ident[EI_CLASS]; 181 elf_datatype = ehdrp->e_ident[EI_DATA]; 182 183 if (not_opened ()) 184 { 185 status = ELF_ERR_CANT_OPEN_FILE; 186 return; 187 } 188 status = ELF_ERR_NONE; 189 190 #if ARCH(SPARC) 191 need_swap_endian = is_Intel (); 192 #else 193 need_swap_endian = !is_Intel (); 194 #endif 195 196 analyzerInfo = 0; 197 SUNW_ldynsym = 0; 198 gnuLink = 0; 199 stab = 0; 200 stabStr = 0; 201 stabIndex = 0; 202 stabIndexStr = 0; 203 stabExcl = 0; 204 stabExclStr = 0; 205 symtab = 0; 206 dynsym = 0; 207 info = 0; 208 plt = 0; 209 dwarf = false; 210 211 for (unsigned int sec = 1; sec < elf_getehdr ()->e_shnum; sec++) 212 { 213 char *name = get_sec_name (sec); 214 if (name == NULL) 215 continue; 216 if (streq (name, NTXT (".stab"))) 217 stab = sec; 218 else if (streq (name, NTXT (".stabstr"))) 219 stabStr = sec; 220 else if (streq (name, NTXT (".stab.index"))) 221 stabIndex = sec; 222 else if (streq (name, NTXT (".stab.indexstr"))) 223 stabIndexStr = sec; 224 else if (streq (name, NTXT (".stab.excl"))) 225 stabExcl = sec; 226 else if (streq (name, NTXT (".stab.exclstr"))) 227 stabExclStr = sec; 228 else if (streq (name, NTXT (".gnu_debuglink"))) 229 gnuLink = sec; 230 else if (streq (name, NTXT (".__analyzer_info"))) 231 analyzerInfo = sec; 232 else if (streq (name, NTXT (".info"))) 233 info = true; 234 else if (streq (name, NTXT (".plt"))) 235 plt = sec; 236 else if (streq (name, NTXT (".SUNW_ldynsym"))) 237 SUNW_ldynsym = sec; 238 else if (streq (name, NTXT (".dynsym"))) 239 dynsym = sec; 240 else if (streq (name, NTXT (".symtab"))) 241 symtab = sec; 242 else if (strncmp (name, NTXT (".debug"), 6) == 0) 243 dwarf = true; 244 } 245 if (fd != -1) 246 { 247 close (fd); 248 fd = -1; 249 } 250 } 251 252 Elf::~Elf () 253 { 254 if (data) 255 { 256 for (int i = 0; i < (int) ehdrp->e_shnum; i++) 257 { 258 Elf_Data *p = data[i]; 259 if (p && !mmap_on_file && (p->d_flags & SHF_SUNW_ABSENT) == 0) 260 free (p->d_buf); 261 delete p; 262 } 263 free (data); 264 } 265 if (ancillary_files) 266 { 267 ancillary_files->destroy (); 268 delete ancillary_files; 269 } 270 delete elfSymbols; 271 delete gnu_debug_file; 272 delete dbeFile; 273 if (abfd) 274 bfd_close (abfd); 275 } 276 277 Elf_Internal_Ehdr * 278 Elf::elf_getehdr () 279 { 280 if (ehdrp == NULL && abfd) 281 ehdrp = elf_elfheader (abfd); 282 return ehdrp; 283 } 284 285 Elf_Internal_Phdr * 286 Elf::get_phdr (unsigned int ndx) 287 { 288 if (ehdrp == NULL || ndx >= ehdrp->e_phnum) 289 return NULL; 290 return &(elf_tdata (abfd)->phdr[ndx]); 291 } 292 293 Elf_Internal_Shdr * 294 Elf::get_shdr (unsigned int ndx) 295 { 296 if (ehdrp == NULL || ndx >= ehdrp->e_shnum) 297 return NULL; 298 return elf_elfsections (abfd)[ndx]; 299 } 300 301 Elf64_Dyn * 302 Elf::elf_getdyn (Elf_Internal_Phdr *phdr, unsigned int ndx, Elf64_Dyn *pdyn) 303 { 304 if (elf_getclass () == ELFCLASS32) 305 { 306 if (ndx * sizeof (Elf32_Dyn) >= phdr->p_filesz) 307 return NULL; 308 Elf32_Dyn *hdr = (Elf32_Dyn*) bind (phdr->p_offset + ndx * sizeof (Elf32_Dyn), 309 sizeof (Elf32_Dyn)); 310 if (hdr == NULL) 311 return NULL; 312 pdyn->d_tag = decode (hdr->d_tag); 313 pdyn->d_un.d_val = decode (hdr->d_un.d_val); 314 } 315 else 316 { 317 if (ndx * sizeof (Elf64_Dyn) >= phdr->p_filesz) 318 return NULL; 319 Elf64_Dyn *hdr = (Elf64_Dyn*) bind (phdr->p_offset + ndx * sizeof (Elf64_Dyn), 320 sizeof (Elf64_Dyn)); 321 if (hdr == NULL) 322 return NULL; 323 pdyn->d_tag = decode (hdr->d_tag); 324 pdyn->d_un.d_val = decode (hdr->d_un.d_val); 325 } 326 return pdyn; 327 } 328 329 unsigned 330 Elf::elf_version (unsigned ver) 331 { 332 // We compile locally, no need to check the version 333 return ver; 334 } 335 336 Elf * 337 Elf::elf_begin (char *fname, Elf_status *stp) 338 { 339 if (fname == NULL) 340 { 341 if (stp) 342 *stp = ELF_ERR_CANT_OPEN_FILE; 343 return NULL; 344 } 345 Elf *elf = new Elf (fname); 346 if (stp) 347 *stp = elf->status; 348 if (elf->status != ELF_ERR_NONE) 349 { 350 delete elf; 351 return NULL; 352 } 353 #if DEBUG 354 if (DUMP_ELF_SEC) 355 { 356 char *str = elf->dump (); 357 fprintf (stderr, NTXT ("%s\n\n"), str); 358 free (str); 359 } 360 #endif /* DEBUG */ 361 return elf; 362 } 363 364 unsigned int 365 Elf::elf_get_sec_num (const char *name) 366 { 367 if (name == NULL || ehdrp == NULL) 368 return 0; 369 for (unsigned int sec = 1; sec < ehdrp->e_shnum; sec++) 370 { 371 Elf_Internal_Shdr *shdr = get_shdr (sec); 372 if (shdr == NULL) 373 continue; 374 char *sname = elf_strptr (ehdrp->e_shstrndx, shdr->sh_name); 375 if (sname != NULL && strcmp (name, sname) == 0) 376 return sec; 377 } 378 return 0; 379 } 380 381 char * 382 Elf::get_sec_name (unsigned int sec) 383 { 384 Elf_Internal_Shdr *shdr = get_shdr (sec); 385 if (ehdrp == NULL || shdr == NULL) 386 return NULL; 387 return elf_strptr (ehdrp->e_shstrndx, shdr->sh_name); 388 } 389 390 Elf_Data * 391 Elf::elf_getdata (unsigned int sec) 392 { 393 if (data == NULL) 394 { 395 data = (Elf_Data **) malloc (ehdrp->e_shnum * sizeof (Elf_Data *)); 396 for (int i = 0; i < (int) ehdrp->e_shnum; i++) 397 data[i] = NULL; 398 } 399 Elf_Data *edta = data[sec]; 400 if (edta == NULL) 401 { 402 Elf_Internal_Shdr *shdr = get_shdr (sec); 403 if (shdr == NULL) 404 return NULL; 405 edta = new Elf_Data; 406 data[sec] = edta; 407 if ((shdr->sh_flags & SHF_SUNW_ABSENT) != 0) 408 { 409 char *sname = get_sec_name (sec); 410 for (int i = 0, sz = VecSize(ancillary_files); i < sz; i++) 411 { 412 Elf *ancElf = ancillary_files->fetch (i); 413 int secNum = sec; 414 if (dbe_strcmp (sname, ancElf->get_sec_name (sec)) != 0) 415 { 416 append_msg (CMSG_WARN, 417 "Warning: the section #%d (%s) is mismatch in ancillary file '%s')\n", 418 sec, STR (sname), STR (ancElf->fname)); 419 secNum = ancElf->elf_get_sec_num (sname); 420 } 421 if (secNum > 0) 422 { 423 Elf_Data *ed = ancElf->elf_getdata (secNum); 424 if (ed && ed->d_buf) 425 { 426 *edta = *ed; 427 edta->d_flags |= SHF_SUNW_ABSENT; 428 return edta; 429 } 430 } 431 } 432 } 433 edta->d_buf = get_data (shdr->sh_offset, (size_t) shdr->sh_size, NULL); 434 edta->d_flags = shdr->sh_flags; 435 edta->d_size = ((edta->d_buf == NULL) || (shdr->sh_type == SHT_NOBITS)) ? 0 : shdr->sh_size; 436 edta->d_off = shdr->sh_offset; 437 edta->d_align = shdr->sh_addralign; 438 } 439 return edta; 440 } 441 442 int64_t 443 Elf::elf_checksum () 444 { 445 if (ehdrp == NULL) 446 return 0; 447 int64_t chk = 0; 448 for (unsigned int ndx = 0; ndx < ehdrp->e_phnum; ndx++) 449 { 450 Elf_Internal_Phdr *phdr = get_phdr (ndx); 451 if (phdr == NULL) 452 continue; 453 if (phdr->p_type == PT_DYNAMIC) 454 { 455 Elf64_Dyn edyn; 456 for (unsigned int i = 0; elf_getdyn (phdr, i, &edyn) != NULL; i++) 457 { 458 if (!edyn.d_tag) 459 break; 460 if (edyn.d_tag == DT_CHECKSUM) 461 { 462 chk = edyn.d_un.d_val; 463 break; 464 } 465 } 466 } 467 } 468 return normalize_checksum (chk); 469 } 470 471 uint64_t 472 Elf::get_baseAddr () 473 { 474 uint64_t addr = 0; 475 for (unsigned int pnum = 0; pnum < elf_getehdr ()->e_phnum; pnum++) 476 { 477 Elf_Internal_Phdr *phdr = get_phdr (pnum); 478 if (phdr->p_type == PT_LOAD && phdr->p_flags == (PF_R | PF_X)) 479 { 480 if (addr == 0) 481 addr = phdr->p_vaddr; 482 else 483 { 484 addr = 0; 485 break; 486 } 487 } 488 } 489 return addr; 490 } 491 492 char * 493 Elf::elf_strptr (unsigned int sec, uint64_t off) 494 { 495 Elf_Data *edta = elf_getdata (sec); 496 if (edta && edta->d_buf && edta->d_size > off) 497 return ((char *) edta->d_buf) + off; 498 return NULL; 499 } 500 501 Elf_Internal_Sym * 502 Elf::elf_getsym (Elf_Data *edta, unsigned int ndx, Elf_Internal_Sym *dst) 503 { 504 if (dst == NULL || edta == NULL) 505 return NULL; 506 if (elf_getclass () == ELFCLASS32) 507 { 508 if (edta->d_size <= ndx * sizeof (Elf32_Sym)) 509 return NULL; 510 Elf32_Sym *hdr = (Elf32_Sym*) bind (edta->d_off + ndx * sizeof (Elf32_Sym), sizeof (Elf32_Sym)); 511 if (hdr == NULL) 512 return NULL; 513 dst->st_name = decode (hdr->st_name); 514 dst->st_value = decode (hdr->st_value); 515 dst->st_size = decode (hdr->st_size); 516 dst->st_info = ELF64_ST_INFO (ELF32_ST_BIND (decode (hdr->st_info)), 517 ELF32_ST_TYPE (decode (hdr->st_info))); 518 dst->st_other = decode (hdr->st_other); 519 dst->st_shndx = decode (hdr->st_shndx); 520 } 521 else 522 { 523 if (edta->d_size <= ndx * sizeof (Elf64_Sym)) 524 return NULL; 525 Elf64_Sym *hdr = (Elf64_Sym*) bind (edta->d_off + ndx * sizeof (Elf64_Sym), 526 sizeof (Elf64_Sym)); 527 if (hdr == NULL) 528 return NULL; 529 dst->st_name = decode (hdr->st_name); 530 dst->st_value = decode (hdr->st_value); 531 dst->st_size = decode (hdr->st_size); 532 dst->st_info = decode (hdr->st_info); 533 dst->st_other = decode (hdr->st_other); 534 dst->st_shndx = decode (hdr->st_shndx); 535 } 536 return dst; 537 } 538 539 Elf_Internal_Rela * 540 Elf::elf_getrel (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst) 541 { 542 if (dst == NULL || edta == NULL || edta->d_buf == NULL) 543 return NULL; 544 if (elf_getclass () == ELFCLASS32) 545 { 546 Elf32_Rel *rel = ((Elf32_Rel *) edta->d_buf) + ndx; 547 dst->r_offset = decode (rel->r_offset); 548 dst->r_info = ELF64_R_INFO (ELF32_R_SYM (decode (rel->r_info)), 549 ELF32_R_TYPE (decode (rel->r_info))); 550 } 551 else 552 { 553 Elf64_Rel *rel = ((Elf64_Rel *) edta->d_buf) + ndx; 554 dst->r_offset = decode (rel->r_offset); 555 dst->r_info = decode (rel->r_info); 556 } 557 return dst; 558 } 559 560 Elf_Internal_Rela * 561 Elf::elf_getrela (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst) 562 { 563 if (dst == NULL || edta == NULL || edta->d_buf == NULL) 564 return NULL; 565 if (elf_getclass () == ELFCLASS32) 566 { 567 Elf32_Rela *rela = ((Elf32_Rela *) edta->d_buf) + ndx; 568 dst->r_offset = decode (rela->r_offset); 569 dst->r_addend = decode (rela->r_addend); 570 dst->r_info = ELF64_R_INFO (ELF32_R_SYM (decode (rela->r_info)), 571 ELF32_R_TYPE (decode (rela->r_info))); 572 } 573 else 574 { 575 Elf64_Rela *rela = ((Elf64_Rela *) edta->d_buf) + ndx; 576 dst->r_offset = decode (rela->r_offset); 577 dst->r_addend = decode (rela->r_addend); 578 dst->r_info = decode (rela->r_info); 579 } 580 return dst; 581 } 582 583 Elf64_Ancillary * 584 Elf::elf_getancillary (Elf_Data *edta, unsigned int ndx, Elf64_Ancillary *dst) 585 { 586 if (dst == NULL || edta == NULL || edta->d_buf == NULL) 587 return NULL; 588 if (elf_getclass () == ELFCLASS32) 589 { 590 Elf32_Ancillary *p = ((Elf32_Ancillary *) edta->d_buf) + ndx; 591 dst->a_tag = decode (p->a_tag); 592 dst->a_un.a_val = decode (p->a_un.a_val); 593 } 594 else 595 { 596 Elf64_Ancillary *p = ((Elf64_Ancillary *) edta->d_buf) + ndx; 597 dst->a_tag = decode (p->a_tag); 598 dst->a_un.a_val = decode (p->a_un.a_val); 599 } 600 return dst; 601 } 602 603 Elf * 604 Elf::get_related_file (const char *lo_name, const char *nm) 605 { 606 DbeFile *df; 607 if (*nm == '/') 608 { 609 df = new DbeFile (nm); 610 df->filetype |= (DbeFile::F_FILE | DbeFile::F_DEBUG_FILE); 611 } 612 else 613 { 614 char *bname = get_basename (lo_name); 615 char *fnm = dbe_sprintf ("%.*s/%s", (int) (bname - lo_name), lo_name, nm); 616 df = new DbeFile (fnm); 617 df->filetype |= (DbeFile::F_FILE | DbeFile::F_DEBUG_FILE); 618 free (fnm); 619 } 620 Dprintf (DEBUG_STABS, "get_related_file: %s -> '%s'\n", nm, df->get_name ()); 621 Elf_status st = ELF_ERR_CANT_OPEN_FILE; 622 Elf *elf = elf_begin (df->get_location (), &st); 623 if (elf) 624 { 625 elf->dbeFile = df; 626 return elf; 627 } 628 switch (st) 629 { 630 case ELF_ERR_CANT_OPEN_FILE: 631 append_msg (CMSG_ERROR, GTXT ("Cannot open file `%s'"), df->get_name ()); 632 break; 633 case ELF_ERR_BAD_ELF_FORMAT: 634 default: 635 append_msg (CMSG_ERROR, GTXT ("Cannot read ELF header of `%s'"), 636 df->get_name ()); 637 break; 638 } 639 delete df; 640 return NULL; 641 } 642 643 Elf * 644 Elf::find_ancillary_files (char *lo_name) 645 { 646 // read the .gnu_debuglink and .SUNW_ancillary seections 647 if (gnu_debug_file) 648 return gnu_debug_file; 649 unsigned int sec = elf_get_sec_num (NTXT (".gnu_debuglink")); 650 if (sec > 0) 651 { 652 Elf_Data *dp = elf_getdata (sec); 653 if (dp) 654 { 655 gnu_debug_file = get_related_file (lo_name, (char *) (dp->d_buf)); 656 if (gnu_debug_file) 657 return gnu_debug_file; 658 } 659 } 660 661 sec = elf_get_sec_num (NTXT (".SUNW_ancillary")); 662 if (sec > 0) 663 { 664 Elf_Internal_Shdr *shdr = get_shdr (sec); 665 uint64_t check_sum = 0; 666 char *ancName = NULL; 667 if (shdr) 668 { 669 Elf_Data *dp = elf_getdata (sec); 670 for (int i = 0, sz = (int) (shdr->sh_size / shdr->sh_entsize); 671 i < sz; i++) 672 { 673 Elf64_Ancillary anc; 674 if (elf_getancillary (dp, i, &anc) == NULL 675 || anc.a_tag == ANC_SUNW_NULL) 676 break; 677 if (anc.a_tag == ANC_SUNW_MEMBER) 678 ancName = elf_strptr (shdr->sh_link, anc.a_un.a_ptr); 679 else if (anc.a_tag == ANC_SUNW_CHECKSUM) 680 { 681 if (i == 0) 682 { 683 check_sum = anc.a_un.a_val; 684 continue; 685 } 686 if (check_sum == anc.a_un.a_val) 687 ancName = NULL; 688 if (ancName) 689 { 690 Elf *ancElf = get_related_file (lo_name, ancName); 691 if (ancElf == NULL) 692 continue; 693 int ancSec = ancElf->elf_get_sec_num (".SUNW_ancillary"); 694 if (ancSec > 0) 695 { 696 Elf_Internal_Shdr *ancHdr = ancElf->get_shdr (ancSec); 697 if (ancHdr) 698 { 699 Elf_Data *anc_dp = ancElf->elf_getdata (ancSec); 700 Elf64_Ancillary anc1; 701 if (ancElf->elf_getancillary (anc_dp, 0, &anc1) 702 && (anc1.a_tag == ANC_SUNW_CHECKSUM) && 703 anc1.a_un.a_val == anc.a_un.a_val) 704 { 705 if (ancillary_files == NULL) 706 ancillary_files = new Vector<Elf*>(2); 707 ancillary_files->append (ancElf); 708 } 709 else 710 append_msg (CMSG_WARN, GTXT ("Load Object: '%s' (checksum Ox%lld). The .anc file '%s' has checksum Ox%llx"), 711 STR (fname), (long long) check_sum, 712 STR (ancElf->dbeFile->get_location ()), 713 (long long) anc1.a_un.a_val); 714 } 715 } 716 ancName = NULL; 717 } 718 } 719 } 720 } 721 } 722 return NULL; 723 } 724 725 char* 726 Elf::get_location () 727 { 728 return dbeFile ? dbeFile->get_location () : fname; 729 } 730 731 #define RET_S(x) if (t == x) return (char *) #x 732 733 static char * 734 get_elf_class_name (int t) 735 { 736 RET_S (ELFCLASSNONE); 737 RET_S (ELFCLASS32); 738 RET_S (ELFCLASS64); 739 return NTXT ("ELFCLASS_UNKNOWN"); 740 } 741 742 static char * 743 get_elf_data_name (int t) 744 { 745 RET_S (ELFDATANONE); 746 RET_S (ELFDATA2LSB); 747 RET_S (ELFDATA2MSB); 748 return NTXT ("ELFDATA_UNKNOWN"); 749 } 750 751 static char * 752 get_elf_osabi_name (int t) 753 { 754 RET_S (ELFOSABI_NONE); 755 RET_S (ELFOSABI_HPUX); 756 RET_S (ELFOSABI_NETBSD); 757 RET_S (ELFOSABI_LINUX); 758 RET_S (ELFOSABI_SOLARIS); 759 RET_S (ELFOSABI_AIX); 760 RET_S (ELFOSABI_IRIX); 761 RET_S (ELFOSABI_FREEBSD); 762 RET_S (ELFOSABI_TRU64); 763 RET_S (ELFOSABI_MODESTO); 764 RET_S (ELFOSABI_OPENBSD); 765 return NTXT ("ELFOSABI_UNKNOWN"); 766 } 767 768 static char * 769 get_elf_etype_name (int t) 770 { 771 RET_S (ET_NONE); 772 RET_S (ET_REL); 773 RET_S (ET_EXEC); 774 RET_S (ET_DYN); 775 RET_S (ET_CORE); 776 RET_S (ET_LOPROC); 777 RET_S (ET_HIPROC); 778 return NTXT ("ETYPE_UNKNOWN"); 779 } 780 781 static char * 782 get_elf_ptype_name (int t) 783 { 784 RET_S (PT_NULL); 785 RET_S (PT_LOAD); 786 RET_S (PT_DYNAMIC); 787 RET_S (PT_INTERP); 788 RET_S (PT_NOTE); 789 RET_S (PT_SHLIB); 790 RET_S (PT_PHDR); 791 RET_S (PT_TLS); 792 RET_S (PT_LOOS); 793 RET_S (PT_GNU_EH_FRAME); 794 RET_S (PT_GNU_EH_FRAME); 795 RET_S (PT_HIOS); 796 RET_S (PT_LOPROC); 797 RET_S (PT_HIPROC); 798 return NTXT ("PTYPE_UNKNOWN"); 799 } 800 801 static char * 802 get_elf_shtype_name (unsigned int t) 803 { 804 RET_S (SHT_NULL); 805 RET_S (SHT_PROGBITS); 806 RET_S (SHT_SYMTAB); 807 RET_S (SHT_STRTAB); 808 RET_S (SHT_RELA); 809 RET_S (SHT_HASH); 810 RET_S (SHT_DYNAMIC); 811 RET_S (SHT_NOTE); 812 RET_S (SHT_NOBITS); 813 RET_S (SHT_REL); 814 RET_S (SHT_SHLIB); 815 RET_S (SHT_DYNSYM); 816 RET_S (SHT_INIT_ARRAY); 817 RET_S (SHT_FINI_ARRAY); 818 RET_S (SHT_PREINIT_ARRAY); 819 RET_S (SHT_GROUP); 820 RET_S (SHT_SYMTAB_SHNDX); 821 RET_S (SHT_LOOS); 822 RET_S (SHT_SUNW_verdef); 823 RET_S (SHT_SUNW_verneed); 824 RET_S (SHT_HIOS); 825 RET_S (SHT_LOPROC); 826 RET_S (SHT_HIPROC); 827 RET_S (SHT_LOUSER); 828 RET_S (SHT_HIUSER); 829 return NTXT ("SHTYPE_UNKNOWN"); 830 } 831 832 static char * 833 get_elf_machine_name (int t) 834 { 835 RET_S (EM_NONE); 836 RET_S (EM_M32); 837 RET_S (EM_SPARC); 838 RET_S (EM_386); 839 RET_S (EM_68K); 840 RET_S (EM_88K); 841 RET_S (EM_860); 842 RET_S (EM_MIPS); 843 RET_S (EM_S370); 844 RET_S (EM_MIPS_RS3_LE); 845 RET_S (EM_SPARC32PLUS); 846 RET_S (EM_960); 847 RET_S (EM_PPC); 848 RET_S (EM_PPC64); 849 RET_S (EM_V800); 850 RET_S (EM_FR20); 851 RET_S (EM_RH32); 852 RET_S (EM_RCE); 853 RET_S (EM_ARM); 854 RET_S (EM_ALPHA); 855 RET_S (EM_SH); 856 RET_S (EM_SPARCV9); 857 RET_S (EM_TRICORE); 858 RET_S (EM_ARC); 859 RET_S (EM_H8_300); 860 RET_S (EM_H8_300H); 861 RET_S (EM_H8S); 862 RET_S (EM_H8_500); 863 RET_S (EM_IA_64); 864 RET_S (EM_MIPS_X); 865 RET_S (EM_COLDFIRE); 866 RET_S (EM_68HC12); 867 RET_S (EM_MMA); 868 RET_S (EM_PCP); 869 RET_S (EM_NCPU); 870 RET_S (EM_NDR1); 871 RET_S (EM_STARCORE); 872 RET_S (EM_ME16); 873 RET_S (EM_ST100); 874 RET_S (EM_TINYJ); 875 RET_S (EM_X86_64); 876 RET_S (EM_PDSP); 877 RET_S (EM_FX66); 878 RET_S (EM_ST9PLUS); 879 RET_S (EM_ST7); 880 RET_S (EM_68HC16); 881 RET_S (EM_68HC11); 882 RET_S (EM_68HC08); 883 RET_S (EM_68HC05); 884 RET_S (EM_SVX); 885 RET_S (EM_ST19); 886 RET_S (EM_VAX); 887 RET_S (EM_CRIS); 888 RET_S (EM_JAVELIN); 889 RET_S (EM_FIREPATH); 890 RET_S (EM_ZSP); 891 RET_S (EM_MMIX); 892 RET_S (EM_HUANY); 893 RET_S (EM_PRISM); 894 RET_S (EM_AVR); 895 RET_S (EM_FR30); 896 RET_S (EM_D10V); 897 RET_S (EM_D30V); 898 RET_S (EM_V850); 899 RET_S (EM_M32R); 900 RET_S (EM_MN10300); 901 RET_S (EM_MN10200); 902 RET_S (EM_PJ); 903 RET_S (EM_OPENRISC); 904 RET_S (EM_XTENSA); 905 return NTXT ("ELFMACHINE_UNKNOWN"); 906 } 907 908 static char * 909 get_elf_version_name (int t) 910 { 911 RET_S (EV_NONE); 912 RET_S (EV_CURRENT); 913 return NTXT ("VERSION_UNKNOWN"); 914 } 915 916 static char * 917 get_elf_ancillary_tag (int t) 918 { 919 RET_S (ANC_SUNW_NULL); 920 RET_S (ANC_SUNW_CHECKSUM); 921 RET_S (ANC_SUNW_MEMBER); 922 RET_S (ANC_SUNW_NUM); 923 return NTXT ("ANCILLARY_TAG_UNKNOWN"); 924 } 925 926 #define ADD_S(x) if ((f & (x)) == (x)) { sb->append(' '); sb->append(#x); f &= ~(x); } 927 928 static void 929 dump_sh_flags (StringBuilder *sb, long long flags) 930 { 931 long long f = flags; 932 if (f != 0) 933 { 934 sb->append (NTXT (" [")); 935 ADD_S (SHF_WRITE) 936 ADD_S (SHF_ALLOC) 937 ADD_S (SHF_EXECINSTR) 938 ADD_S (SHF_MERGE) 939 ADD_S (SHF_STRINGS) 940 ADD_S (SHF_INFO_LINK) 941 ADD_S (SHF_LINK_ORDER) 942 ADD_S (SHF_OS_NONCONFORMING) 943 ADD_S (SHF_GROUP) 944 ADD_S (SHF_TLS) 945 ADD_S (SHF_SUNW_ABSENT) 946 ADD_S (SHF_EXCLUDE) 947 if (f != 0 && f != flags) 948 sb->appendf (NTXT (" 0x%llx"), (long long) f); 949 sb->append (NTXT (" ]")); 950 } 951 sb->append (NTXT ("\n")); 952 } 953 954 static void 955 dump_p_flags (StringBuilder *sb, long long flags) 956 { 957 long long f = flags; 958 if (f != 0) 959 { 960 sb->append (NTXT (" [")); 961 ADD_S (PF_X) 962 ADD_S (PF_W) 963 ADD_S (PF_R) 964 ADD_S (PF_MASKPROC) 965 if (f != 0 && f != flags) 966 sb->appendf (NTXT (" 0x%llx"), (long long) f); 967 sb->append (NTXT (" ]")); 968 } 969 sb->append (NTXT ("\n")); 970 } 971 972 char * 973 Elf::dump () 974 { 975 StringBuilder sb; 976 sb.sprintf (NTXT ("ELF Header: %s\n"), fname ? fname : GTXT ("(unknown)")); 977 if (ehdrp == NULL) 978 { 979 sb.appendf (GTXT ("\n\n Cannot read Elf header\n")); 980 return sb.toString (); 981 } 982 sb.appendf (NTXT (" %-15s "), NTXT ("e_ident")); 983 for (int i = 0; i < EI_NIDENT; i++) 984 sb.appendf (NTXT ("%x"), ehdrp->e_ident[i]); 985 sb.append (NTXT ("\n")); 986 char *fmt0 = NTXT (" %-15s %10lld ( %s )\n"); 987 char *fmt1 = NTXT (" %-15s 0x%08llx ( %lld )\n"); 988 char *fmt2 = NTXT (" %-15s 0x%08llx"); 989 sb.appendf (fmt0, NTXT ("EI_CLASS"), (long long) ehdrp->e_ident[EI_CLASS], 990 get_elf_class_name (ehdrp->e_ident[EI_CLASS])); 991 sb.appendf (fmt0, NTXT ("EI_DATA"), (long long) ehdrp->e_ident[EI_DATA], 992 get_elf_data_name (ehdrp->e_ident[EI_DATA])); 993 sb.appendf (fmt0, NTXT ("EI_OSABI"), (long long) ehdrp->e_ident[EI_OSABI], 994 get_elf_osabi_name (ehdrp->e_ident[EI_OSABI])); 995 sb.appendf (fmt0, NTXT ("e_type"), (long long) ehdrp->e_type, 996 get_elf_etype_name (ehdrp->e_type)); 997 sb.appendf (fmt0, NTXT ("e_machine"), (long long) ehdrp->e_machine, 998 get_elf_machine_name (ehdrp->e_machine)); 999 sb.appendf (fmt0, NTXT ("e_version"), (long long) ehdrp->e_version, 1000 get_elf_version_name (ehdrp->e_version)); 1001 sb.appendf (fmt1, NTXT ("e_entry"), (long long) ehdrp->e_entry, 1002 (long long) ehdrp->e_entry); 1003 sb.appendf (fmt1, NTXT ("e_phoff"), (long long) ehdrp->e_phoff, 1004 (long long) ehdrp->e_phoff); 1005 sb.appendf (fmt1, NTXT ("e_shoff"), (long long) ehdrp->e_shoff, 1006 (long long) ehdrp->e_shoff); 1007 sb.appendf (fmt1, NTXT ("e_flags"), (long long) ehdrp->e_flags, 1008 (long long) ehdrp->e_flags); 1009 sb.appendf (fmt1, NTXT ("e_ehsize"), (long long) ehdrp->e_ehsize, 1010 (long long) ehdrp->e_ehsize); 1011 sb.appendf (fmt1, NTXT ("e_phentsize"), (long long) ehdrp->e_phentsize, 1012 (long long) ehdrp->e_phentsize); 1013 sb.appendf (fmt1, NTXT ("e_phnum"), (long long) ehdrp->e_phnum, 1014 (long long) ehdrp->e_phnum); 1015 sb.appendf (fmt1, NTXT ("e_shentsize"), (long long) ehdrp->e_shentsize, 1016 (long long) ehdrp->e_shentsize); 1017 sb.appendf (fmt1, NTXT ("e_shnum"), (long long) ehdrp->e_shnum, 1018 (long long) ehdrp->e_shnum); 1019 sb.appendf (fmt1, NTXT ("e_shstrndx"), (long long) ehdrp->e_shstrndx, 1020 (long long) ehdrp->e_shstrndx); 1021 1022 for (unsigned int i = 0; i < ehdrp->e_phnum; i++) 1023 { 1024 sb.appendf (NTXT ("\nProgram Header[%d]:\n"), i); 1025 Elf_Internal_Phdr *phdr = get_phdr (i); 1026 if (phdr == NULL) 1027 { 1028 sb.appendf (NTXT (" ERROR: get_phdr(%d) failed\n"), i); 1029 continue; 1030 } 1031 sb.appendf (fmt0, "p_type", (long long) phdr->p_type, 1032 get_elf_ptype_name (phdr->p_type)); 1033 sb.appendf (fmt2, "p_flags", (long long) phdr->p_flags); 1034 dump_p_flags (&sb, phdr->p_flags); 1035 sb.appendf (fmt1, "p_offset", (long long) phdr->p_offset, 1036 (long long) phdr->p_offset); 1037 sb.appendf (fmt1, "p_vaddr", (long long) phdr->p_vaddr, 1038 (long long) phdr->p_vaddr); 1039 sb.appendf (fmt1, "p_paddr", (long long) phdr->p_paddr, 1040 (long long) phdr->p_paddr); 1041 sb.appendf (fmt1, "p_filesz", (long long) phdr->p_filesz, 1042 (long long) phdr->p_filesz); 1043 sb.appendf (fmt1, "p_memsz", (long long) phdr->p_memsz, 1044 (long long) phdr->p_memsz); 1045 sb.appendf (fmt1, "p_align", (long long) phdr->p_align, 1046 (long long) phdr->p_align); 1047 } 1048 1049 for (unsigned int i = 1; i < ehdrp->e_shnum; i++) 1050 { 1051 sb.appendf (NTXT ("\nSection Header[%d]:\n"), i); 1052 Elf_Internal_Shdr *shdr = get_shdr (i); 1053 if (shdr == NULL) 1054 { 1055 sb.appendf (NTXT (" ERROR: get_shdr(%d) failed\n"), i); 1056 continue; 1057 } 1058 char *s = get_sec_name (i); 1059 sb.appendf (fmt0, "sh_name", (long long) shdr->sh_name, 1060 s ? s : NTXT ("NULL")); 1061 sb.appendf (fmt0, "sh_type", (long long) shdr->sh_type, 1062 get_elf_shtype_name (shdr->sh_type)); 1063 sb.appendf (fmt2, "sh_flags", (long long) shdr->sh_flags); 1064 dump_sh_flags (&sb, shdr->sh_flags); 1065 sb.appendf (fmt1, "sh_addr", (long long) shdr->sh_addr, 1066 (long long) shdr->sh_addr); 1067 sb.appendf (fmt1, "sh_offset", (long long) shdr->sh_offset, 1068 (long long) shdr->sh_offset); 1069 sb.appendf (fmt1, "sh_size", (long long) shdr->sh_size, 1070 (long long) shdr->sh_size); 1071 sb.appendf (fmt1, "sh_link", (long long) shdr->sh_link, 1072 (long long) shdr->sh_link); 1073 sb.appendf (fmt1, "sh_info", (long long) shdr->sh_info, 1074 (long long) shdr->sh_info); 1075 sb.appendf (fmt1, "sh_addralign", (long long) shdr->sh_addralign, 1076 (long long) shdr->sh_addralign); 1077 sb.appendf (fmt1, "sh_entsize", (long long) shdr->sh_entsize, 1078 (long long) shdr->sh_entsize); 1079 } 1080 1081 for (unsigned int i = 1; i < ehdrp->e_shnum; i++) 1082 { 1083 Elf_Internal_Shdr *shdr = get_shdr (i); 1084 if (shdr == NULL) 1085 continue; 1086 char *secName = get_sec_name (i); 1087 if (secName == NULL) 1088 continue; 1089 if (strcmp (NTXT (".SUNW_ancillary"), secName) == 0) 1090 { 1091 sb.appendf (NTXT ("\nSection[%d]: %s\n"), i, secName); 1092 Elf_Data *dp = elf_getdata (i); 1093 for (int j = 0, cnt = (int) (shdr->sh_size / shdr->sh_entsize); 1094 j < cnt; j++) 1095 { 1096 Elf64_Ancillary anc; 1097 if (elf_getancillary (dp, j, &anc) == NULL) 1098 break; 1099 sb.appendf (NTXT ("%10d %-20s 0x%08llx %6lld"), j, 1100 get_elf_ancillary_tag ((int) anc.a_tag), 1101 (long long) anc.a_un.a_ptr, (long long) anc.a_un.a_ptr); 1102 if (anc.a_tag == ANC_SUNW_MEMBER) 1103 sb.appendf (NTXT (" %s\n"), STR (elf_strptr (shdr->sh_link, anc.a_un.a_ptr))); 1104 else 1105 sb.append (NTXT ("\n")); 1106 } 1107 } 1108 } 1109 return sb.toString (); 1110 } 1111 1112 void 1113 Elf::dump_elf_sec () 1114 { 1115 if (!DUMP_ELF_SEC) 1116 return; 1117 if (ehdrp == NULL) 1118 return; 1119 Dprintf (DUMP_ELF_SEC, "======= DwarfLib::dump_elf_sec\n" 1120 " N |type|flags| sh_addr | sh_offset | sh_size | sh_link |" 1121 " sh_info | sh_addralign | sh_entsize | sh_name | name\n"); 1122 for (unsigned int sec = 1; sec < ehdrp->e_shnum; sec++) 1123 { 1124 Elf_Internal_Shdr *shdr = get_shdr (sec); 1125 if (shdr == NULL) 1126 continue; 1127 char *name = elf_strptr (ehdrp->e_shstrndx, shdr->sh_name); 1128 Dprintf (DUMP_ELF_SEC, "%3d:%3d |%4d |%9lld | %9lld |%8lld |%8lld |" 1129 "%8lld |%14d |%11lld | %6lld %s\n", 1130 sec, (int) shdr->sh_type, (int) shdr->sh_flags, 1131 (long long) shdr->sh_addr, (long long) shdr->sh_offset, 1132 (long long) shdr->sh_size, (long long) shdr->sh_link, 1133 (long long) shdr->sh_info, 1134 (int) shdr->sh_addralign, (long long) shdr->sh_entsize, 1135 (long long) shdr->sh_name, name ? name : NTXT ("NULL")); 1136 } 1137 Dprintf (DUMP_ELF_SEC, NTXT ("\n")); 1138 } 1139