]> Git Repo - uclibc-ng.git/blame - utils/readsoname2.c
Remove /usr/X11R6/lib from default list.
[uclibc-ng.git] / utils / readsoname2.c
CommitLineData
66f269d2
EA
1char *readsonameXX(char *name, FILE *infile, int expected_type, int *type)
2{
3 ElfW(Ehdr) *epnt;
4 ElfW(Phdr) *ppnt;
5 int i, j;
6 char *header;
7 ElfW(Word) dynamic_addr = 0;
8 ElfW(Word) dynamic_size = 0;
9 unsigned long page_size = getpagesize();
10 ElfW(Word) strtab_val = 0;
11 ElfW(Word) needed_val;
12 ElfW(Sword) loadaddr = -1;
13 ElfW(Dyn) *dpnt;
14 struct stat st;
15 char *needed;
16 char *soname = NULL;
17 int multi_libcs = 0;
18
19 if(expected_type == LIB_DLL)
20 {
21 warn("%s does not match type specified for directory!", name);
22 expected_type = LIB_ANY;
23 }
24
25 *type = LIB_ELF;
26
27 if (fstat(fileno(infile), &st))
28 return NULL;
29 header = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fileno(infile), 0);
30 if (header == (caddr_t)-1)
31 return NULL;
32
33 epnt = (ElfW(Ehdr) *)header;
34 if ((char *)(epnt+1) > (char *)(header + st.st_size))
35 goto skip;
36
37 ppnt = (ElfW(Phdr) *)&header[epnt->e_phoff];
38 if ((char *)ppnt < (char *)header ||
39 (char *)(ppnt+epnt->e_phnum) > (char *)(header + st.st_size))
40 goto skip;
41
42 for(i = 0; i < epnt->e_phnum; i++)
43 {
44 if (loadaddr == -1 && ppnt->p_type == PT_LOAD)
45 loadaddr = (ppnt->p_vaddr & ~(page_size-1)) -
46 (ppnt->p_offset & ~(page_size-1));
47 if(ppnt->p_type == 2)
48 {
49 dynamic_addr = ppnt->p_offset;
50 dynamic_size = ppnt->p_filesz;
51 };
52 ppnt++;
53 };
54
55 dpnt = (ElfW(Dyn) *) &header[dynamic_addr];
56 dynamic_size = dynamic_size / sizeof(ElfW(Dyn));
57 if ((char *)dpnt < (char *)header ||
58 (char *)(dpnt+dynamic_size) > (char *)(header + st.st_size))
59 goto skip;
60
61 while (dpnt->d_tag != DT_NULL)
62 {
63 if (dpnt->d_tag == DT_STRTAB)
64 strtab_val = dpnt->d_un.d_val;
65 dpnt++;
66 };
67
68 if (!strtab_val)
69 goto skip;
70
71 dpnt = (ElfW(Dyn) *) &header[dynamic_addr];
72 while (dpnt->d_tag != DT_NULL)
73 {
74 if (dpnt->d_tag == DT_SONAME || dpnt->d_tag == DT_NEEDED)
75 {
76 needed_val = dpnt->d_un.d_val;
77 if (needed_val + strtab_val - loadaddr >= 0 ||
78 needed_val + strtab_val - loadaddr < st.st_size)
79 {
80 needed = (char *) (header - loadaddr + strtab_val + needed_val);
81
82 if (dpnt->d_tag == DT_SONAME)
83 soname = xstrdup(needed);
84
85 for (j = 0; needed_tab[j].soname != NULL; j++)
86 {
87 if (strcmp(needed, needed_tab[j].soname) == 0)
88 {
89 if (*type != LIB_ELF && *type != needed_tab[j].type)
90 multi_libcs = 1;
91 *type = needed_tab[j].type;
92 }
93 }
94 }
95 }
96 dpnt++;
97 };
98
99 if (multi_libcs)
100 warn("%s appears to be for multiple libc's", name);
101
102 /* If we could not deduce the libc type, and we know what to expect, set the type */
103 if(*type == LIB_ELF && expected_type != LIB_ANY) *type = expected_type;
104
105 if(expected_type != LIB_ANY && expected_type != LIB_ELF &&
106 expected_type != *type)
107 {
108 warn("%s does not match type specified for directory!", name);
109 }
110
111 skip:
112 munmap(header, st.st_size);
113
114 return soname;
115}
This page took 0.108436 seconds and 4 git commands to generate.