diff options
author | marcel <marcel@FreeBSD.org> | 2003-08-09 01:55:37 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2003-08-09 01:55:37 +0000 |
commit | 892df4d6175d0656bd4d556877ab6efbad2cbbfb (patch) | |
tree | af8928f210eec94c1bb39dc17efe70eb0abfcd89 | |
parent | e97bb1421920a22ac8b48f7024258ad83b332821 (diff) | |
download | FreeBSD-src-892df4d6175d0656bd4d556877ab6efbad2cbbfb.zip FreeBSD-src-892df4d6175d0656bd4d556877ab6efbad2cbbfb.tar.gz |
Fix sign-extension bug for 32 and 64-bit values. For 64-bit values
this involves the sign-extension of the high and low "word". Both
of which are 32-bit. The bug is especially harmful on ia64, where
0x9fffffffe0000000 is a common address (base of register stack).
This was invariably displayed as 0xffffffffe0000000.
The sign-extension is fixed by using {b|l}e{16|32|64}dec() where
applicable. Since elfdump(1) is not a bootstrap tool, dependency
on these functions is not a problem.
-rw-r--r-- | usr.bin/elfdump/elfdump.c | 66 |
1 files changed, 27 insertions, 39 deletions
diff --git a/usr.bin/elfdump/elfdump.c b/usr.bin/elfdump/elfdump.c index 89b24e9..d4a53ad 100644 --- a/usr.bin/elfdump/elfdump.c +++ b/usr.bin/elfdump/elfdump.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> #include <sys/elf32.h> #include <sys/elf64.h> +#include <sys/endian.h> #include <sys/mman.h> #include <sys/stat.h> #include <err.h> @@ -917,17 +918,14 @@ u_int64_t elf_get_byte(Elf32_Ehdr *e, void *base, elf_member_t member) { u_int64_t val; - u_char *p; val = 0; switch (e->e_ident[EI_CLASS]) { case ELFCLASS32: - p = (char *)base + elf32_offsets[member]; - val = *p; + val = ((char *)base)[elf32_offsets[member]]; break; case ELFCLASS64: - p = (char *)base + elf64_offsets[member]; - val = *p; + val = ((char *)base)[elf64_offsets[member]]; break; case ELFCLASSNONE: errx(1, "invalid class"); @@ -940,31 +938,30 @@ u_int64_t elf_get_quarter(Elf32_Ehdr *e, void *base, elf_member_t member) { u_int64_t val; - u_char *p; val = 0; switch (e->e_ident[EI_CLASS]) { case ELFCLASS32: - p = (char *)base + elf32_offsets[member]; + base = (char *)base + elf32_offsets[member]; switch (e->e_ident[EI_DATA]) { case ELFDATA2MSB: - val = p[0] << 8 | p[1]; + val = be16dec(base); break; case ELFDATA2LSB: - val = p[1] << 8 | p[0]; + val = le16dec(base); break; case ELFDATANONE: errx(1, "invalid data format"); } break; case ELFCLASS64: - p = (char *)base + elf64_offsets[member]; + base = (char *)base + elf64_offsets[member]; switch (e->e_ident[EI_DATA]) { case ELFDATA2MSB: - val = p[0] << 8 | p[1]; + val = be16dec(base); break; case ELFDATA2LSB: - val = p[1] << 8 | p[0]; + val = le16dec(base); break; case ELFDATANONE: errx(1, "invalid data format"); @@ -981,31 +978,30 @@ u_int64_t elf_get_half(Elf32_Ehdr *e, void *base, elf_member_t member) { u_int64_t val; - u_char *p; val = 0; switch (e->e_ident[EI_CLASS]) { case ELFCLASS32: - p = (char *)base + elf32_offsets[member]; + base = (char *)base + elf32_offsets[member]; switch (e->e_ident[EI_DATA]) { case ELFDATA2MSB: - val = p[0] << 8 | p[1]; + val = be16dec(base); break; case ELFDATA2LSB: - val = p[1] << 8 | p[0]; + val = le16dec(base); break; case ELFDATANONE: errx(1, "invalid data format"); } break; case ELFCLASS64: - p = (char *)base + elf64_offsets[member]; + base = (char *)base + elf64_offsets[member]; switch (e->e_ident[EI_DATA]) { case ELFDATA2MSB: - val = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; + val = be32dec(base); break; case ELFDATA2LSB: - val = p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]; + val = le32dec(base); break; case ELFDATANONE: errx(1, "invalid data format"); @@ -1022,31 +1018,30 @@ u_int64_t elf_get_word(Elf32_Ehdr *e, void *base, elf_member_t member) { u_int64_t val; - u_char *p; val = 0; switch (e->e_ident[EI_CLASS]) { case ELFCLASS32: - p = (char *)base + elf32_offsets[member]; + base = (char *)base + elf32_offsets[member]; switch (e->e_ident[EI_DATA]) { case ELFDATA2MSB: - val = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; + val = be32dec(base); break; case ELFDATA2LSB: - val = p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]; + val = le32dec(base); break; case ELFDATANONE: errx(1, "invalid data format"); } break; case ELFCLASS64: - p = (char *)base + elf64_offsets[member]; + base = (char *)base + elf64_offsets[member]; switch (e->e_ident[EI_DATA]) { case ELFDATA2MSB: - val = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; + val = be32dec(base); break; case ELFDATA2LSB: - val = p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]; + val = le32dec(base); break; case ELFDATANONE: errx(1, "invalid data format"); @@ -1062,38 +1057,31 @@ elf_get_word(Elf32_Ehdr *e, void *base, elf_member_t member) u_int64_t elf_get_quad(Elf32_Ehdr *e, void *base, elf_member_t member) { - u_int64_t high; - u_int64_t low; u_int64_t val; - u_char *p; val = 0; switch (e->e_ident[EI_CLASS]) { case ELFCLASS32: - p = (char *)base + elf32_offsets[member]; + base = (char *)base + elf32_offsets[member]; switch (e->e_ident[EI_DATA]) { case ELFDATA2MSB: - val = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; + val = be32dec(base); break; case ELFDATA2LSB: - val = p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]; + val = le32dec(base); break; case ELFDATANONE: errx(1, "invalid data format"); } break; case ELFCLASS64: - p = (char *)base + elf64_offsets[member]; + base = (char *)base + elf64_offsets[member]; switch (e->e_ident[EI_DATA]) { case ELFDATA2MSB: - high = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; - low = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7]; - val = high << 32 | low; + val = be64dec(base); break; case ELFDATA2LSB: - high = p[7] << 24 | p[6] << 16 | p[5] << 8 | p[4]; - low = p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]; - val = high << 32 | low; + val = le64dec(base); break; case ELFDATANONE: errx(1, "invalid data format"); |