1 static char *readsonameXX(char *name
, FILE *infile
, int expected_type
, int *type
)
7 ElfW(Addr
) dynamic_addr
= 0;
8 ElfW(Addr
) dynamic_size
= 0;
9 unsigned long page_size
= getpagesize();
10 ElfW(Addr
) strtab_val
= 0;
11 ElfW(Addr
) needed_val
;
12 ElfW(Addr
) loadaddr
= -1;
19 if (expected_type
== LIB_DLL
) {
20 warn("%s does not match type specified for directory!", name
);
21 expected_type
= LIB_ANY
;
26 if (fstat(fileno(infile
), &st
))
29 mmap(0, st
.st_size
, PROT_READ
| PROT_WRITE
, MAP_PRIVATE
,
31 if (header
== (caddr_t
) - 1)
34 epnt
= (ElfW(Ehdr
) *) header
;
35 if ((char *)(epnt
+ 1) > (char *)(header
+ st
.st_size
))
38 if (UCLIBC_ENDIAN_HOST
== UCLIBC_ENDIAN_LITTLE
)
39 byteswap
= (epnt
->e_ident
[5] == ELFDATA2MSB
) ? 1 : 0;
40 else if (UCLIBC_ENDIAN_HOST
== UCLIBC_ENDIAN_BIG
)
41 byteswap
= (epnt
->e_ident
[5] == ELFDATA2LSB
) ? 1 : 0;
43 /* Be very lazy, and only byteswap the stuff we use */
45 epnt
->e_phoff
= bswap_32(epnt
->e_phoff
);
46 epnt
->e_phnum
= bswap_16(epnt
->e_phnum
);
49 ppnt
= (ElfW(Phdr
) *) & header
[epnt
->e_phoff
];
50 if ((char *)ppnt
< (char *)header
||
51 (char *)(ppnt
+ epnt
->e_phnum
) > (char *)(header
+ st
.st_size
))
54 for (i
= 0; i
< epnt
->e_phnum
; i
++) {
55 /* Be very lazy, and only byteswap the stuff we use */
57 ppnt
->p_type
= bswap_32(ppnt
->p_type
);
58 ppnt
->p_vaddr
= bswap_32(ppnt
->p_vaddr
);
59 ppnt
->p_offset
= bswap_32(ppnt
->p_offset
);
60 ppnt
->p_filesz
= bswap_32(ppnt
->p_filesz
);
63 if (loadaddr
== (ElfW(Addr
)) - 1 && ppnt
->p_type
== PT_LOAD
)
64 loadaddr
= (ppnt
->p_vaddr
& ~(page_size
- 1)) -
65 (ppnt
->p_offset
& ~(page_size
- 1));
66 if (ppnt
->p_type
== 2) {
67 dynamic_addr
= ppnt
->p_offset
;
68 dynamic_size
= ppnt
->p_filesz
;
73 dpnt
= (ElfW(Dyn
) *) & header
[dynamic_addr
];
74 dynamic_size
= dynamic_size
/ sizeof(ElfW(Dyn
));
75 if ((char *)dpnt
< (char *)header
||
76 (char *)(dpnt
+ dynamic_size
) > (char *)(header
+ st
.st_size
))
80 dpnt
->d_tag
= bswap_32(dpnt
->d_tag
);
81 dpnt
->d_un
.d_val
= bswap_32(dpnt
->d_un
.d_val
);
84 while (dpnt
->d_tag
!= DT_NULL
) {
85 if (dpnt
->d_tag
== DT_STRTAB
)
86 strtab_val
= dpnt
->d_un
.d_val
;
89 dpnt
->d_tag
= bswap_32(dpnt
->d_tag
);
90 dpnt
->d_un
.d_val
= bswap_32(dpnt
->d_un
.d_val
);
97 dpnt
= (ElfW(Dyn
) *) & header
[dynamic_addr
];
98 while (dpnt
->d_tag
!= DT_NULL
) {
99 if (dpnt
->d_tag
== DT_SONAME
|| dpnt
->d_tag
== DT_NEEDED
) {
100 needed_val
= dpnt
->d_un
.d_val
;
101 if (needed_val
+ strtab_val
>= loadaddr
||
102 needed_val
+ strtab_val
< st
.st_size
- loadaddr
) {
104 (char *)(header
- loadaddr
+ strtab_val
+
107 if (dpnt
->d_tag
== DT_SONAME
)
108 soname
= xstrdup(needed
);
110 for (j
= 0; needed_tab
[j
].soname
!= NULL
; j
++) {
111 if (strcmp(needed
, needed_tab
[j
].soname
)
117 *type
= needed_tab
[j
].type
;
126 warn("%s appears to be for multiple libc's", name
);
128 /* If we could not deduce the libc type, and we know what to expect, set the type */
129 if (*type
== LIB_ELF
&& expected_type
!= LIB_ANY
)
130 *type
= expected_type
;
132 if (expected_type
!= LIB_ANY
&& expected_type
!= LIB_ELF
&&
133 expected_type
!= *type
) {
134 warn("%s does not match type specified for directory!", name
);
138 munmap(header
, st
.st_size
);