#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.93 2012/10/31 17:03:41 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.94 2012/12/13 13:48:31 christos Exp $")
#endif
#ifdef BUILTIN_ELF
private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
off_t, int *, int);
private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
- off_t, int *, int);
+ off_t, int *, int, int);
private size_t donote(struct magic_set *, void *, size_t, size_t, int,
int, size_t, int *);
#define elf_getu32(swap, value) getu32(swap, value)
#ifdef USE_ARRAY_FOR_64BIT_TYPES
# define elf_getu64(swap, array) \
- ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \
- (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32)))
+ ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 \
+ : elf_getu32(swap, array[0])) + \
+ (swap ? elf_getu32(swap, array[1]) : \
+ ((uint64_t)elf_getu32(swap, array[1]) << 32)))
#else
# define elf_getu64(swap, value) getu64(swap, value)
#endif
#define xsh_addr (clazz == ELFCLASS32 \
- ? (void *) &sh32 \
- : (void *) &sh64)
+ ? (void *)&sh32 \
+ : (void *)&sh64)
#define xsh_sizeof (clazz == ELFCLASS32 \
- ? sizeof sh32 \
- : sizeof sh64)
-#define xsh_size (clazz == ELFCLASS32 \
+ ? sizeof(sh32) \
+ : sizeof(sh64))
+#define xsh_size (size_t)(clazz == ELFCLASS32 \
? elf_getu32(swap, sh32.sh_size) \
: elf_getu64(swap, sh64.sh_size))
#define xsh_offset (off_t)(clazz == ELFCLASS32 \
#define xsh_type (clazz == ELFCLASS32 \
? elf_getu32(swap, sh32.sh_type) \
: elf_getu32(swap, sh64.sh_type))
+#define xsh_name (clazz == ELFCLASS32 \
+ ? elf_getu32(swap, sh32.sh_name) \
+ : elf_getu32(swap, sh64.sh_name))
#define xph_addr (clazz == ELFCLASS32 \
? (void *) &ph32 \
: (void *) &ph64)
#define xph_sizeof (clazz == ELFCLASS32 \
- ? sizeof ph32 \
- : sizeof ph64)
+ ? sizeof(ph32) \
+ : sizeof(ph64))
#define xph_type (clazz == ELFCLASS32 \
? elf_getu32(swap, ph32.p_type) \
: elf_getu32(swap, ph64.p_type))
? elf_getu32(swap, ph32.p_filesz) \
: elf_getu64(swap, ph64.p_filesz)))
#define xnh_addr (clazz == ELFCLASS32 \
- ? (void *) &nh32 \
- : (void *) &nh64)
+ ? (void *)&nh32 \
+ : (void *)&nh64)
#define xph_memsz (size_t)((clazz == ELFCLASS32 \
? elf_getu32(swap, ph32.p_memsz) \
: elf_getu64(swap, ph64.p_memsz)))
? prpsoffsets32[i] \
: prpsoffsets64[i])
#define xcap_addr (clazz == ELFCLASS32 \
- ? (void *) &cap32 \
- : (void *) &cap64)
+ ? (void *)&cap32 \
+ : (void *)&cap64)
#define xcap_sizeof (clazz == ELFCLASS32 \
? sizeof cap32 \
: sizeof cap64)
{
Elf32_Phdr ph32;
Elf64_Phdr ph64;
- size_t offset;
+ size_t offset, len;
unsigned char nbuf[BUFSIZ];
ssize_t bufsize;
* Loop through all the program headers.
*/
for ( ; num; num--) {
- if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- if (read(fd, xph_addr, xph_sizeof) == -1) {
+ if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
file_badread(ms);
return -1;
}
* This is a PT_NOTE section; loop through all the notes
* in the section.
*/
- if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- bufsize = read(fd, nbuf,
- ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf)));
- if (bufsize == -1) {
+ len = xph_filesz < sizeof(nbuf) ? xph_filesz : sizeof(nbuf);
+ if ((bufsize = pread(fd, nbuf, len, xph_offset)) == -1) {
file_badread(ms);
return -1;
}
private int
doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
- size_t size, off_t fsize, int *flags, int mach)
+ size_t size, off_t fsize, int *flags, int mach, int strtab)
{
Elf32_Shdr sh32;
Elf64_Shdr sh64;
int stripped = 1;
void *nbuf;
- off_t noff, coff;
+ off_t noff, coff, name_off;
uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
+ char name[50];
if (size != xsh_sizeof) {
if (file_printf(ms, ", corrupted section header size") == -1)
return 0;
}
+ /* Save offset of name section to be able to read section names later */
+ name_off = off * size * strtab;
+ /* Read the name of this section. */
+ if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) {
+ file_badread(ms);
+ return -1;
+ }
+ name[sizeof(name) - 1] = '\0';
+ if (strcmp(name, ".debug_info") == 0)
+ stripped = 0;
+
for ( ; num; num--) {
- if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- if (read(fd, xsh_addr, xsh_sizeof) == -1) {
+ if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) {
file_badread(ms);
return -1;
}
/* Things we can determine when we seek */
switch (xsh_type) {
case SHT_NOTE:
- if ((nbuf = malloc((size_t)xsh_size)) == NULL) {
+ if ((nbuf = malloc(xsh_size)) == NULL) {
file_error(ms, errno, "Cannot allocate memory"
" for note");
return -1;
}
- if ((noff = lseek(fd, (off_t)xsh_offset, SEEK_SET)) ==
- (off_t)-1) {
+ if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) {
file_badread(ms);
free(nbuf);
return -1;
}
- if (read(fd, nbuf, (size_t)xsh_size) !=
- (ssize_t)xsh_size) {
- free(nbuf);
- file_badread(ms);
- return -1;
- }
noff = 0;
for (;;) {
if (noff >= (off_t)xsh_size)
break;
noff = donote(ms, nbuf, (size_t)noff,
- (size_t)xsh_size, clazz, swap, 4,
- flags);
+ xsh_size, clazz, swap, 4, flags);
if (noff == 0)
break;
}
goto skip;
}
- if (lseek(fd, (off_t)xsh_offset, SEEK_SET) ==
- (off_t)-1) {
+ if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
file_badseek(ms);
return -1;
}
const char *shared_libraries = "";
unsigned char nbuf[BUFSIZ];
ssize_t bufsize;
- size_t offset, align;
+ size_t offset, align, len;
if (size != xph_sizeof) {
if (file_printf(ms, ", corrupted program header size") == -1)
}
for ( ; num; num--) {
- if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
-
- if (read(fd, xph_addr, xph_sizeof) == -1) {
- file_badread(ms);
+ if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
+ file_badread(ms);
return -1;
}
* This is a PT_NOTE section; loop through all the notes
* in the section.
*/
- if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- bufsize = read(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ?
- xph_filesz : sizeof(nbuf)));
+ len = xph_filesz < sizeof(nbuf) ? xph_filesz
+ : sizeof(nbuf);
+ bufsize = pread(fd, nbuf, len, xph_offset);
if (bufsize == -1) {
file_badread(ms);
return -1;