From 665435215e31fcec0a19777edb9e83b0baf69854 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 21 Feb 2005 02:55:56 +0000 Subject: [PATCH] * readelf.c (BYTE_GET8): Delete. Replace uses with BYTE_GET. (byte_get_little_endian): Don't handle size of -8. (byte_get_signed, byte_get_big_endian): Likewise. (print_dec_vma, print_hex_vma): New functions. (print_vma): Use them. Return chars output. (get_dynamic_data): Return a bfd_vma array. Add ent_size parm. (process_symbol_table): Handle alpha and s390 .hash. --- binutils/ChangeLog | 10 ++ binutils/readelf.c | 323 ++++++++++++++++++++++++++++------------------------- 2 files changed, 179 insertions(+), 154 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 12837ea..7978950 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,13 @@ +2005-02-21 Alan Modra + + * readelf.c (BYTE_GET8): Delete. Replace uses with BYTE_GET. + (byte_get_little_endian): Don't handle size of -8. + (byte_get_signed, byte_get_big_endian): Likewise. + (print_dec_vma, print_hex_vma): New functions. + (print_vma): Use them. Return chars output. + (get_dynamic_data): Return a bfd_vma array. Add ent_size parm. + (process_symbol_table): Handle alpha and s390 .hash. + 2005-02-18 H.J. Lu * readelf.c (display_debug_loc): Print out offset for end of diff --git a/binutils/readelf.c b/binutils/readelf.c index e607e0f..877c04b 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -248,20 +248,6 @@ static void (*byte_put) (unsigned char *, bfd_vma, int); #define BYTE_GET(field) byte_get (field, sizeof (field)) -/* If we can support a 64 bit data type then BFD64 should be defined - and sizeof (bfd_vma) == 8. In this case when translating from an - external 8 byte field to an internal field, we can assume that the - internal field is also 8 bytes wide and so we can extract all the data. - If, however, BFD64 is not defined, then we must assume that the - internal data structure only has 4 byte wide fields that are the - equivalent of the 8 byte wide external counterparts, and so we must - truncate the data. */ -#ifdef BFD64 -#define BYTE_GET8(field) byte_get (field, -8) -#else -#define BYTE_GET8(field) byte_get (field, 8) -#endif - #define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0])) #define GET_ELF_SYMBOLS(file, section) \ @@ -365,11 +351,6 @@ byte_get_little_endian (unsigned char *field, int size) #ifdef BFD64 case 8: - case -8: - /* This is a special case, generated by the BYTE_GET8 macro. - It means that we are loading an 8 byte value from a field - in an external structure into an 8 byte value in a field - in an internal structure. */ return ((bfd_vma) (field[0])) | (((bfd_vma) (field[1])) << 8) | (((bfd_vma) (field[2])) << 16) @@ -399,7 +380,6 @@ byte_get_signed (unsigned char *field, int size) case 4: return (x ^ 0x80000000) - 0x80000000; case 8: - case -8: return x; default: abort (); @@ -434,8 +414,60 @@ byte_put_little_endian (unsigned char *field, bfd_vma value, int size) } } +#if defined BFD64 && !BFD_HOST_64BIT_LONG +static int +print_dec_vma (bfd_vma vma, int is_signed) +{ + char buf[40]; + char *bufp = buf; + int nc = 0; + + if (is_signed && (bfd_signed_vma) vma < 0) + { + vma = -vma; + putchar ('-'); + nc = 1; + } + + do + { + *bufp++ = '0' + vma % 10; + vma /= 10; + } + while (vma != 0); + nc += bufp - buf; + + while (bufp > buf) + putchar (*--bufp); + return nc; +} + +static int +print_hex_vma (bfd_vma vma) +{ + char buf[32]; + char *bufp = buf; + int nc; + + do + { + char digit = '0' + (vma & 0x0f); + if (digit > '9') + digit += 'a' - '0' - 10; + *bufp++ = digit; + vma >>= 4; + } + while (vma != 0); + nc = bufp - buf; + + while (bufp > buf) + putchar (*--bufp); + return nc; +} +#endif + /* Print a VMA value. */ -static void +static int print_vma (bfd_vma vma, print_mode mode) { #ifdef BFD64 @@ -445,106 +477,85 @@ print_vma (bfd_vma vma, print_mode mode) switch (mode) { case FULL_HEX: - printf ("0x"); - /* Drop through. */ + return printf ("0x%8.8lx", (unsigned long) vma); + case LONG_HEX: - printf ("%8.8lx", (unsigned long) vma); - break; + return printf ("%8.8lx", (unsigned long) vma); case DEC_5: if (vma <= 99999) - { - printf ("%5ld", (long) vma); - break; - } + return printf ("%5ld", (long) vma); /* Drop through. */ + case PREFIX_HEX: - printf ("0x"); - /* Drop through. */ + return printf ("0x%lx", (unsigned long) vma); + case HEX: - printf ("%lx", (unsigned long) vma); - break; + return printf ("%lx", (unsigned long) vma); case DEC: - printf ("%ld", (unsigned long) vma); - break; + return printf ("%ld", (unsigned long) vma); case UNSIGNED: - printf ("%lu", (unsigned long) vma); - break; + return printf ("%lu", (unsigned long) vma); } } #ifdef BFD64 else { + int nc = 0; + switch (mode) { case FULL_HEX: - printf ("0x"); + nc = printf ("0x"); /* Drop through. */ case LONG_HEX: printf_vma (vma); - break; + return nc + 16; case PREFIX_HEX: - printf ("0x"); + nc = printf ("0x"); /* Drop through. */ case HEX: #if BFD_HOST_64BIT_LONG - printf ("%lx", vma); + return nc + printf ("%lx", vma); #else - if (_bfd_int64_high (vma)) - printf ("%lx%8.8lx", _bfd_int64_high (vma), _bfd_int64_low (vma)); - else - printf ("%lx", _bfd_int64_low (vma)); + return nc + print_hex_vma (vma); #endif - break; case DEC: #if BFD_HOST_64BIT_LONG - printf ("%ld", vma); + return printf ("%ld", vma); #else - if (_bfd_int64_high (vma)) - /* ugg */ - printf ("++%ld", _bfd_int64_low (vma)); - else - printf ("%ld", _bfd_int64_low (vma)); + return print_dec_vma (vma, 1); #endif - break; case DEC_5: #if BFD_HOST_64BIT_LONG if (vma <= 99999) - printf ("%5ld", vma); + return printf ("%5ld", vma); else - printf ("%#lx", vma); + return printf ("%#lx", vma); #else - if (_bfd_int64_high (vma)) - /* ugg */ - printf ("++%ld", _bfd_int64_low (vma)); - else if (vma <= 99999) - printf ("%5ld", _bfd_int64_low (vma)); + if (vma <= 99999) + return printf ("%5ld", _bfd_int64_low (vma)); else - printf ("%#lx", _bfd_int64_low (vma)); + return print_hex_vma (vma); #endif - break; case UNSIGNED: #if BFD_HOST_64BIT_LONG - printf ("%lu", vma); + return printf ("%lu", vma); #else - if (_bfd_int64_high (vma)) - /* ugg */ - printf ("++%lu", _bfd_int64_low (vma)); - else - printf ("%lu", _bfd_int64_low (vma)); + return print_dec_vma (vma, 0); #endif - break; } } #endif + return 0; } /* Display a symbol on stdout. If do_wide is not true then @@ -575,27 +586,21 @@ byte_get_big_endian (unsigned char *field, int size) case 2: return ((unsigned int) (field[1])) | (((int) (field[0])) << 8); +#ifndef BFD64 + case 8: + /* Although we are extracing data from an 8 byte wide field, + we are returning only 4 bytes of data. */ + field += 4; + /* Fall thru */ +#endif case 4: return ((unsigned long) (field[3])) | (((unsigned long) (field[2])) << 8) | (((unsigned long) (field[1])) << 16) | (((unsigned long) (field[0])) << 24); -#ifndef BFD64 - case 8: - /* Although we are extracing data from an 8 byte wide field, - we are returning only 4 bytes of data. */ - return ((unsigned long) (field[7])) - | (((unsigned long) (field[6])) << 8) - | (((unsigned long) (field[5])) << 16) - | (((unsigned long) (field[4])) << 24); -#else +#ifdef BFD64 case 8: - case -8: - /* This is a special case, generated by the BYTE_GET8 macro. - It means that we are loading an 8 byte value from a field - in an external structure into an 8 byte value in a field - in an internal structure. */ return ((bfd_vma) (field[7])) | (((bfd_vma) (field[6])) << 8) | (((bfd_vma) (field[5])) << 16) @@ -807,9 +812,9 @@ slurp_rela_relocs (FILE *file, for (i = 0; i < nrelas; i++) { - relas[i].r_offset = BYTE_GET8 (erelas[i].r_offset); - relas[i].r_info = BYTE_GET8 (erelas[i].r_info); - relas[i].r_addend = BYTE_GET8 (erelas[i].r_addend); + relas[i].r_offset = BYTE_GET (erelas[i].r_offset); + relas[i].r_info = BYTE_GET (erelas[i].r_info); + relas[i].r_addend = BYTE_GET (erelas[i].r_addend); } free (erelas); @@ -877,8 +882,8 @@ slurp_rel_relocs (FILE *file, for (i = 0; i < nrels; i++) { - rels[i].r_offset = BYTE_GET8 (erels[i].r_offset); - rels[i].r_info = BYTE_GET8 (erels[i].r_info); + rels[i].r_offset = BYTE_GET (erels[i].r_offset); + rels[i].r_info = BYTE_GET (erels[i].r_info); rels[i].r_addend = 0; } @@ -3108,12 +3113,12 @@ get_64bit_program_headers (FILE *file, Elf_Internal_Phdr *program_headers) { internal->p_type = BYTE_GET (external->p_type); internal->p_flags = BYTE_GET (external->p_flags); - internal->p_offset = BYTE_GET8 (external->p_offset); - internal->p_vaddr = BYTE_GET8 (external->p_vaddr); - internal->p_paddr = BYTE_GET8 (external->p_paddr); - internal->p_filesz = BYTE_GET8 (external->p_filesz); - internal->p_memsz = BYTE_GET8 (external->p_memsz); - internal->p_align = BYTE_GET8 (external->p_align); + internal->p_offset = BYTE_GET (external->p_offset); + internal->p_vaddr = BYTE_GET (external->p_vaddr); + internal->p_paddr = BYTE_GET (external->p_paddr); + internal->p_filesz = BYTE_GET (external->p_filesz); + internal->p_memsz = BYTE_GET (external->p_memsz); + internal->p_align = BYTE_GET (external->p_align); } free (phdrs); @@ -3488,10 +3493,10 @@ get_64bit_section_headers (FILE *file, unsigned int num) { internal->sh_name = BYTE_GET (shdrs[i].sh_name); internal->sh_type = BYTE_GET (shdrs[i].sh_type); - internal->sh_flags = BYTE_GET8 (shdrs[i].sh_flags); - internal->sh_addr = BYTE_GET8 (shdrs[i].sh_addr); - internal->sh_size = BYTE_GET8 (shdrs[i].sh_size); - internal->sh_entsize = BYTE_GET8 (shdrs[i].sh_entsize); + internal->sh_flags = BYTE_GET (shdrs[i].sh_flags); + internal->sh_addr = BYTE_GET (shdrs[i].sh_addr); + internal->sh_size = BYTE_GET (shdrs[i].sh_size); + internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize); internal->sh_link = BYTE_GET (shdrs[i].sh_link); internal->sh_info = BYTE_GET (shdrs[i].sh_info); internal->sh_offset = BYTE_GET (shdrs[i].sh_offset); @@ -3618,8 +3623,8 @@ get_64bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section) if (psym->st_shndx == SHN_XINDEX && shndx != NULL) psym->st_shndx = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j])); - psym->st_value = BYTE_GET8 (esyms[j].st_value); - psym->st_size = BYTE_GET8 (esyms[j].st_size); + psym->st_value = BYTE_GET (esyms[j].st_value); + psym->st_size = BYTE_GET (esyms[j].st_size); } if (shndx) @@ -4410,7 +4415,7 @@ dump_ia64_unwind (struct ia64_unw_aux_info *aux) (unsigned long) (tp->info.offset - aux->seg_base)); head = aux->info + (tp->info.offset - aux->info_addr); - stamp = BYTE_GET8 ((unsigned char *) head); + stamp = BYTE_GET ((unsigned char *) head); printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n", (unsigned) UNW_VER (stamp), @@ -4490,9 +4495,9 @@ slurp_ia64_unwind_table (FILE *file, } else { - tep->start.offset = BYTE_GET8 ((unsigned char *) tp + 0); - tep->end.offset = BYTE_GET8 ((unsigned char *) tp + 8); - tep->info.offset = BYTE_GET8 ((unsigned char *) tp + 16); + tep->start.offset = BYTE_GET ((unsigned char *) tp + 0); + tep->end.offset = BYTE_GET ((unsigned char *) tp + 8); + tep->info.offset = BYTE_GET ((unsigned char *) tp + 16); } tep->start.offset += aux->seg_base; tep->end.offset += aux->seg_base; @@ -4875,8 +4880,8 @@ slurp_hppa_unwind_table (FILE *file, } else { - tep->start.offset = BYTE_GET8 ((unsigned char *) tp + 0); - tep->end.offset = BYTE_GET8 ((unsigned char *) tp + 8); + tep->start.offset = BYTE_GET ((unsigned char *) tp + 0); + tep->end.offset = BYTE_GET ((unsigned char *) tp + 8); tmp1 = byte_get ((unsigned char *) tp + 16, 4); tmp2 = byte_get ((unsigned char *) tp + 20, 4); } @@ -5273,7 +5278,7 @@ get_64bit_dynamic_section (FILE *file) ext++) { dynamic_nent++; - if (BYTE_GET8 (ext->d_tag) == DT_NULL) + if (BYTE_GET (ext->d_tag) == DT_NULL) break; } @@ -5289,8 +5294,8 @@ get_64bit_dynamic_section (FILE *file) entry < dynamic_section + dynamic_nent; ext++, entry++) { - entry->d_tag = BYTE_GET8 (ext->d_tag); - entry->d_un.d_val = BYTE_GET8 (ext->d_un.d_val); + entry->d_tag = BYTE_GET (ext->d_tag); + entry->d_un.d_val = BYTE_GET (ext->d_un.d_val); } free (edyn); @@ -6430,13 +6435,13 @@ get_symbol_index_type (unsigned int type) return buff; } -static int * -get_dynamic_data (FILE *file, unsigned int number) +static bfd_vma * +get_dynamic_data (FILE *file, unsigned int number, unsigned int ent_size) { unsigned char *e_data; - int *i_data; + bfd_vma *i_data; - e_data = malloc (number * 4); + e_data = malloc (number * ent_size); if (e_data == NULL) { @@ -6444,7 +6449,7 @@ get_dynamic_data (FILE *file, unsigned int number) return NULL; } - if (fread (e_data, 4, number, file) != number) + if (fread (e_data, ent_size, number, file) != number) { error (_("Unable to read in dynamic data\n")); return NULL; @@ -6460,7 +6465,7 @@ get_dynamic_data (FILE *file, unsigned int number) } while (number--) - i_data[number] = byte_get (e_data + number * 4, 4); + i_data[number] = byte_get (e_data + number * ent_size, ent_size); free (e_data); @@ -6472,12 +6477,10 @@ static int process_symbol_table (FILE *file) { Elf_Internal_Shdr *section; - unsigned char nb[4]; - unsigned char nc[4]; - int nbuckets = 0; - int nchains = 0; - int *buckets = NULL; - int *chains = NULL; + bfd_vma nbuckets = 0; + bfd_vma nchains = 0; + bfd_vma *buckets = NULL; + bfd_vma *chains = NULL; if (! do_syms && !do_histogram) return 1; @@ -6485,6 +6488,16 @@ process_symbol_table (FILE *file) if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL) || do_histogram)) { + unsigned char nb[8]; + unsigned char nc[8]; + int hash_ent_size = 4; + + if ((elf_header.e_machine == EM_ALPHA + || elf_header.e_machine == EM_S390 + || elf_header.e_machine == EM_S390_OLD) + && elf_header.e_ident[EI_CLASS] == ELFCLASS64) + hash_ent_size = 8; + if (fseek (file, (archive_file_offset + offset_from_vma (file, dynamic_info[DT_HASH], @@ -6495,23 +6508,23 @@ process_symbol_table (FILE *file) return 0; } - if (fread (nb, sizeof (nb), 1, file) != 1) + if (fread (nb, hash_ent_size, 1, file) != 1) { error (_("Failed to read in number of buckets\n")); return 0; } - if (fread (nc, sizeof (nc), 1, file) != 1) + if (fread (nc, hash_ent_size, 1, file) != 1) { error (_("Failed to read in number of chains\n")); return 0; } - nbuckets = byte_get (nb, 4); - nchains = byte_get (nc, 4); + nbuckets = byte_get (nb, hash_ent_size); + nchains = byte_get (nc, hash_ent_size); - buckets = get_dynamic_data (file, nbuckets); - chains = get_dynamic_data (file, nchains); + buckets = get_dynamic_data (file, nbuckets, hash_ent_size); + chains = get_dynamic_data (file, nchains, hash_ent_size); if (buckets == NULL || chains == NULL) return 0; @@ -6520,8 +6533,8 @@ process_symbol_table (FILE *file) if (do_syms && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL) { - int hn; - int si; + unsigned long hn; + bfd_vma si; printf (_("\nSymbol table for image:\n")); if (is_32bit_elf) @@ -6537,12 +6550,16 @@ process_symbol_table (FILE *file) for (si = buckets[hn]; si < nchains && si > 0; si = chains[si]) { Elf_Internal_Sym *psym; + int n; psym = dynamic_symbols + si; - printf (" %3d %3d: ", si, hn); + n = print_vma (si, DEC_5); + if (n < 5) + fputs (" " + n, stdout); + printf (" %3lu: ", hn); print_vma (psym->st_value, LONG_HEX); - putchar (' ' ); + putchar (' '); print_vma (psym->st_size, DEC_5); printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info))); @@ -6760,19 +6777,19 @@ process_symbol_table (FILE *file) if (do_histogram && buckets != NULL) { - int *lengths; - int *counts; - int hn; - int si; - int maxlength = 0; - int nzero_counts = 0; - int nsyms = 0; + unsigned long *lengths; + unsigned long *counts; + unsigned long hn; + bfd_vma si; + unsigned long maxlength = 0; + unsigned long nzero_counts = 0; + unsigned long nsyms = 0; - printf (_("\nHistogram for bucket list length (total of %d buckets):\n"), - nbuckets); + printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"), + (unsigned long) nbuckets); printf (_(" Length Number %% of total Coverage\n")); - lengths = calloc (nbuckets, sizeof (int)); + lengths = calloc (nbuckets, sizeof (*lengths)); if (lengths == NULL) { error (_("Out of memory")); @@ -6780,9 +6797,6 @@ process_symbol_table (FILE *file) } for (hn = 0; hn < nbuckets; ++hn) { - if (! buckets[hn]) - continue; - for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si]) { ++nsyms; @@ -6791,7 +6805,7 @@ process_symbol_table (FILE *file) } } - counts = calloc (maxlength + 1, sizeof (int)); + counts = calloc (maxlength + 1, sizeof (*counts)); if (counts == NULL) { error (_("Out of memory")); @@ -6803,13 +6817,14 @@ process_symbol_table (FILE *file) if (nbuckets > 0) { - printf (" 0 %-10d (%5.1f%%)\n", + unsigned long i; + printf (" 0 %-10lu (%5.1f%%)\n", counts[0], (counts[0] * 100.0) / nbuckets); - for (si = 1; si <= maxlength; ++si) + for (i = 1; i <= maxlength; ++i) { - nzero_counts += counts[si] * si; - printf ("%7d %-10d (%5.1f%%) %5.1f%%\n", - si, counts[si], (counts[si] * 100.0) / nbuckets, + nzero_counts += counts[i] * i; + printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n", + i, counts[i], (counts[i] * 100.0) / nbuckets, (nzero_counts * 100.0) / nsyms); } } @@ -11017,7 +11032,7 @@ process_mips_specific (FILE *file) reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]); reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]); reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]); - reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value); + reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value); printf ("GPR %08lx GP 0x", reginfo.ri_gprmask); @@ -11638,9 +11653,9 @@ get_file_header (FILE *file) elf_header.e_type = BYTE_GET (ehdr64.e_type); elf_header.e_machine = BYTE_GET (ehdr64.e_machine); elf_header.e_version = BYTE_GET (ehdr64.e_version); - elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry); - elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff); - elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff); + elf_header.e_entry = BYTE_GET (ehdr64.e_entry); + elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff); + elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff); elf_header.e_flags = BYTE_GET (ehdr64.e_flags); elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize); elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize); -- 2.7.4