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.
This commit is contained in:
Marcel Moolenaar 2003-08-09 01:55:37 +00:00
parent 6098c5e1a2
commit ac2ded1df3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=118680

View file

@ -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");