aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/elf_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/elf_extractor.c')
-rw-r--r--src/plugins/elf_extractor.c802
1 files changed, 802 insertions, 0 deletions
diff --git a/src/plugins/elf_extractor.c b/src/plugins/elf_extractor.c
new file mode 100644
index 0000000..379f615
--- /dev/null
+++ b/src/plugins/elf_extractor.c
@@ -0,0 +1,802 @@
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/gif_extractor.c
22 * @brief plugin to support GIF files
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "extractor.h"
27#include "pack.h"
28#include <stdint.h>
29
30
31typedef uint32_t Elf32_Addr;
32typedef uint16_t Elf32_Half;
33typedef uint32_t Elf32_Off;
34typedef int32_t Elf32_Sword;
35typedef uint32_t Elf32_Word;
36
37typedef uint16_t Elf64_Half;
38typedef uint32_t Elf64_Word;
39typedef uint64_t Elf64_Addr;
40typedef uint64_t Elf64_Off;
41
42/* first 4 bytes of the ELF header */
43static 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
51typedef 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
85static char *ELF_HEADER_SPECS[] = {
86 "hhwwwwwhhhhhh",
87 "HHWWWWWHHHHHH",
88};
89
90typedef 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
124static char *ELF64_HEADER_SPECS[] = {
125 "hhwxxxwhhhhhh",
126 "HHWXXXWHHHHHH",
127};
128
129
130typedef 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
156static char *ELF_SECTION_SPECS[] = {
157 "wwwwwwwwww",
158 "WWWWWWWWWW",
159};
160
161typedef 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
182static char *ELF_PHDR_SPECS[] = {
183 "wwwwwwww",
184 "WWWWWWWW",
185};
186
187typedef 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
200static 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 1 if we need to convert, 0 if not
314 */
315static int
316getByteorder (char ei_data)
317{
318 if (ei_data == ELFDATA2LSB)
319 {
320#if __BYTE_ORDER == __BIG_ENDIAN
321 return 1;
322#else
323 return 0;
324#endif
325 }
326 else
327 {
328#if __BYTE_ORDER == __BIG_ENDIAN
329 return 0;
330#else
331 return 1;
332#endif
333 }
334}
335
336
337/**
338 *
339 * @return 0 on success, -1 on error
340 */
341static int
342getSectionHdr (struct EXTRACTOR_ExtractContext *ec,
343 unsigned int bo,
344 const Elf32_Ehdr *ehdr,
345 Elf32_Half idx,
346 Elf32_Shdr *ret)
347{
348 ssize_t size;
349 uint64_t max;
350 int64_t off;
351 void *data;
352
353 if (ehdr->e_shnum <= idx)
354 return -1;
355 max = ec->get_size (ec->cls);
356 if (ehdr->e_shoff + ehdr->e_shentsize * idx + sizeof (*ret) > max)
357 return -1;
358 off = ec->seek (ec->cls,
359 ehdr->e_shoff + ehdr->e_shentsize * idx,
360 SEEK_SET);
361 if (-1 == off)
362 return -1;
363 size = ec->read (ec->cls,
364 &data,
365 sizeof (*ret));
366 if (size < sizeof (*ret))
367 return -1;
368 EXTRACTOR_common_cat_unpack (data,
369 ELF_SECTION_SPECS[bo],
370 ELF_SECTION_FIELDS (ret));
371 return 0;
372}
373
374
375/**
376 *
377 * @return 0 on success, -1 on error
378 */
379static int
380getDynTag (struct EXTRACTOR_ExtractContext *ec,
381 unsigned int bo,
382 const Elf32_Ehdr *ehdr,
383 Elf32_Off off,
384 Elf32_Word osize,
385 unsigned int idx,
386 Elf32_Dyn *ret)
387{
388 ssize_t size;
389 uint64_t max;
390 int64_t soff;
391 void *data;
392
393 max = ec->get_size (ec->cls);
394 if ( (off + osize > max) ||
395 ((idx + 1) * ELF_DYN_SIZE > osize) )
396 return -1;
397 if (off + idx * ELF_DYN_SIZE + sizeof (*ret) > max)
398 return -1;
399 soff = ec->seek (ec->cls,
400 off + idx * ELF_DYN_SIZE,
401 SEEK_SET);
402 if (-1 == soff)
403 return -1;
404 size = ec->read (ec->cls,
405 &data,
406 sizeof (*ret));
407 if (size < sizeof (*ret))
408 return -1;
409 EXTRACTOR_common_cat_unpack (data,
410 ELF_DYN_SPECS[bo],
411 ELF_DYN_FIELDS (ret));
412 return 0;
413}
414
415
416/**
417 *
418 * @return 0 on success, -1 on error
419 */
420static int
421getProgramHdr (struct EXTRACTOR_ExtractContext *ec,
422 unsigned int bo,
423 const Elf32_Ehdr *ehdr,
424 Elf32_Half idx,
425 Elf32_Phdr *ret)
426{
427 void *data;
428 ssize_t size;
429 int64_t off;
430
431 if (ehdr->e_phnum <= idx)
432 return -1;
433 off = ec->seek (ec->cls,
434 ehdr->e_phoff + ehdr->e_phensize * idx,
435 SEEK_SET);
436 if (-1 == off)
437 return -1;
438 size = ec->read (ec->cls,
439 &data,
440 sizeof (*ret));
441 if (size < sizeof (*ret))
442 return -1;
443 EXTRACTOR_common_cat_unpack (data,
444 ELF_PHDR_SPECS[bo],
445 ELF_PHDR_FIELDS (ret));
446 return 0;
447}
448
449
450/**
451 * @return the string (offset into data, do NOT free), NULL on error
452 */
453static char *
454readStringTable (struct EXTRACTOR_ExtractContext *ec,
455 unsigned int bo,
456 const Elf32_Ehdr *ehdr,
457 Elf32_Half strTableOffset,
458 Elf32_Word sh_name)
459{
460 Elf32_Shdr shrd;
461 char *data;
462 ssize_t size;
463 int64_t off;
464
465 if (-1 == getSectionHdr (ec,
466 bo,
467 ehdr,
468 strTableOffset,
469 &shrd))
470 return NULL;
471 if ((shrd.sh_type != SHT_STRTAB) ||
472 (shrd.sh_size <= sh_name) )
473 return NULL;
474 off = ec->seek (ec->cls,
475 shrd.sh_offset,
476 SEEK_SET);
477 if (-1 == off)
478 return NULL;
479 size = ec->read (ec->cls,
480 (void **) &data,
481 shrd.sh_size);
482 if (size < shrd.sh_size)
483 return NULL;
484 if (data[shrd.sh_size - 1] != '\0')
485 return NULL;
486 return strdup (&data[sh_name]);
487}
488
489
490#define ADD(s, type) do { \
491 if (0!=ec->proc (ec->cls, "elf", type, \
492 EXTRACTOR_METAFORMAT_UTF8, "text/plain", \
493 s, strlen (s) + 1)) \
494 { \
495 return; \
496 } \
497} while (0)
498
499
500/**
501 * Main entry method for the 'application/x-executable' extraction plugin.
502 *
503 * @param ec extraction context provided to the plugin
504 */
505void
506EXTRACTOR_elf_extract_method (struct EXTRACTOR_ExtractContext *ec)
507{
508 Elf32_Ehdr ehdr;
509 Elf64_Ehdr ehdr64;
510 int ret;
511 unsigned int bo;
512 char *data;
513 ssize_t size;
514 uint64_t max;
515 size_t want;
516
517 max = ec->get_size (ec->cls);
518 want = sizeof (ehdr);
519 if (sizeof (ehdr64) > want)
520 want = sizeof (ehdr64);
521 want += EI_NIDENT;
522 if (max < want)
523 return;
524 size = ec->read (ec->cls,
525 (void**) &data,
526 max);
527 if (size < EI_NIDENT)
528 return;
529 if (0 != memcmp (data,
530 elfMagic,
531 sizeof (elfMagic)))
532 return; /* not an elf */
533 switch (data[EI_CLASS])
534 {
535 case ELFCLASS32:
536 if (size < sizeof (Elf32_Ehdr) + EI_NIDENT)
537 return;
538 bo = getByteorder (data[EI_DATA]);
539 EXTRACTOR_common_cat_unpack (&data[EI_NIDENT],
540 ELF_HEADER_SPECS[bo],
541 ELF_HEADER_FIELDS (&ehdr));
542 if (ehdr.e_shoff + ehdr.e_shentsize * ehdr.e_shnum > max)
543 return; /* invalid offsets... */
544 if (ehdr.e_shentsize < ELF_SECTION_SIZE)
545 return; /* huh? */
546 if (ehdr.e_phoff + ehdr.e_phensize * ehdr.e_phnum > max)
547 return;
548 ret = 0;
549 bo = getByteorder (data[EI_CLASS]);
550 break;
551 case ELFCLASS64:
552 if (size < sizeof (Elf64_Ehdr) + EI_NIDENT)
553 return;
554 bo = getByteorder (data[EI_DATA]);
555 EXTRACTOR_common_cat_unpack (&data[EI_NIDENT],
556 ELF64_HEADER_SPECS[bo],
557 ELF64_HEADER_FIELDS (&ehdr64));
558 if (ehdr64.e_shoff + ((uint32_t) ehdr64.e_shentsize * ehdr64.e_shnum) >
559 max)
560 return; /* invalid offsets... */
561 if (ehdr64.e_phoff + ((uint32_t) ehdr64.e_phensize * ehdr64.e_phnum) >
562 max)
563 return;
564 bo = getByteorder (data[EI_CLASS]);
565 ret = 1;
566 break;
567 default:
568 return;
569 }
570
571 ADD ("application/x-executable",
572 EXTRACTOR_METATYPE_MIMETYPE);
573 switch ( ((unsigned char*) data)[EI_OSABI])
574 {
575 case ELFOSABI_LINUX:
576 ADD ("Linux",
577 EXTRACTOR_METATYPE_TARGET_OS);
578 break;
579 case ELFOSABI_FREEBSD:
580 ADD ("FreeBSD",
581 EXTRACTOR_METATYPE_TARGET_OS);
582 break;
583 case ELFOSABI_NETBSD:
584 ADD ("NetBSD",
585 EXTRACTOR_METATYPE_TARGET_OS);
586 break;
587 case ELFOSABI_OPENBSD:
588 ADD ("OpenBSD",
589 EXTRACTOR_METATYPE_TARGET_OS);
590 break;
591 case ELFOSABI_IRIX:
592 ADD ("IRIX",
593 EXTRACTOR_METATYPE_TARGET_OS);
594 break;
595 default:
596 break;
597 }
598 switch ( (0 == ret) ? ehdr.e_type : ehdr64.e_type)
599 {
600 case ET_REL:
601 ADD ("Relocatable file",
602 EXTRACTOR_METATYPE_RESOURCE_TYPE);
603 break;
604 case ET_EXEC:
605 ADD ("Executable file",
606 EXTRACTOR_METATYPE_RESOURCE_TYPE);
607 break;
608 case ET_DYN:
609 ADD ("Shared object file",
610 EXTRACTOR_METATYPE_RESOURCE_TYPE);
611 break;
612 case ET_CORE:
613 ADD ("Core file",
614 EXTRACTOR_METATYPE_RESOURCE_TYPE);
615 break;
616 default:
617 break; /* unknown */
618 }
619 switch ( (0 == ret) ? ehdr.e_machine : ehdr64.e_machine)
620 {
621 case EM_M32:
622 ADD ("M32",
623 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
624 break;
625 case EM_386:
626 ADD ("i386",
627 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
628 break;
629 case EM_68K:
630 ADD ("68K",
631 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
632 break;
633 case EM_88K:
634 ADD ("88K",
635 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
636 break;
637 case EM_SPARC:
638 ADD ("Sparc",
639 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
640 break;
641 case EM_860:
642 ADD ("960",
643 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
644 break;
645 case EM_MIPS:
646 ADD ("MIPS",
647 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
648 break;
649 case EM_PPC:
650 ADD ("PPC",
651 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
652 break;
653 case EM_PPC64:
654 ADD ("PPC64",
655 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
656 break;
657 case EM_S390:
658 ADD ("S390",
659 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
660 break;
661 case EM_ARM:
662 ADD ("ARM",
663 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
664 break;
665 case EM_ALPHA:
666 ADD ("ALPHA",
667 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
668 break;
669 case EM_IA_64:
670 ADD ("IA-64",
671 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
672 break;
673 case EM_X86_64:
674 ADD ("x86_64",
675 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
676 break;
677 case EM_CUDA:
678 ADD ("NVIDIA CUDA",
679 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
680 break;
681 default:
682 break; /* oops */
683 }
684
685 if (0 != ret)
686 return; /* FIXME: full support for 64-bit ELF... */
687 for (Elf32_Half idx = 0; idx < ehdr.e_phnum; idx++)
688 {
689 Elf32_Phdr phdr;
690
691 if (0 != getProgramHdr (ec,
692 bo,
693 &ehdr,
694 idx,
695 &phdr))
696 return;
697 if (phdr.p_type == PT_DYNAMIC)
698 {
699 unsigned int dc = phdr.p_filesz / ELF_DYN_SIZE;
700 Elf32_Addr stringPtr;
701 Elf32_Half stringIdx;
702 Elf32_Half six;
703
704 stringPtr = 0;
705 for (unsigned int id = 0; id < dc; id++)
706 {
707 Elf32_Dyn dyn;
708
709 if (0 != getDynTag (ec,
710 bo,
711 &ehdr,
712 phdr.p_offset,
713 phdr.p_filesz,
714 id,
715 &dyn))
716 return;
717 if (DT_STRTAB == dyn.d_tag)
718 {
719 stringPtr = dyn.d_un.d_ptr;
720 break;
721 }
722 }
723 if (0 == stringPtr)
724 return;
725 for (six = 0; six < ehdr.e_shnum; six++)
726 {
727 Elf32_Shdr sec;
728
729 if (-1 == getSectionHdr (ec,
730 bo,
731 &ehdr,
732 six,
733 &sec))
734 return;
735 if ( (sec.sh_addr == stringPtr) &&
736 (sec.sh_type == SHT_STRTAB) )
737 {
738 stringIdx = six;
739 break;
740 }
741 }
742 if (six == ehdr.e_shnum)
743 return; /* stringIdx not found */
744
745 for (unsigned int id = 0; id < dc; id++)
746 {
747 Elf32_Dyn dyn;
748
749 if (0 != getDynTag (ec,
750 bo,
751 &ehdr,
752 phdr.p_offset,
753 phdr.p_filesz,
754 id,
755 &dyn))
756 return;
757 switch (dyn.d_tag)
758 {
759 case DT_RPATH:
760 {
761 char *rpath;
762
763 rpath = readStringTable (ec,
764 bo,
765 &ehdr,
766 stringIdx,
767 dyn.d_un.d_val);
768 /* "source" of the dependencies: path
769 to dynamic libraries */
770 if (NULL != rpath)
771 {
772 ADD (rpath,
773 EXTRACTOR_METATYPE_LIBRARY_SEARCH_PATH);
774 free (rpath);
775 }
776 break;
777 }
778 case DT_NEEDED:
779 {
780 char *needed;
781
782 needed = readStringTable (ec,
783 bo,
784 &ehdr,
785 stringIdx,
786 dyn.d_un.d_val);
787 if (NULL != needed)
788 {
789 ADD (needed,
790 EXTRACTOR_METATYPE_LIBRARY_DEPENDENCY);
791 free (needed);
792 }
793 break;
794 }
795 }
796 }
797 }
798 }
799}
800
801
802/* end of gif_extractor.c */