Applied Fred Fish's patch to fix decoding of core notes.

This commit is contained in:
Nick Clifton 1999-11-25 11:08:25 +00:00
parent 61e8273b2c
commit 6d118b099c
2 changed files with 61 additions and 34 deletions

View file

@ -1,3 +1,13 @@
1999-11-25 Fred Fish <fnf@cygnus.com>
* readelf.c (process_note): Change arg from Elf_External_Note
to Elf32_Internal_Note, which also turns the function body
into little more than a call to printf.
(process_corefile_note_segment): Substantially rewritten
to properly handle case where target and host are different
endianness, handle note sections with padding, and add some
cruft to handle notes with unterminated name data.
1999-11-22 Nick Clifton <nickc@cygnus.com> 1999-11-22 Nick Clifton <nickc@cygnus.com>
* objcopy.c (copy_usage): Reformat. * objcopy.c (copy_usage): Reformat.

View file

@ -200,7 +200,7 @@ static const char * get_data_encoding PARAMS ((unsigned char));
static const char * get_osabi_name PARAMS ((unsigned char)); static const char * get_osabi_name PARAMS ((unsigned char));
static int guess_is_rela PARAMS ((unsigned long)); static int guess_is_rela PARAMS ((unsigned long));
static char * get_note_type PARAMS ((unsigned int)); static char * get_note_type PARAMS ((unsigned int));
static int process_note PARAMS ((Elf_External_Note *)); static int process_note PARAMS ((Elf32_Internal_Note *));
static int process_corefile_note_segment PARAMS ((FILE *, unsigned long, unsigned long)); static int process_corefile_note_segment PARAMS ((FILE *, unsigned long, unsigned long));
static int process_corefile_note_segments PARAMS ((FILE *)); static int process_corefile_note_segments PARAMS ((FILE *));
static int process_corefile_contents PARAMS ((FILE *)); static int process_corefile_contents PARAMS ((FILE *));
@ -6605,33 +6605,22 @@ get_note_type (e_type)
} }
} }
/* Note that by the ELF standard, the name field is already null byte
terminated, and namesz includes the terminating null byte.
I.E. the value of namesz for the name "FSF" is 4.
If the value of namesz is zero, there is no name present. */
static int static int
process_note (pnote) process_note (pnote)
Elf_External_Note * pnote; Elf32_Internal_Note * pnote;
{ {
Elf32_Internal_Note * internal;
char * pname;
internal = (Elf32_Internal_Note *) pnote;
pname = malloc (internal->namesz + 1);
if (pname == NULL)
{
error (_("Out of memory\n"));
return 0;
}
memcpy (pname, pnote->name, internal->namesz);
pname[internal->namesz] = '\0';
printf (" %s\t\t0x%08lx\t%s\n", printf (" %s\t\t0x%08lx\t%s\n",
pname, internal->descsz, get_note_type (internal->type)); pnote->namesz ? pnote->namedata : "(NONE)",
pnote->descsz, get_note_type (pnote->type));
free (pname);
return 1; return 1;
} }
static int static int
process_corefile_note_segment (file, offset, length) process_corefile_note_segment (file, offset, length)
FILE * file; FILE * file;
@ -6640,10 +6629,6 @@ process_corefile_note_segment (file, offset, length)
{ {
Elf_External_Note * pnotes; Elf_External_Note * pnotes;
Elf_External_Note * external; Elf_External_Note * external;
Elf32_Internal_Note* internal;
unsigned int notesz;
unsigned int nlength;
unsigned char * p;
int res = 1; int res = 1;
if (length <= 0) if (length <= 0)
@ -6652,21 +6637,53 @@ process_corefile_note_segment (file, offset, length)
GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes"); GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes");
external = pnotes; external = pnotes;
p = (unsigned char *) pnotes;
nlength = length;
printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"), offset, length); printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"), offset, length);
printf (_(" Owner\t\tData size\tDescription\n")); printf (_(" Owner\t\tData size\tDescription\n"));
while (nlength > 0) while (external < (Elf_External_Note *)((char *) pnotes + length))
{ {
res &= process_note (external); Elf32_Internal_Note inote;
char * temp = NULL;
internal = (Elf32_Internal_Note *) p; inote.type = BYTE_GET (external->type);
notesz = 3 * sizeof(unsigned long) + internal->namesz + internal->descsz; inote.namesz = BYTE_GET (external->namesz);
nlength -= notesz; inote.namedata = external->name;
p += notesz; inote.descsz = BYTE_GET (external->descsz);
external = (Elf_External_Note *) p; inote.descdata = inote.namedata + align_power (inote.namesz, 2);
inote.descpos = offset + (inote.descdata - (char *) pnotes);
external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
/* Verify that name is null terminated. It appears that at least
one version of Linux (RedHat 6.0) generates corefiles that don't
comply with the ELF spec by failing to include the null byte in
namesz. */
if (inote.namedata[inote.namesz] != '\0')
{
temp = malloc (inote.namesz + 1);
if (temp == NULL)
{
error (_("Out of memory\n"));
res = 0;
break;
}
strncpy (temp, inote.namedata, inote.namesz);
temp[inote.namesz] = 0;
/* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
inote.namedata = temp;
}
res &= process_note (& inote);
if (temp != NULL)
{
free (temp);
temp = NULL;
}
} }
free (pnotes); free (pnotes);