diff options
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 10 | ||||
-rw-r--r-- | binutils/readelf.c | 85 |
2 files changed, 61 insertions, 34 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index bb14678..84b1f86 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -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> * objcopy.c (copy_usage): Reformat. diff --git a/binutils/readelf.c b/binutils/readelf.c index cc287c2..c54ac53 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -200,7 +200,7 @@ static const char * get_data_encoding PARAMS ((unsigned char)); static const char * get_osabi_name PARAMS ((unsigned char)); static int guess_is_rela PARAMS ((unsigned long)); 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_segments 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 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", - pname, internal->descsz, get_note_type (internal->type)); - - free (pname); - + pnote->namesz ? pnote->namedata : "(NONE)", + pnote->descsz, get_note_type (pnote->type)); return 1; } + static int process_corefile_note_segment (file, offset, length) FILE * file; @@ -6640,10 +6629,6 @@ process_corefile_note_segment (file, offset, length) { Elf_External_Note * pnotes; Elf_External_Note * external; - Elf32_Internal_Note* internal; - unsigned int notesz; - unsigned int nlength; - unsigned char * p; int res = 1; if (length <= 0) @@ -6652,21 +6637,53 @@ process_corefile_note_segment (file, offset, length) GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes"); external = pnotes; - p = (unsigned char *) pnotes; - nlength = length; printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"), offset, length); 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; + + inote.type = BYTE_GET (external->type); + inote.namesz = BYTE_GET (external->namesz); + inote.namedata = external->name; + inote.descsz = BYTE_GET (external->descsz); + 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); - internal = (Elf32_Internal_Note *) p; - notesz = 3 * sizeof(unsigned long) + internal->namesz + internal->descsz; - nlength -= notesz; - p += notesz; - external = (Elf_External_Note *) p; + if (temp != NULL) + { + free (temp); + temp = NULL; + } } free (pnotes); |