Add 64bit patch.

CVS patchset: 5753
CVS date: 2002/10/06 05:28:21
This commit is contained in:
jbj 2002-10-06 05:28:21 +00:00
parent 00c78bd40c
commit 9ff3ad0cae
2 changed files with 269 additions and 34 deletions

View File

@ -24,38 +24,168 @@ typedef struct {
} UnstripInfo32;
typedef struct {
Elf32_Off orig_e_shoff;
Elf32_Off n_sections;
Elf64_Off orig_e_shoff;
Elf64_Off n_sections;
UnstripInfoSection64 sections[1];
} UnstripInfo64;
static uint32_t
elf_32_to_file (uint32_t x, int file_is_little_endian)
{
volatile uint32_t out;
unsigned char *outbytes;
outbytes = (unsigned char *)&out;
if (file_is_little_endian)
{
outbytes[0] = (x >> 0) & 0xff;
outbytes[1] = (x >> 8) & 0xff;
outbytes[2] = (x >> 16) & 0xff;
outbytes[3] = (x >> 24) & 0xff;
}
else /* big endian */
{
outbytes[0] = (x >> 24) & 0xff;
outbytes[1] = (x >> 16) & 0xff;
outbytes[2] = (x >> 8) & 0xff;
outbytes[3] = (x >> 0) & 0xff;
}
return out;
}
static uint64_t
elf_64_to_file (uint64_t x, int file_is_little_endian)
{
volatile uint64_t out;
unsigned char *outbytes;
int i;
outbytes = (unsigned char *)&out;
if (file_is_little_endian)
{
for (i = 0; i < 8; i++)
outbytes[i] = (x >> (8*i)) & 0xff;
}
else /* big endian */
{
for (i = 0; i < 8; i++)
outbytes[7-i] = (x >> (8*i)) & 0xff;
}
return out;
}
static Elf32_Word
word32_to_file (Elf32_Word x, Elf *elf)
{
/* FIXME: implement */
return x;
Elf32_Ehdr *ehdr = elf32_getehdr (elf);
return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
}
static Elf32_Off
off32_to_file (Elf32_Off x, Elf *elf)
{
/* FIXME: implement */
return x;
Elf32_Ehdr *ehdr = elf32_getehdr (elf);
return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
}
static Elf64_Word
word64_to_file (Elf64_Word x, Elf *elf)
{
Elf64_Ehdr *ehdr = elf64_getehdr (elf);
return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
}
static Elf64_Off
off64_to_file (Elf64_Off x, Elf *elf)
{
Elf64_Ehdr *ehdr = elf64_getehdr (elf);
return elf_64_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
}
static uint32_t
elf_32_from_file (uint32_t x, int file_is_little_endian)
{
unsigned char *inbytes;
inbytes = (unsigned char *)&x;
if (file_is_little_endian)
{
return
(inbytes[0] << 0) |
(inbytes[1] << 8) |
(inbytes[2] << 16) |
(inbytes[3] << 24);
}
else /* big endian */
{
return
(inbytes[0] << 24) |
(inbytes[1] << 16) |
(inbytes[2] << 8) |
(inbytes[3] << 0);
}
}
static uint64_t
elf_64_from_file (uint64_t x, int file_is_little_endian)
{
unsigned char *inbytes;
inbytes = (unsigned char *)&x;
if (file_is_little_endian)
{
return
((uint64_t)inbytes[0] << 0) |
((uint64_t)inbytes[1] << 8) |
((uint64_t)inbytes[2] << 16) |
((uint64_t)inbytes[3] << 24) |
((uint64_t)inbytes[4] << 32) |
((uint64_t)inbytes[5] << 40) |
((uint64_t)inbytes[6] << 48) |
((uint64_t)inbytes[7] << 56);
}
else /* big endian */
{
return
((uint64_t)inbytes[0] << 56) |
((uint64_t)inbytes[1] << 48) |
((uint64_t)inbytes[2] << 40) |
((uint64_t)inbytes[3] << 32) |
((uint64_t)inbytes[4] << 24) |
((uint64_t)inbytes[5] << 16) |
((uint64_t)inbytes[6] << 8) |
((uint64_t)inbytes[7] << 0);
}
}
static Elf32_Word
word32_from_file (Elf32_Word x, Elf *elf)
{
/* FIXME: implement */
return x;
Elf32_Ehdr *ehdr = elf32_getehdr (elf);
return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
}
static Elf32_Off
off32_from_file (Elf32_Off x, Elf *elf)
{
/* FIXME: implement */
return x;
Elf32_Ehdr *ehdr = elf32_getehdr (elf);
return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
}
static Elf64_Word
word64_from_file (Elf64_Word x, Elf *elf)
{
Elf64_Ehdr *ehdr = elf64_getehdr (elf);
return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
}
static Elf64_Off
off64_from_file (Elf64_Off x, Elf *elf)
{
Elf64_Ehdr *ehdr = elf64_getehdr (elf);
return elf_64_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB);
}
static void
@ -93,7 +223,29 @@ unstrip_info_to_data64 (UnstripInfo *info,
Elf *elf,
Elf_Data *data)
{
UnstripInfo64 *info64;
int i;
data->d_align = 8;
data->d_size =
/* orig_e_shoff */ sizeof (Elf64_Off) +
/* n_sections */ sizeof (Elf64_Off) +
/* sections */ info->n_sections * sizeof (UnstripInfoSection64);
data->d_buf = calloc (1, data->d_size);
info64 = (UnstripInfo64 *) data->d_buf;
info64->orig_e_shoff = off64_to_file (info->orig_e_shoff, elf);
info64->n_sections = off64_to_file (info->n_sections, elf);
for (i = 0; i < info->n_sections; i++)
{
info64->sections[i].debug_section = word64_to_file (info->sections[i].debug_section, elf);
info64->sections[i].name = word64_to_file (info->sections[i].name, elf);
info64->sections[i].orig_offset = off64_to_file (info->sections[i].orig_offset, elf);
}
}
void
@ -101,11 +253,18 @@ unstrip_info_to_data (UnstripInfo *info,
Elf *elf,
Elf_Data *data)
{
GElf_Ehdr ehdr;
data->d_type = ELF_T_BYTE;
data->d_off = 0;
/* FIXME: use right version */
unstrip_info_to_data32 (info, elf, data);
gelf_getehdr (elf, &ehdr);
if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
unstrip_info_to_data32 (info, elf, data);
else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
unstrip_info_to_data64 (info, elf, data);
else
fprintf (stderr, "Warning. unsupported elf class\n");
}
void
@ -130,23 +289,49 @@ unstrip_info_from_data32 (UnstripInfo *info,
}
}
void
unstrip_info_from_data64 (UnstripInfo *info,
Elf *elf,
Elf_Data *data)
{
UnstripInfo64 *info64;
int i;
info64 = (UnstripInfo64 *) data->d_buf;
info->orig_e_shoff = off64_from_file (info64->orig_e_shoff, elf);
info->n_sections = off64_from_file (info64->n_sections, elf);
info->sections = calloc (info->n_sections, sizeof (UnstripInfoSection));
for (i = 0; i < info->n_sections; i++)
{
info->sections[i].debug_section = word64_from_file (info64->sections[i].debug_section, elf);
info->sections[i].name = word64_from_file (info64->sections[i].name, elf);
info->sections[i].orig_offset = off64_from_file (info64->sections[i].orig_offset, elf);
}
}
UnstripInfo *
unstrip_info_from_data (Elf *elf,
Elf_Data *data)
{
GElf_Ehdr ehdr;
UnstripInfo *info;
info = malloc (sizeof (UnstripInfo));
/* FIXME: use right version */
unstrip_info_from_data32 (info,
elf,
data);
gelf_getehdr (elf, &ehdr);
if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
unstrip_info_from_data32 (info, elf, data);
else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
unstrip_info_from_data64 (info, elf, data);
else
fprintf (stderr, "Warning. unsupported elf class\n");
return info;
}
static void
debug_link_to_data32 (DebugLink *debuglink,
Elf *elf,
@ -169,17 +354,47 @@ debug_link_to_data32 (DebugLink *debuglink,
p = data->d_buf + namelen_aligned;
*(Elf32_Word *)p = word32_to_file (debuglink->checksum, elf);
p += sizeof (Elf32_Word);
}
static void
debug_link_to_data64 (DebugLink *debuglink,
Elf *elf,
Elf_Data *data)
{
size_t namelen_aligned;
char *p;
data->d_align = 4;
namelen_aligned = align_up (strlen(debuglink->filename) + 1, 4);
data->d_size =
/* name */ namelen_aligned +
/* checksum */ sizeof (Elf64_Word);
data->d_buf = calloc (1, data->d_size);
strcpy (data->d_buf, debuglink->filename);
p = data->d_buf + namelen_aligned;
*(Elf64_Word *)p = word64_to_file (debuglink->checksum, elf);
}
void
debug_link_to_data (DebugLink *debuglink, Elf *elf, Elf_Data *data)
{
GElf_Ehdr ehdr;
data->d_type = ELF_T_BYTE;
data->d_off = 0;
/* FIXME: use right version */
debug_link_to_data32 (debuglink, elf, data);
gelf_getehdr (elf, &ehdr);
if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
debug_link_to_data32 (debuglink, elf, data);
else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
debug_link_to_data64 (debuglink, elf, data);
else
fprintf (stderr, "Warning. unsupported elf class\n");
}
void
@ -197,21 +412,41 @@ debug_link_from_data32 (DebugLink *debuglink,
p = data->d_buf + namelen_aligned;
debuglink->checksum = word32_from_file (*(Elf32_Word *)p, elf);
p += sizeof (Elf32_Word);
}
void
debug_link_from_data64 (DebugLink *debuglink,
Elf *elf,
Elf_Data *data)
{
size_t namelen_aligned;
char *p;
debuglink->filename = strdup (data->d_buf);
namelen_aligned = align_up (strlen (debuglink->filename) + 1, 4);
p = data->d_buf + namelen_aligned;
debuglink->checksum = word64_from_file (*(Elf64_Word *)p, elf);
}
DebugLink *
debug_link_from_data (Elf *elf, Elf_Data *data)
{
GElf_Ehdr ehdr;
DebugLink *debuglink;
debuglink = malloc (sizeof (DebugLink));
/* FIXME: use right version */
debug_link_from_data32 (debuglink,
elf,
data);
gelf_getehdr (elf, &ehdr);
if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
debug_link_from_data32 (debuglink, elf, data);
else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
debug_link_from_data64 (debuglink, elf, data);
else
fprintf (stderr, "Warning. unsupported elf class\n");
return debuglink;
}

View File

@ -201,7 +201,7 @@ strip_to_file(Elf *elf, Elf *out_elf, DebugLink *debuglink)
/* Update section header stringtab ref */
gelf_getehdr (out_elf, &out_ehdr);
out_ehdr.e_shstrndx = section_map[out_ehdr.e_shstrndx];
out_ehdr.e_shoff = align_up (last_offset, 4);
out_ehdr.e_shoff = align_up (last_offset, 8);
gelf_update_ehdr(out_elf, &out_ehdr);
/* Update section header links */
@ -402,6 +402,7 @@ main (int argc, char *argv[])
Elf *elf, *out_elf;
int fd, out;
const char *origname;
char *origname_base;
char *debugname, *strippedname;
DebugLink *debuglink;
poptContext optCon; /* context for parsing command-line options */
@ -433,14 +434,13 @@ main (int argc, char *argv[])
origname = args[0];
if (output_dir) {
const char * bn = strrchr(origname, '/');
if ((bn = strrchr(origname, '/')) != NULL)
bn++;
else
bn = origname;
debugname = strconcat (output_dir, "/", bn, ".debug", NULL);
} else
if (output_dir)
{
origname_base = path_basename (origname);
debugname = strconcat (output_dir, "/", origname_base, ".debug", NULL);
free (origname_base);
}
else
debugname = strconcat (origname, ".debug", NULL);
strippedname = strconcat (origname, ".XXXXXX", NULL);