diff options
-rw-r--r-- | binutils/ChangeLog | 6 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/aarch64/in-order.d | 28 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/aarch64/out-of-order.d | 17 | ||||
-rw-r--r-- | opcodes/ChangeLog | 5 | ||||
-rw-r--r-- | opcodes/aarch64-dis.c | 44 |
5 files changed, 93 insertions, 7 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 121c54d..1c6c354 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,5 +1,11 @@ 2019-03-25 Tamar Christina <tamar.christina@arm.com> + * testsuite/binutils-all/aarch64/in-order.d: New test. + * testsuite/binutils-all/aarch64/out-of-order.d: Disassemble data as + well. + +2019-03-25 Tamar Christina <tamar.christina@arm.com> + * objdump.c (disassemble_bytes): Pass stop_offset. * testsuite/binutils-all/aarch64/out-of-order.T: New test. * testsuite/binutils-all/aarch64/out-of-order.d: New test. diff --git a/binutils/testsuite/binutils-all/aarch64/in-order.d b/binutils/testsuite/binutils-all/aarch64/in-order.d new file mode 100644 index 0000000..090337f --- /dev/null +++ b/binutils/testsuite/binutils-all/aarch64/in-order.d @@ -0,0 +1,28 @@ +#PROG: objcopy +#source: out-of-order.s +#ld: -e v1 -Ttext-segment=0x400000 +#objdump: -d +#name: Check if disassembler can handle sections in default order + +.*: +file format .*aarch64.* + +Disassembly of section \.func1: + +0000000000400000 <v1>: + 400000: 8b010000 add x0, x0, x1 + 400004: 00000000 \.word 0x00000000 + +Disassembly of section .func2: + +0000000000400008 <\.func2>: + 400008: 8b010000 add x0, x0, x1 + +Disassembly of section \.func3: + +000000000040000c <\.func3>: + 40000c: 8b010000 add x0, x0, x1 + 400010: 8b010000 add x0, x0, x1 + 400014: 8b010000 add x0, x0, x1 + 400018: 8b010000 add x0, x0, x1 + 40001c: 8b010000 add x0, x0, x1 + 400020: 00000000 \.word 0x00000000 diff --git a/binutils/testsuite/binutils-all/aarch64/out-of-order.d b/binutils/testsuite/binutils-all/aarch64/out-of-order.d index 410f37f..f78adec 100644 --- a/binutils/testsuite/binutils-all/aarch64/out-of-order.d +++ b/binutils/testsuite/binutils-all/aarch64/out-of-order.d @@ -1,10 +1,20 @@ #PROG: objcopy #ld: -T out-of-order.T -#objdump: -d +#objdump: -D #name: Check if disassembler can handle sections in different order than header .*: +file format .*aarch64.* +Disassembly of section \.global: + +00000000ffe00000 <\.global>: + ffe00000: 00000001 \.word 0x00000001 + ffe00004: 00000000 \.word 0x00000000 + ffe00008: 00000001 \.word 0x00000001 + ffe0000c: 00000000 \.word 0x00000000 + ffe00010: 00000001 \.word 0x00000001 + ffe00014: 00000000 \.word 0x00000000 + Disassembly of section \.func2: 0000000004018280 <\.func2>: @@ -25,3 +35,8 @@ Disassembly of section \.func3: 401500c: 8b010000 add x0, x0, x1 4015010: 8b010000 add x0, x0, x1 4015014: 00000000 \.word 0x00000000 + +Disassembly of section \.rodata: + +0000000004015018 <\.rodata>: + 4015018: 00000004 \.word 0x00000004 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 81fe9f0..e5705d7 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,5 +1,10 @@ 2019-03-25 Tamar Christina <tamar.christina@arm.com> + * aarch64-dis.c (print_insn_aarch64): Update the mapping symbol search + order. + +2019-03-25 Tamar Christina <tamar.christina@arm.com> + * aarch64-dis.c (last_stop_offset): New. (print_insn_aarch64): Use stop_offset. diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index fc7e95d..1f931d0 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -3318,14 +3318,26 @@ print_insn_aarch64 (bfd_vma pc, /* Aarch64 instructions are always little-endian */ info->endian_code = BFD_ENDIAN_LITTLE; + /* Default to DATA. A text section is required by the ABI to contain an + INSN mapping symbol at the start. A data section has no such + requirement, hence if no mapping symbol is found the section must + contain only data. This however isn't very useful if the user has + fully stripped the binaries. If this is the case use the section + attributes to determine the default. If we have no section default to + INSN as well, as we may be disassembling some raw bytes on a baremetal + HEX file or similar. */ + enum map_type type = MAP_DATA; + if ((info->section && info->section->flags & SEC_CODE) || !info->section) + type = MAP_INSN; + /* First check the full symtab for a mapping symbol, even if there are no usable non-mapping symbols for this address. */ if (info->symtab_size != 0 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour) { - enum map_type type = MAP_INSN; int last_sym = -1; - bfd_vma addr; + bfd_vma addr, section_vma = 0; + bfd_boolean can_use_search_opt_p; int n; if (pc <= last_mapping_addr) @@ -3334,13 +3346,20 @@ print_insn_aarch64 (bfd_vma pc, /* Start scanning at the start of the function, or wherever we finished last time. */ n = info->symtab_pos + 1; + /* If the last stop offset is different from the current one it means we are disassembling a different glob of bytes. As such the optimization would not be safe and we should start over. */ - if (n < last_mapping_sym && info->stop_offset == last_stop_offset) + can_use_search_opt_p = last_mapping_sym >= 0 + && info->stop_offset == last_stop_offset; + + if (n >= last_mapping_sym && can_use_search_opt_p) n = last_mapping_sym; - /* Scan up to the location being disassembled. */ + /* Look down while we haven't passed the location being disassembled. + The reason for this is that there's no defined order between a symbol + and an mapping symbol that may be at the same address. We may have to + look at least one position ahead. */ for (; n < info->symtab_size; n++) { addr = bfd_asymbol_value (info->symtab[n]); @@ -3356,13 +3375,24 @@ print_insn_aarch64 (bfd_vma pc, if (!found) { n = info->symtab_pos; - if (n < last_mapping_sym) + if (n >= last_mapping_sym && can_use_search_opt_p) n = last_mapping_sym; /* No mapping symbol found at this address. Look backwards - for a preceeding one. */ + for a preceeding one, but don't go pass the section start + otherwise a data section with no mapping symbol can pick up + a text mapping symbol of a preceeding section. The documentation + says section can be NULL, in which case we will seek up all the + way to the top. */ + if (info->section) + section_vma = info->section->vma; + for (; n >= 0; n--) { + addr = bfd_asymbol_value (info->symtab[n]); + if (addr < section_vma) + break; + if (get_sym_code_type (info, n, &type)) { last_sym = n; @@ -3400,6 +3430,8 @@ print_insn_aarch64 (bfd_vma pc, size = (pc & 1) ? 1 : 2; } } + else + last_type = type; if (last_type == MAP_DATA) { |