From 22a398e1906e55c453f561070206acb80daf91f1 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 14 Nov 2003 15:12:44 +0000 Subject: [PATCH] Add new field to disassemble_info structure: symbol_is_valid() and use it to skip displaying arm elf mapping symbols in disassembly output. --- binutils/ChangeLog | 13 ++++ binutils/objdump.c | 110 ++++++++++++++++++---------------- gas/testsuite/ChangeLog | 10 ++++ gas/testsuite/gas/arm/arm7t.d | 2 +- gas/testsuite/gas/arm/pic.d | 4 +- include/ChangeLog | 11 ++++ include/dis-asm.h | 20 ++++++- opcodes/ChangeLog | 12 ++++ opcodes/arm-dis.c | 17 ++++++ opcodes/dis-buf.c | 11 +++- opcodes/dis-init.c | 2 + opcodes/disassemble.c | 18 ++++++ 12 files changed, 170 insertions(+), 60 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 0db5c0f534a..f6eeb845272 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,16 @@ +2003-11-14 Nick Clifton + + * objdump.c (find_symbol_for_address): Change parameters so + that the entire disassemble_info structure is passed, not just + a few fields. Use the symbol_is_valid field to check the + validity of located symbols and continue searching if they are + not valid. + (objdump_print_addr): Alter parameters passed to + find_symbol_for_address. + (objdump_symbol_at_address): Likewise. + (disassemble_address): Likewise. Also use symbol_is_valid + function to check the validity of located symbols. + 2003-11-13 Tobias Burnus * ar.c (open_inarch): Emit a warning when an archive is created diff --git a/binutils/objdump.c b/binutils/objdump.c index 723a28c0c5e..dee8490e480 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -643,14 +643,14 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *info, free (alloc); } -/* Locate a symbol given a bfd, a section, and a VMA. If REQUIRE_SEC - is TRUE, then always require the symbol to be in the section. This - returns NULL if there is no suitable symbol. If PLACE is not NULL, - then *PLACE is set to the index of the symbol in sorted_syms. */ +/* Locate a symbol given a bfd and a section (from INFO->application_data), + and a VMA. If INFO->application_data->require_sec is TRUE, then always + require the symbol to be in the section. Returns NULL if there is no + suitable symbol. If PLACE is not NULL, then *PLACE is set to the index + of the symbol in sorted_syms. */ static asymbol * -find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma, - bfd_boolean require_sec, long *place) +find_symbol_for_address (bfd_vma vma, struct disassemble_info *info, long *place) { /* @@ Would it speed things up to cache the last two symbols returned, and maybe their address ranges? For many processors, only one memory @@ -661,6 +661,9 @@ find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma, long min = 0; long max = sorted_symcount; long thisplace; + struct objdump_disasm_info * aux = (struct objdump_disasm_info *) info->application_data; + bfd * abfd = aux->abfd; + asection * sec = aux->sec; unsigned int opb = bfd_octets_per_byte (abfd); if (sorted_symcount < 1) @@ -704,7 +707,7 @@ find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma, no way to tell what's desired without looking at the relocation table. */ if (sorted_syms[thisplace]->section != sec - && (require_sec + && (aux->require_sec || ((abfd->flags & HAS_RELOC) != 0 && vma >= bfd_get_section_vma (abfd, sec) && vma < (bfd_get_section_vma (abfd, sec) @@ -749,15 +752,22 @@ find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma, } if (sorted_syms[thisplace]->section != sec - && (require_sec + && (aux->require_sec || ((abfd->flags & HAS_RELOC) != 0 && vma >= bfd_get_section_vma (abfd, sec) && vma < (bfd_get_section_vma (abfd, sec) + bfd_section_size (abfd, sec))))) - { - /* There is no suitable symbol. */ - return NULL; - } + /* There is no suitable symbol. */ + return NULL; + } + + /* Give the target a chance to reject the symbol. */ + while (! info->symbol_is_valid (sorted_syms [thisplace], info)) + { + ++ thisplace; + if (thisplace >= sorted_symcount + || bfd_asymbol_value (sorted_syms [thisplace]) > vma) + return NULL; } if (place != NULL) @@ -819,7 +829,7 @@ static void objdump_print_addr (bfd_vma vma, struct disassemble_info *info, bfd_boolean skip_zeroes) { - struct objdump_disasm_info *aux; + struct objdump_disasm_info * aux = (struct objdump_disasm_info *) info->application_data; asymbol *sym; if (sorted_symcount < 1) @@ -829,9 +839,7 @@ objdump_print_addr (bfd_vma vma, struct disassemble_info *info, return; } - aux = (struct objdump_disasm_info *) info->application_data; - sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec, - NULL); + sym = find_symbol_for_address (vma, info, NULL); objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info, skip_zeroes); } @@ -850,16 +858,9 @@ objdump_print_address (bfd_vma vma, struct disassemble_info *info) static int objdump_symbol_at_address (bfd_vma vma, struct disassemble_info * info) { - struct objdump_disasm_info * aux; asymbol * sym; - /* No symbols - do not bother checking. */ - if (sorted_symcount < 1) - return 0; - - aux = (struct objdump_disasm_info *) info->application_data; - sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec, - NULL); + sym = find_symbol_for_address (vma, info, NULL); return (sym != NULL && (bfd_asymbol_value (sym) == vma)); } @@ -1627,6 +1628,7 @@ disassemble_section (bfd *abfd, asection *section, void *info) bfd_get_section_contents (abfd, section, data, 0, datasize); paux->sec = section; + paux->require_sec = TRUE; pinfo->buffer = data; pinfo->buffer_vma = section->vma; pinfo->buffer_length = datasize; @@ -1659,8 +1661,7 @@ disassemble_section (bfd *abfd, asection *section, void *info) printf (_("Disassembly of section %s:\n"), section->name); /* Find the nearest symbol forwards from our current position. */ - sym = find_symbol_for_address (abfd, section, section->vma + addr_offset, - TRUE, &place); + sym = find_symbol_for_address (section->vma + addr_offset, info, &place); /* Disassemble a block of instructions up to the address associated with the symbol we have just found. Then print the symbol and find the @@ -1668,81 +1669,81 @@ disassemble_section (bfd *abfd, asection *section, void *info) or we have reached the end of the address range we are interested in. */ while (addr_offset < stop_offset) { + bfd_vma addr; asymbol *nextsym; unsigned long nextstop_offset; bfd_boolean insns; - if (sym != NULL - && bfd_asymbol_value (sym) <= section->vma + addr_offset) + addr = section->vma + addr_offset; + + if (sym != NULL && bfd_asymbol_value (sym) <= addr) { int x; for (x = place; (x < sorted_symcount - && (bfd_asymbol_value (sorted_syms[x]) - <= section->vma + addr_offset)); + && (bfd_asymbol_value (sorted_syms[x]) <= addr)); ++x) continue; - pinfo->symbols = & sorted_syms[place]; + pinfo->symbols = sorted_syms + place; pinfo->num_symbols = x - place; } else - pinfo->symbols = NULL; + { + pinfo->symbols = NULL; + pinfo->num_symbols = 0; + } if (! prefix_addresses) { pinfo->fprintf_func (pinfo->stream, "\n"); - objdump_print_addr_with_sym (abfd, section, sym, - section->vma + addr_offset, + objdump_print_addr_with_sym (abfd, section, sym, addr, pinfo, FALSE); pinfo->fprintf_func (pinfo->stream, ":\n"); } - if (sym != NULL - && bfd_asymbol_value (sym) > section->vma + addr_offset) + if (sym != NULL && bfd_asymbol_value (sym) > addr) nextsym = sym; else if (sym == NULL) nextsym = NULL; else { +#define is_valid_next_sym(SYM) \ + ((SYM)->section == section \ + && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \ + && pinfo->symbol_is_valid (SYM, pinfo)) + /* Search forward for the next appropriate symbol in SECTION. Note that all the symbols are sorted together into one big array, and that some sections may have overlapping addresses. */ while (place < sorted_symcount - && (sorted_syms[place]->section != section - || (bfd_asymbol_value (sorted_syms[place]) - <= bfd_asymbol_value (sym)))) + && ! is_valid_next_sym (sorted_syms [place])) ++place; + if (place >= sorted_symcount) nextsym = NULL; else nextsym = sorted_syms[place]; } - if (sym != NULL - && bfd_asymbol_value (sym) > section->vma + addr_offset) - { - nextstop_offset = bfd_asymbol_value (sym) - section->vma; - if (nextstop_offset > stop_offset) - nextstop_offset = stop_offset; - } + if (sym != NULL && bfd_asymbol_value (sym) > addr) + nextstop_offset = bfd_asymbol_value (sym) - section->vma; else if (nextsym == NULL) nextstop_offset = stop_offset; else - { - nextstop_offset = bfd_asymbol_value (nextsym) - section->vma; - if (nextstop_offset > stop_offset) - nextstop_offset = stop_offset; - } + nextstop_offset = bfd_asymbol_value (nextsym) - section->vma; + + if (nextstop_offset > stop_offset) + nextstop_offset = stop_offset; /* If a symbol is explicitly marked as being an object rather than a function, just dump the bytes without disassembling them. */ if (disassemble_all || sym == NULL - || bfd_asymbol_value (sym) > section->vma + addr_offset + || bfd_asymbol_value (sym) > addr || ((sym->flags & BSF_OBJECT) == 0 && (strstr (bfd_asymbol_name (sym), "gnu_compiled") == NULL) @@ -1789,7 +1790,7 @@ disassemble_data (bfd *abfd) /* Sort the symbols into section and symbol order. */ qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols); - init_disassemble_info (&disasm_info, stdout, fprintf); + init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf); disasm_info.application_data = (void *) &aux; aux.abfd = abfd; @@ -1845,6 +1846,9 @@ disassemble_data (bfd *abfd) instead. */ disasm_info.endian = BFD_ENDIAN_UNKNOWN; + /* Allow the target to customize the info structure. */ + disassemble_init_for_target (& disasm_info); + /* Pre-load the dynamic relocs if we are going to be dumping them along with the disassembly. */ if (dump_dynamic_reloc_info) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index c10a1434d30..9d21c630572 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2003-11-14 Nick Clifton + + * gas/arm/arm7.d: Pass -D instead of -d to objdump in order to + display the contents of data fields in the .text section. + This change is necessary after the addition of arm elf mapping + symbol support to gas. + * gas/arm/pic.d: Expect addresses with function name offsets. + This change is necessary after the addition of arm elf mapping + symbol support to gas. + 2003-11-13 Nick Clifton * gas/arm/mapping.s: New test: Source for ARM ELF mapping diff --git a/gas/testsuite/gas/arm/arm7t.d b/gas/testsuite/gas/arm/arm7t.d index 17e4e9d4fb5..768ce139c9e 100644 --- a/gas/testsuite/gas/arm/arm7t.d +++ b/gas/testsuite/gas/arm/arm7t.d @@ -1,4 +1,4 @@ -#objdump: -dr --prefix-addresses --show-raw-insn +#objdump: -Dr --prefix-addresses --show-raw-insn #name: ARM arm7t #as: -mcpu=arm7t -EL diff --git a/gas/testsuite/gas/arm/pic.d b/gas/testsuite/gas/arm/pic.d index 0e6943eb0be..6c4a0433063 100644 --- a/gas/testsuite/gas/arm/pic.d +++ b/gas/testsuite/gas/arm/pic.d @@ -6,9 +6,9 @@ .*: +file format .*arm.* Disassembly of section .text: -0x0+0 ebfffffe bl 0x0+0 +00+0 <[^>]*> ebfffffe bl 00+0 <[^>]*> 0: R_ARM_PC24 foo -0x0+4 ebfffffe bl 0x0+4 +00+4 <[^>]*> ebfffffe bl 00+4 <[^>]*> 4: R_ARM_PLT32 foo \.\.\. 8: R_ARM_ABS32 sym diff --git a/include/ChangeLog b/include/ChangeLog index 9fa8373e4e5..9052a6e203f 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,14 @@ +2003-11-14 Nick Clifton + + * dis-asm.h (struct disassemble_info): Add new field + 'symbol_is_valid' which is a function which can tell the + disassembler to skip certain symbols as they should not be + displayed to the user. + (arm_symbol_is_valid): New prototype. This is the ARM + specific function for the symbol_is_valid field. + (generic_symbol_is_valid): New prototype. This is the default + function pointed to by the symbol_is_valid field. + 2003-11-06 Bruno Rohee * hp-symtab.h: Fix "the the" typo. diff --git a/include/dis-asm.h b/include/dis-asm.h index 6bdd7517de5..3670c518986 100644 --- a/include/dis-asm.h +++ b/include/dis-asm.h @@ -130,6 +130,12 @@ typedef struct disassemble_info { int (* symbol_at_address_func) (bfd_vma addr, struct disassemble_info * info); + /* Function called to check if a SYMBOL is can be displayed to the user. + This is used by some ports that want to hide special symbols when + displaying debugging outout. */ + bfd_boolean (* symbol_is_valid) + (asymbol *, struct disassemble_info * info); + /* These are for buffer_read_memory. */ bfd_byte *buffer; bfd_vma buffer_vma; @@ -141,7 +147,7 @@ typedef struct disassemble_info { the same value in order to get reasonable looking output. */ int bytes_per_line; - /* the next two variables control the way objdump displays the raw data */ + /* The next two variables control the way objdump displays the raw data. */ /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */ /* output will look like this: 00: 00000000 00000000 @@ -251,12 +257,16 @@ extern void print_arm_disassembler_options (FILE *); extern void parse_arm_disassembler_option (char *); extern int get_arm_regname_num_options (void); extern int set_arm_regname_option (int); -extern int get_arm_regnames - (int, const char **, const char **, const char ***); +extern int get_arm_regnames (int, const char **, const char **, const char ***); +extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *); /* Fetch the disassembler for a given BFD, if that support is available. */ extern disassembler_ftype disassembler (bfd *); +/* Amend the disassemble_info structure as necessary for the target architecture. + Should only be called after initialising the info->arch field. */ +extern void disassemble_init_for_target (struct disassemble_info * info); + /* Document any target specific options available from the disassembler. */ extern void disassembler_usage (FILE *); @@ -284,6 +294,10 @@ extern void generic_print_address extern int generic_symbol_at_address (bfd_vma, struct disassemble_info *); +/* Also always true. */ +extern bfd_boolean generic_symbol_is_valid + (asymbol *, struct disassemble_info *); + /* Method to initialize a disassemble_info struct. This should be called by all applications creating such a struct. */ extern void init_disassemble_info (struct disassemble_info *info, void *stream, diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 2f613cb71e5..5918252c802 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,15 @@ +2003-11-14 Nick Clifton + + * dis-init.c (init_disassemble_info): Initialise + symbol_is_valid field. + * dis-buf.c (generic_symbol_is_valid): New function. Always + returns TRUE. + * arm-dis.c (arm_symbol_is_valid): New function. Return FALSE + for ARM ELF mapping symbols. + * disassemble.c (disassemble_init_for_target): Set + symbol_is_valid field to arm_symbol_is_valid of the target is + an ARM. + 2003-11-05 H.J. Lu * m68k-opc.c (m68k_opcodes): Reorder "fmovel". diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 5f8fc4cfd12..d4ba196b852 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -1145,6 +1145,23 @@ print_insn_thumb (pc, info, given) abort (); } +/* Disallow mapping symbols ($a, $b, $d, $t etc) from + being displayed in symbol relative addresses. */ + +bfd_boolean +arm_symbol_is_valid (asymbol * sym, + struct disassemble_info * info ATTRIBUTE_UNUSED) +{ + const char * name; + + if (sym == NULL) + return FALSE; + + name = bfd_asymbol_name (sym); + + return (name && *name != '$'); +} + /* Parse an individual disassembler option. */ void diff --git a/opcodes/dis-buf.c b/opcodes/dis-buf.c index 8f846a9b1b7..83fbfbd7d21 100644 --- a/opcodes/dis-buf.c +++ b/opcodes/dis-buf.c @@ -107,7 +107,7 @@ generic_strcat_address (addr, buf, len) } #endif -/* Just return the given address. */ +/* Just return true. */ int generic_symbol_at_address (addr, info) @@ -116,3 +116,12 @@ generic_symbol_at_address (addr, info) { return 1; } + +/* Just return TRUE. */ + +bfd_boolean +generic_symbol_is_valid (asymbol * sym ATTRIBUTE_UNUSED, + struct disassemble_info *info ATTRIBUTE_UNUSED) +{ + return TRUE; +} diff --git a/opcodes/dis-init.c b/opcodes/dis-init.c index 4c3e36e6e8c..35a5ee720b8 100644 --- a/opcodes/dis-init.c +++ b/opcodes/dis-init.c @@ -26,6 +26,7 @@ init_disassemble_info (struct disassemble_info *info, void *stream, fprintf_ftype fprintf_func) { memset (info, 0, sizeof (*info)); + info->flavour = bfd_target_unknown_flavour; info->arch = bfd_arch_unknown; info->endian = BFD_ENDIAN_UNKNOWN; @@ -36,6 +37,7 @@ init_disassemble_info (struct disassemble_info *info, void *stream, info->memory_error_func = perror_memory; info->print_address_func = generic_print_address; info->symbol_at_address_func = generic_symbol_at_address; + info->symbol_is_valid = generic_symbol_is_valid; info->display_endian = BFD_ENDIAN_UNKNOWN; } diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c index 14113b57366..d5b17be3253 100644 --- a/opcodes/disassemble.c +++ b/opcodes/disassemble.c @@ -397,3 +397,21 @@ disassembler_usage (stream) return; } + +void +disassemble_init_for_target (struct disassemble_info * info) +{ + if (info == NULL) + return; + + switch (info->arch) + { +#ifdef ARCH_arm + case bfd_arch_arm: + info->symbol_is_valid = arm_symbol_is_valid; + break; +#endif + default: + break; + } +} -- 2.30.2