summaryrefslogtreecommitdiff
path: root/utils/readsoname2.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/readsoname2.c')
-rw-r--r--utils/readsoname2.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/utils/readsoname2.c b/utils/readsoname2.c
index 1bf47b7c6..9452c0c4d 100644
--- a/utils/readsoname2.c
+++ b/utils/readsoname2.c
@@ -26,7 +26,7 @@ char *readsonameXX(char *name, FILE *infile, int expected_type, int *type)
if (fstat(fileno(infile), &st))
return NULL;
- header = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fileno(infile), 0);
+ header = mmap(0, st.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(infile), 0);
if (header == (caddr_t)-1)
return NULL;
@@ -34,6 +34,19 @@ char *readsonameXX(char *name, FILE *infile, int expected_type, int *type)
if ((char *)(epnt+1) > (char *)(header + st.st_size))
goto skip;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ byteswap = (epnt->e_ident[5] == ELFDATA2MSB) ? 1 : 0;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ byteswap = (epnt->e_ident[5] == ELFDATA2LSB) ? 1 : 0;
+#else
+#error Unknown host byte order!
+#endif
+ /* Be very lazy, and only byteswap the stuff we use */
+ if (byteswap==1) {
+ epnt->e_phoff=bswap_32(epnt->e_phoff);
+ epnt->e_phnum=bswap_16(epnt->e_phnum);
+ }
+
ppnt = (ElfW(Phdr) *)&header[epnt->e_phoff];
if ((char *)ppnt < (char *)header ||
(char *)(ppnt+epnt->e_phnum) > (char *)(header + st.st_size))
@@ -41,6 +54,14 @@ char *readsonameXX(char *name, FILE *infile, int expected_type, int *type)
for(i = 0; i < epnt->e_phnum; i++)
{
+ /* Be very lazy, and only byteswap the stuff we use */
+ if (byteswap==1) {
+ ppnt->p_type=bswap_32(ppnt->p_type);
+ ppnt->p_vaddr=bswap_32(ppnt->p_vaddr);
+ ppnt->p_offset=bswap_32(ppnt->p_offset);
+ ppnt->p_filesz=bswap_32(ppnt->p_filesz);
+ }
+
if (loadaddr == -1 && ppnt->p_type == PT_LOAD)
loadaddr = (ppnt->p_vaddr & ~(page_size-1)) -
(ppnt->p_offset & ~(page_size-1));
@@ -58,11 +79,20 @@ char *readsonameXX(char *name, FILE *infile, int expected_type, int *type)
(char *)(dpnt+dynamic_size) > (char *)(header + st.st_size))
goto skip;
+ if (byteswap==1) {
+ dpnt->d_tag=bswap_32(dpnt->d_tag);
+ dpnt->d_un.d_val=bswap_32(dpnt->d_un.d_val);
+ }
+
while (dpnt->d_tag != DT_NULL)
{
if (dpnt->d_tag == DT_STRTAB)
strtab_val = dpnt->d_un.d_val;
dpnt++;
+ if (byteswap==1) {
+ dpnt->d_tag=bswap_32(dpnt->d_tag);
+ dpnt->d_un.d_val=bswap_32(dpnt->d_un.d_val);
+ }
};
if (!strtab_val)