diff options
Diffstat (limited to 'utils/readsoname2.c')
-rw-r--r-- | utils/readsoname2.c | 32 |
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) |