elf_extractor.c (19813B)
1 /* 2 This file is part of libextractor. 3 Copyright (C) 2012 Vidyut Samanta and Christian Grothoff 4 5 libextractor is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published 7 by the Free Software Foundation; either version 3, or (at your 8 option) any later version. 9 10 libextractor is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with libextractor; see the file COPYING. If not, write to the 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 /** 21 * @file plugins/elf_extractor.c 22 * @brief plugin to support ELF files 23 * @author Christian Grothoff 24 */ 25 #include "platform.h" 26 #include "extractor.h" 27 #include "pack.h" 28 #include <stdint.h> 29 30 31 typedef uint32_t Elf32_Addr; 32 typedef uint16_t Elf32_Half; 33 typedef uint32_t Elf32_Off; 34 typedef int32_t Elf32_Sword; 35 typedef uint32_t Elf32_Word; 36 37 typedef uint16_t Elf64_Half; 38 typedef uint32_t Elf64_Word; 39 typedef uint64_t Elf64_Addr; 40 typedef uint64_t Elf64_Off; 41 42 /* first 4 bytes of the ELF header */ 43 static char elfMagic[] = { 0x7f, 'E', 'L', 'F' }; 44 45 #define EI_CLASS 4 46 #define EI_DATA 5 47 #define EI_VERSION 6 48 #define EI_OSABI 7 49 #define EI_NIDENT 16 50 51 typedef struct 52 { 53 Elf32_Half e_type; 54 Elf32_Half e_machine; 55 Elf32_Word e_version; 56 Elf32_Addr e_entry; 57 Elf32_Off e_phoff; 58 Elf32_Off e_shoff; /* offset of the section header table */ 59 Elf32_Word e_flags; 60 Elf32_Half e_ehsize; 61 Elf32_Half e_phensize; 62 Elf32_Half e_phnum; 63 Elf32_Half e_shentsize; /* size of each entry in SH table */ 64 Elf32_Half e_shnum; /* how many entries in section header table */ 65 Elf32_Half e_shstrndx; /* section header's sh_name member is index into this string table! */ 66 } Elf32_Ehdr; 67 68 /* elf-header minus e_ident */ 69 #define ELF_HEADER_SIZE sizeof (Elf32_Ehdr) 70 71 #define ELF_HEADER_FIELDS(p) \ 72 & (p)->e_type, \ 73 &(p)->e_machine, \ 74 &(p)->e_version, \ 75 &(p)->e_entry, \ 76 &(p)->e_phoff, \ 77 &(p)->e_shoff, \ 78 &(p)->e_flags, \ 79 &(p)->e_ehsize, \ 80 &(p)->e_phensize, \ 81 &(p)->e_phnum, \ 82 &(p)->e_shentsize, \ 83 &(p)->e_shnum, \ 84 &(p)->e_shstrndx 85 static char *ELF_HEADER_SPECS[] = { 86 "hhwwwwwhhhhhh", 87 "HHWWWWWHHHHHH", 88 }; 89 90 typedef struct 91 { 92 Elf64_Half e_type; 93 Elf64_Half e_machine; 94 Elf64_Word e_version; 95 Elf64_Addr e_entry; 96 Elf64_Off e_phoff; 97 Elf64_Off e_shoff; 98 Elf64_Word e_flags; 99 Elf64_Half e_ehsize; 100 Elf64_Half e_phensize; 101 Elf64_Half e_phnum; 102 Elf64_Half e_shentsize; 103 Elf64_Half e_shnum; 104 Elf64_Half e_shstrndx; 105 } Elf64_Ehdr; 106 107 /* elf-header minus e_ident */ 108 #define ELF64_HEADER_SIZE sizeof (Elf64_Ehdr) 109 110 #define ELF64_HEADER_FIELDS(p) \ 111 & (p)->e_type, \ 112 &(p)->e_machine, \ 113 &(p)->e_version, \ 114 &(p)->e_entry, \ 115 &(p)->e_phoff, \ 116 &(p)->e_shoff, \ 117 &(p)->e_flags, \ 118 &(p)->e_ehsize, \ 119 &(p)->e_phensize, \ 120 &(p)->e_phnum, \ 121 &(p)->e_shentsize, \ 122 &(p)->e_shnum, \ 123 &(p)->e_shstrndx 124 static char *ELF64_HEADER_SPECS[] = { 125 "hhwxxxwhhhhhh", 126 "HHWXXXWHHHHHH", 127 }; 128 129 130 typedef struct 131 { 132 Elf32_Word sh_name; 133 Elf32_Word sh_type; 134 Elf32_Word sh_flags; 135 Elf32_Addr sh_addr; /* where loaded */ 136 Elf32_Off sh_offset; /* where in image (! sh_type==SHT_NOBITS) */ 137 Elf32_Word sh_size; /* section size in bytes */ 138 Elf32_Word sh_link; /* for symbol table: section header index of the associated string table! */ 139 Elf32_Word sh_info; /* "one greater than the symbol table index of the last local symbol _STB_LOCAL_" */ 140 Elf32_Word sh_addralign; 141 Elf32_Word sh_entsize; 142 } Elf32_Shdr; 143 #define ELF_SECTION_SIZE 40 144 145 #define ELF_SECTION_FIELDS(p) \ 146 & (p)->sh_name, \ 147 &(p)->sh_type, \ 148 &(p)->sh_flags, \ 149 &(p)->sh_addr, \ 150 &(p)->sh_offset, \ 151 &(p)->sh_size, \ 152 &(p)->sh_link, \ 153 &(p)->sh_info, \ 154 &(p)->sh_addralign, \ 155 &(p)->sh_entsize 156 static char *ELF_SECTION_SPECS[] = { 157 "wwwwwwwwww", 158 "WWWWWWWWWW", 159 }; 160 161 typedef struct 162 { 163 Elf32_Word p_type; 164 Elf32_Off p_offset; 165 Elf32_Addr p_vaddr; 166 Elf32_Addr p_paddr; 167 Elf32_Word p_filesz; 168 Elf32_Word p_memsz; 169 Elf32_Word p_flags; 170 Elf32_Word p_align; 171 } Elf32_Phdr; 172 #define ELF_PDHR_SIZE 32 173 #define ELF_PHDR_FIELDS(p) \ 174 & (p)->p_type, \ 175 &(p)->p_offset, \ 176 &(p)->p_vaddr, \ 177 &(p)->p_paddr, \ 178 &(p)->p_filesz, \ 179 &(p)->p_memsz, \ 180 &(p)->p_flags, \ 181 &(p)->p_align 182 static char *ELF_PHDR_SPECS[] = { 183 "wwwwwwww", 184 "WWWWWWWW", 185 }; 186 187 typedef struct 188 { 189 Elf32_Sword d_tag; 190 union 191 { 192 Elf32_Word d_val; 193 Elf32_Addr d_ptr; 194 } d_un; 195 } Elf32_Dyn; 196 #define ELF_DYN_SIZE 8 197 #define ELF_DYN_FIELDS(p) \ 198 & (p)->d_tag, \ 199 &(p)->d_un 200 static char *ELF_DYN_SPECS[] = { 201 "ww", 202 "WW", 203 }; 204 205 #define ET_NONE 0 206 #define ET_REL 1 207 #define ET_EXEC 2 208 #define ET_DYN 3 209 #define ET_CORE 4 210 #define ET_LOPROC 0xff00 211 #define ET_HIPROC 0xffff 212 213 #define EM_NONE 0 214 #define EM_M32 1 215 #define EM_SPARC 2 216 #define EM_386 3 217 #define EM_68K 4 218 #define EM_88K 5 219 #define EM_860 7 220 #define EM_MIPS 8 221 #define EM_PPC 20 222 #define EM_PPC64 21 223 #define EM_S390 22 224 #define EM_ARM 40 225 #define EM_ALPHA 41 226 #define EM_IA_64 50 227 #define EM_X86_64 62 228 #define EM_CUDA 190 229 230 #define ELFOSABI_NETBSD 2 231 #define ELFOSABI_LINUX 3 232 #define ELFOSABI_IRIX 8 233 #define ELFOSABI_FREEBSD 9 234 #define ELFOSABI_OPENBSD 12 235 236 #define EV_NONE 0 237 #define EV_CURRENT 1 238 239 #define SHT_NULL 0 240 #define SHT_PROGBITS 1 241 #define SHT_SYMTAB 2 242 /* string table! */ 243 #define SHT_STRTAB 3 244 #define SHT_RELA 4 245 #define SHT_HASH 5 246 /* dynamic linking info! */ 247 #define SHT_DYNAMIC 6 248 #define SHT_NOTE 7 249 #define SHT_NOBITS 8 250 #define SHT_REL 9 251 #define SHT_SHLIB 10 252 #define SHT_DYNSYM 11 253 #define SHT_LOPROC 0x70000000 254 #define SHT_HIPROC 0x7fffffff 255 #define SHT_LOUSER 0x80000000 256 #define SHT_HIUSER 0xffffffff 257 258 #define SHF_WRITE 0x1 259 #define SHF_ALLOC 0x2 260 #define SHF_EXECINSTR 0x4 261 #define SHF_MASKPROC 0xf000000 262 263 #define DT_NULL 0 264 /* name of a needed library, offset into table 265 recorded in DT_STRTAB entry */ 266 #define DT_NEEDED 1 267 #define DT_PLTRELSZ 2 268 #define DT_PLTGOT 3 269 #define DT_HASH 4 270 /* address of the string table from where symbol 271 names, library names, etc for this DT come from */ 272 #define DT_STRTAB 5 273 #define DT_SYMTAB 6 274 #define DT_SYMENT 7 275 #define DT_RELA 7 276 #define DT_RELASZ 8 277 #define DT_RELAENT 9 278 /* size of the string-table in bytes */ 279 #define DT_STRSZ 10 280 /* fixme 11 */ 281 #define DT_INIT 12 282 #define DT_FINI 13 283 /* string-table offset giving the name of the shared object */ 284 #define DT_SONAME 14 285 /* string-table offset of a null-terminated library search path */ 286 #define DT_RPATH 15 287 #define DT_SYMBOLIC 16 288 289 290 #define PT_NULL 0 291 #define PT_LOAD 1 292 #define PT_DYNAMIC 2 293 #define PT_INTERP 3 294 #define PT_NOTE 4 295 #define PT_SHLIB 5 296 #define PT_PHDR 6 297 #define PT_LOPROC 0x70000000 298 #define PT_HIPROC 0x7fffffff 299 300 301 #define ELFCLASSNONE 0 302 #define ELFCLASS32 1 303 #define ELFCLASS64 2 304 305 #define ELFDATANONE 0 306 /* little endian */ 307 #define ELFDATA2LSB 1 308 /* big endian */ 309 #define ELFDATA2MSB 2 310 311 /** 312 * @param ei_data ELFDATA2LSB or ELFDATA2MSB 313 * @return 0 for little-endian ELF (use lowercase pack specs), 314 * 1 for big-endian ELF (use uppercase pack specs) 315 */ 316 static unsigned int 317 get_byte_order (char ei_data) 318 { 319 return (ei_data == ELFDATA2LSB) ? 0 : 1; 320 } 321 322 323 /** 324 * 325 * @return 0 on success, -1 on error 326 */ 327 static int 328 get_section_header (struct EXTRACTOR_ExtractContext *ec, 329 unsigned int bo, 330 const Elf32_Ehdr *ehdr, 331 Elf32_Half idx, 332 Elf32_Shdr *ret) 333 { 334 ssize_t size; 335 uint64_t max; 336 int64_t off; 337 void *data; 338 339 if (ehdr->e_shnum <= idx) 340 return -1; 341 max = ec->get_size (ec->cls); 342 if (ehdr->e_shoff + ehdr->e_shentsize * idx + sizeof (*ret) > max) 343 return -1; 344 off = ec->seek (ec->cls, 345 ehdr->e_shoff + ehdr->e_shentsize * idx, 346 SEEK_SET); 347 if (-1 == off) 348 return -1; 349 size = ec->read (ec->cls, 350 &data, 351 sizeof (*ret)); 352 if (size < sizeof (*ret)) 353 return -1; 354 EXTRACTOR_common_cat_unpack (data, 355 ELF_SECTION_SPECS[bo], 356 ELF_SECTION_FIELDS (ret)); 357 return 0; 358 } 359 360 361 /** 362 * 363 * @return 0 on success, -1 on error 364 */ 365 static int 366 getDynTag (struct EXTRACTOR_ExtractContext *ec, 367 unsigned int bo, 368 const Elf32_Ehdr *ehdr, 369 Elf32_Off off, 370 Elf32_Word osize, 371 unsigned int idx, 372 Elf32_Dyn *ret) 373 { 374 ssize_t size; 375 uint64_t max; 376 int64_t soff; 377 void *data; 378 379 max = ec->get_size (ec->cls); 380 if ( (off + osize > max) || 381 ((idx + 1) * ELF_DYN_SIZE > osize) ) 382 return -1; 383 if (off + idx * ELF_DYN_SIZE + sizeof (*ret) > max) 384 return -1; 385 soff = ec->seek (ec->cls, 386 off + idx * ELF_DYN_SIZE, 387 SEEK_SET); 388 if (-1 == soff) 389 return -1; 390 size = ec->read (ec->cls, 391 &data, 392 sizeof (*ret)); 393 if (size < sizeof (*ret)) 394 return -1; 395 EXTRACTOR_common_cat_unpack (data, 396 ELF_DYN_SPECS[bo], 397 ELF_DYN_FIELDS (ret)); 398 return 0; 399 } 400 401 402 /** 403 * 404 * @return 0 on success, -1 on error 405 */ 406 static int 407 getProgramHdr (struct EXTRACTOR_ExtractContext *ec, 408 unsigned int bo, 409 const Elf32_Ehdr *ehdr, 410 Elf32_Half idx, 411 Elf32_Phdr *ret) 412 { 413 void *data; 414 ssize_t size; 415 int64_t off; 416 417 if (ehdr->e_phnum <= idx) 418 return -1; 419 off = ec->seek (ec->cls, 420 ehdr->e_phoff + ehdr->e_phensize * idx, 421 SEEK_SET); 422 if (-1 == off) 423 return -1; 424 size = ec->read (ec->cls, 425 &data, 426 sizeof (*ret)); 427 if (size < sizeof (*ret)) 428 return -1; 429 EXTRACTOR_common_cat_unpack (data, 430 ELF_PHDR_SPECS[bo], 431 ELF_PHDR_FIELDS (ret)); 432 return 0; 433 } 434 435 436 /** 437 * @return the string (offset into data, do NOT free), NULL on error 438 */ 439 static char * 440 readStringTable (struct EXTRACTOR_ExtractContext *ec, 441 unsigned int bo, 442 const Elf32_Ehdr *ehdr, 443 Elf32_Half strTableOffset, 444 Elf32_Word sh_name) 445 { 446 Elf32_Shdr shrd; 447 char *data; 448 ssize_t size; 449 int64_t off; 450 451 if (-1 == get_section_header (ec, 452 bo, 453 ehdr, 454 strTableOffset, 455 &shrd)) 456 return NULL; 457 if ((shrd.sh_type != SHT_STRTAB) || 458 (shrd.sh_size <= sh_name) ) 459 return NULL; 460 off = ec->seek (ec->cls, 461 shrd.sh_offset, 462 SEEK_SET); 463 if (-1 == off) 464 return NULL; 465 size = ec->read (ec->cls, 466 (void **) &data, 467 shrd.sh_size); 468 if (size < shrd.sh_size) 469 return NULL; 470 if (data[shrd.sh_size - 1] != '\0') 471 return NULL; 472 return strdup (&data[sh_name]); 473 } 474 475 476 #define ADD(s, type) do { \ 477 if (0!=ec->proc (ec->cls, "elf", type, \ 478 EXTRACTOR_METAFORMAT_UTF8, "text/plain", \ 479 s, strlen (s) + 1)) \ 480 { \ 481 return; \ 482 } \ 483 } while (0) 484 485 486 /** 487 * Main entry method for the 'application/x-executable' extraction plugin. 488 * 489 * @param ec extraction context provided to the plugin 490 */ 491 void 492 EXTRACTOR_elf_extract_method (struct EXTRACTOR_ExtractContext *ec) 493 { 494 Elf32_Ehdr ehdr; 495 Elf64_Ehdr ehdr64; 496 int ret; 497 unsigned int bo; 498 char *data; 499 ssize_t size; 500 uint64_t max; 501 size_t want; 502 503 max = ec->get_size (ec->cls); 504 want = sizeof (ehdr); 505 if (sizeof (ehdr64) > want) 506 want = sizeof (ehdr64); 507 want += EI_NIDENT; 508 if (max < want) 509 return; 510 size = ec->read (ec->cls, 511 (void**) &data, 512 max); 513 if (size < EI_NIDENT) 514 return; 515 if (0 != memcmp (data, 516 elfMagic, 517 sizeof (elfMagic))) 518 return; /* not an elf */ 519 switch (data[EI_CLASS]) 520 { 521 case ELFCLASS32: 522 if (size < sizeof (Elf32_Ehdr) + EI_NIDENT) 523 return; 524 bo = get_byte_order (data[EI_DATA]); 525 EXTRACTOR_common_cat_unpack (&data[EI_NIDENT], 526 ELF_HEADER_SPECS[bo], 527 ELF_HEADER_FIELDS (&ehdr)); 528 if (ehdr.e_shoff + ehdr.e_shentsize * ehdr.e_shnum > max) 529 return; /* invalid offsets... */ 530 if (ehdr.e_shentsize < ELF_SECTION_SIZE) 531 return; /* huh? */ 532 if (ehdr.e_phoff + ehdr.e_phensize * ehdr.e_phnum > max) 533 return; 534 ret = 0; 535 bo = get_byte_order (data[EI_DATA]); 536 break; 537 case ELFCLASS64: 538 if (size < sizeof (Elf64_Ehdr) + EI_NIDENT) 539 return; 540 bo = get_byte_order (data[EI_DATA]); 541 EXTRACTOR_common_cat_unpack (&data[EI_NIDENT], 542 ELF64_HEADER_SPECS[bo], 543 ELF64_HEADER_FIELDS (&ehdr64)); 544 if (ehdr64.e_shoff + ((uint32_t) ehdr64.e_shentsize * ehdr64.e_shnum) > 545 max) 546 return; /* invalid offsets... */ 547 if (ehdr64.e_phoff + ((uint32_t) ehdr64.e_phensize * ehdr64.e_phnum) > 548 max) 549 return; 550 bo = get_byte_order (data[EI_DATA]); 551 ret = 1; 552 break; 553 default: 554 return; 555 } 556 557 ADD ("application/x-executable", 558 EXTRACTOR_METATYPE_MIMETYPE); 559 switch ( ((unsigned char*) data)[EI_OSABI]) 560 { 561 case ELFOSABI_LINUX: 562 ADD ("Linux", 563 EXTRACTOR_METATYPE_TARGET_OS); 564 break; 565 case ELFOSABI_FREEBSD: 566 ADD ("FreeBSD", 567 EXTRACTOR_METATYPE_TARGET_OS); 568 break; 569 case ELFOSABI_NETBSD: 570 ADD ("NetBSD", 571 EXTRACTOR_METATYPE_TARGET_OS); 572 break; 573 case ELFOSABI_OPENBSD: 574 ADD ("OpenBSD", 575 EXTRACTOR_METATYPE_TARGET_OS); 576 break; 577 case ELFOSABI_IRIX: 578 ADD ("IRIX", 579 EXTRACTOR_METATYPE_TARGET_OS); 580 break; 581 default: 582 break; 583 } 584 switch ( (0 == ret) ? ehdr.e_type : ehdr64.e_type) 585 { 586 case ET_REL: 587 ADD ("Relocatable file", 588 EXTRACTOR_METATYPE_RESOURCE_TYPE); 589 break; 590 case ET_EXEC: 591 ADD ("Executable file", 592 EXTRACTOR_METATYPE_RESOURCE_TYPE); 593 break; 594 case ET_DYN: 595 ADD ("Shared object file", 596 EXTRACTOR_METATYPE_RESOURCE_TYPE); 597 break; 598 case ET_CORE: 599 ADD ("Core file", 600 EXTRACTOR_METATYPE_RESOURCE_TYPE); 601 break; 602 default: 603 break; /* unknown */ 604 } 605 switch ( (0 == ret) ? ehdr.e_machine : ehdr64.e_machine) 606 { 607 case EM_M32: 608 ADD ("M32", 609 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 610 break; 611 case EM_386: 612 ADD ("i386", 613 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 614 break; 615 case EM_68K: 616 ADD ("68K", 617 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 618 break; 619 case EM_88K: 620 ADD ("88K", 621 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 622 break; 623 case EM_SPARC: 624 ADD ("Sparc", 625 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 626 break; 627 case EM_860: 628 ADD ("960", 629 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 630 break; 631 case EM_MIPS: 632 ADD ("MIPS", 633 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 634 break; 635 case EM_PPC: 636 ADD ("PPC", 637 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 638 break; 639 case EM_PPC64: 640 ADD ("PPC64", 641 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 642 break; 643 case EM_S390: 644 ADD ("S390", 645 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 646 break; 647 case EM_ARM: 648 ADD ("ARM", 649 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 650 break; 651 case EM_ALPHA: 652 ADD ("ALPHA", 653 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 654 break; 655 case EM_IA_64: 656 ADD ("IA-64", 657 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 658 break; 659 case EM_X86_64: 660 ADD ("x86_64", 661 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 662 break; 663 case EM_CUDA: 664 ADD ("NVIDIA CUDA", 665 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 666 break; 667 default: 668 break; /* oops */ 669 } 670 671 if (0 != ret) 672 return; /* FIXME: full support for 64-bit ELF... */ 673 for (Elf32_Half idx = 0; idx < ehdr.e_phnum; idx++) 674 { 675 Elf32_Phdr phdr; 676 677 if (0 != getProgramHdr (ec, 678 bo, 679 &ehdr, 680 idx, 681 &phdr)) 682 return; 683 if (phdr.p_type == PT_DYNAMIC) 684 { 685 unsigned int dc = phdr.p_filesz / ELF_DYN_SIZE; 686 Elf32_Addr stringPtr; 687 Elf32_Half stringIdx; 688 Elf32_Half six; 689 690 stringPtr = 0; 691 for (unsigned int id = 0; id < dc; id++) 692 { 693 Elf32_Dyn dyn; 694 695 if (0 != getDynTag (ec, 696 bo, 697 &ehdr, 698 phdr.p_offset, 699 phdr.p_filesz, 700 id, 701 &dyn)) 702 return; 703 if (DT_STRTAB == dyn.d_tag) 704 { 705 stringPtr = dyn.d_un.d_ptr; 706 break; 707 } 708 } 709 if (0 == stringPtr) 710 return; 711 for (six = 0; six < ehdr.e_shnum; six++) 712 { 713 Elf32_Shdr sec; 714 715 if (-1 == get_section_header (ec, 716 bo, 717 &ehdr, 718 six, 719 &sec)) 720 return; 721 if ( (sec.sh_addr == stringPtr) && 722 (sec.sh_type == SHT_STRTAB) ) 723 { 724 stringIdx = six; 725 break; 726 } 727 } 728 if (six == ehdr.e_shnum) 729 return; /* stringIdx not found */ 730 731 for (unsigned int id = 0; id < dc; id++) 732 { 733 Elf32_Dyn dyn; 734 735 if (0 != getDynTag (ec, 736 bo, 737 &ehdr, 738 phdr.p_offset, 739 phdr.p_filesz, 740 id, 741 &dyn)) 742 return; 743 switch (dyn.d_tag) 744 { 745 case DT_RPATH: 746 { 747 char *rpath; 748 749 rpath = readStringTable (ec, 750 bo, 751 &ehdr, 752 stringIdx, 753 dyn.d_un.d_val); 754 /* "source" of the dependencies: path 755 to dynamic libraries */ 756 if (NULL != rpath) 757 { 758 ADD (rpath, 759 EXTRACTOR_METATYPE_LIBRARY_SEARCH_PATH); 760 free (rpath); 761 } 762 break; 763 } 764 case DT_NEEDED: 765 { 766 char *needed; 767 768 needed = readStringTable (ec, 769 bo, 770 &ehdr, 771 stringIdx, 772 dyn.d_un.d_val); 773 if (NULL != needed) 774 { 775 ADD (needed, 776 EXTRACTOR_METATYPE_LIBRARY_DEPENDENCY); 777 free (needed); 778 } 779 break; 780 } 781 } 782 } 783 } 784 } 785 } 786 787 788 /* end of elf_extractor.c */