Stop "objdump -d" from disassembling past a symbolic address.

include	* dis-asm.h (struct disassemble_info): Add stop_vma field.

binuti  * objdump.c (disassemble_bytes): Set the stop_vma field in the
	disassemble_info structure when disassembling code sections with
	-d.
	* doc/binutils.texi (objdump): Document the discrepancy between -d
	and -D.

opcodes	* dis-buf.c (buffer_read_memory): Fail is stop_vma is set and the
	requested region lies beyond it.
	* bfin-dis.c (print_insn_bfin): Ignore sysop instructions when
	looking for 32-bit insns.
	* mcore-dis.c (print_insn_mcore): Disable stop_vma when reading
	data.
	* sh-dis.c (print_insn_sh): Likewise.
	* tic6x-dis.c (print_insn_tic6x): Disable stop_vma when reading
	blocks of instructions.
	* vax-dis.c (print_insn_vax): Check that the requested address
	does not clash with the stop_vma.

tests	* gas/arm/backslash-at.s: Add extra .byte directives so that the
	foo symbol does not appear to point half way through an
	instruction.
	* gas/arm/backslash-at.d: Update expected disassembly.
	* gas/i386/ilp32/x86-64-opcode-inval-intel.d: Likewise.
	* gas/i386/ilp32/x86-64-opcode-inval.d: Likewise.
	* gas/i386/x86-64-opcode-inval-intel.d: Likewise.
	* gas/i386/x86-64-opcode-inval.d: Likewise.
This commit is contained in:
Nick Clifton 2015-06-22 16:53:27 +01:00
parent 07fcd30112
commit bdc4de1b24
19 changed files with 128 additions and 49 deletions

View file

@ -1,3 +1,11 @@
2015-06-22 Nick Clifton <nickc@redhat.com>
* objdump.c (disassemble_bytes): Set the stop_vma field in the
disassemble_info structure when disassembling code sections with
-d.
* doc/binutils.texi (objdump): Document the discrepancy between -d
and -D.
2015-06-05 Nick Clifton <nickc@redhat.com>
* dwarf.c (read_debug_line_header): Use reloc_at to detect

View file

@ -2041,6 +2041,15 @@ expected to contain instructions.
Like @option{-d}, but disassemble the contents of all sections, not just
those expected to contain instructions.
This option also has a subtle effect on the disassembly of
instructions in code sections. When option @option{-d} is in effect
objdump will assume that any symbols present in a code section occur
on the boundary between instructions and it will refuse to disassemble
across such a boundary. When option @option{-D} is in effect however
this assumption is supressed. This means that it is possible for the
output of @option{-d} and @option{-D} to differ if, for example, data
is stored in code sections.
If the target is an ARM architecture this switch also has the effect
of forcing the disassembler to decode pieces of data found in code
sections as if they were instructions.

View file

@ -1685,7 +1685,18 @@ disassemble_bytes (struct disassemble_info * inf,
}
}
if (! disassemble_all
&& (section->flags & (SEC_CODE | SEC_HAS_CONTENTS))
== (SEC_CODE | SEC_HAS_CONTENTS))
/* Set a stop_vma so that the disassembler will not read
beyond the next symbol. We assume that symbols appear on
the boundaries between instructions. We only do this when
disassembling code of course, and when -D is in effect. */
inf->stop_vma = section->vma + stop_offset;
octets = (*disassemble_fn) (section->vma + addr_offset, inf);
inf->stop_vma = 0;
inf->fprintf_func = (fprintf_ftype) fprintf;
inf->stream = stdout;
if (insn_width == 0 && inf->bytes_per_line != 0)
@ -1911,7 +1922,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
arelent ** rel_pp = NULL;
arelent ** rel_ppstart = NULL;
arelent ** rel_ppend;
unsigned long stop_offset;
bfd_vma stop_offset;
asymbol * sym = NULL;
long place = 0;
long rel_count;
@ -2035,7 +2046,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
{
bfd_vma addr;
asymbol *nextsym;
unsigned long nextstop_offset;
bfd_vma nextstop_offset;
bfd_boolean insns;
addr = section->vma + addr_offset;
@ -2330,7 +2341,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
section->num_relocs = reloc_count;
}
}
}
}
return 1;
}
@ -2794,9 +2805,9 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
{
bfd_byte *data = 0;
bfd_size_type datasize;
bfd_size_type addr_offset;
bfd_size_type start_offset;
bfd_size_type stop_offset;
bfd_vma addr_offset;
bfd_vma start_offset;
bfd_vma stop_offset;
unsigned int opb = bfd_octets_per_byte (abfd);
/* Bytes per line. */
const int onaline = 16;
@ -3451,7 +3462,7 @@ display_any_bfd (bfd *file, int level)
{
bfd *arfile = NULL;
bfd *last_arfile = NULL;
if (level == 0)
printf (_("In archive %s:\n"), bfd_get_filename (file));
else if (level > 100)

View file

@ -1,3 +1,14 @@
2015-06-22 Nick Clifton <nickc@redhat.com>
* gas/arm/backslash-at.s: Add extra .byte directives so that the
foo symbol does not appear to point half way through an
instruction.
* gas/arm/backslash-at.d: Update expected disassembly.
* gas/i386/ilp32/x86-64-opcode-inval-intel.d: Likewise.
* gas/i386/ilp32/x86-64-opcode-inval.d: Likewise.
* gas/i386/x86-64-opcode-inval-intel.d: Likewise.
* gas/i386/x86-64-opcode-inval.d: Likewise.
2015-06-19 Peter Bergner <bergner@vnet.ibm.com>
* gas/ppc/power8.d: Fixup rfebb test results.

View file

@ -5,13 +5,13 @@
Disassembly of section .text:
0+000 <.*>.*(615c|5c61).*
0+002 <foo> e3a00000 mov r0, #0
0+006 <foo\+0x4> e3a00000 mov r0, #0
0+00a <foo\+0x8> e3a00000 mov r0, #0
0+00e <foo\+0xc> e3a00001 mov r0, #1
0+012 <foo\+0x10> e3a00001 mov r0, #1
0+016 <foo\+0x14> e3a00001 mov r0, #1
0+01a <foo\+0x18> e3a00002 mov r0, #2
0+01e <foo\+0x1c> e3a00002 mov r0, #2
0+022 <foo\+0x20> e3a00002 mov r0, #2
0+004 <foo> e3a00000 mov r0, #0
0+008 <foo\+0x4> e3a00000 mov r0, #0
0+00c <foo\+0x8> e3a00000 mov r0, #0
0+010 <foo\+0xc> e3a00001 mov r0, #1
0+014 <foo\+0x10> e3a00001 mov r0, #1
0+018 <foo\+0x14> e3a00001 mov r0, #1
0+01c <foo\+0x18> e3a00002 mov r0, #2
0+020 <foo\+0x1c> e3a00002 mov r0, #2
0+024 <foo\+0x20> e3a00002 mov r0, #2
#...

View file

@ -6,9 +6,10 @@
mov r0, #\@ @comment
.endm
.byte '\\
.byte '\a
.byte '\\
.byte '\a
.byte 0
.byte 0
foo:
bar
bar

View file

@ -12,26 +12,26 @@ Disassembly of section .text:
0+1 <aad0>:
[ ]*[a-f0-9]+: d5 \(bad\)
[ ]*[a-f0-9]+: 0a d5 or dl,ch
[ ]*[a-f0-9]+: 0a .byte 0xa
0+3 <aad1>:
[ ]*[a-f0-9]+: d5 \(bad\)
[ ]*[a-f0-9]+: 02 d4 add dl,ah
[ ]*[a-f0-9]+: 02 .byte 0x2
0+5 <aam0>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 0a d4 or dl,ah
[ ]*[a-f0-9]+: 0a .byte 0xa
0+7 <aam1>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 02 3f add bh,BYTE PTR \[rdi\]
[ ]*[a-f0-9]+: 02 .byte 0x2
0+9 <aas>:
[ ]*[a-f0-9]+: 3f \(bad\)
0+a <bound>:
[ ]*[a-f0-9]+: 62 \(bad\)
[ ]*[a-f0-9]+: 10 27 adc BYTE PTR \[rdi\],ah
[ ]*[a-f0-9]+: 62 .byte 0x62
[ ]*[a-f0-9]+: 10 .byte 0x10
0+c <daa>:
[ ]*[a-f0-9]+: 27 \(bad\)

View file

@ -12,26 +12,26 @@ Disassembly of section .text:
0+1 <aad0>:
[ ]*[a-f0-9]+: d5 \(bad\)
[ ]*[a-f0-9]+: 0a d5 or %ch,%dl
[ ]*[a-f0-9]+: 0a .byte 0xa
0+3 <aad1>:
[ ]*[a-f0-9]+: d5 \(bad\)
[ ]*[a-f0-9]+: 02 d4 add %ah,%dl
[ ]*[a-f0-9]+: 02 .byte 0x2
0+5 <aam0>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 0a d4 or %ah,%dl
[ ]*[a-f0-9]+: 0a .byte 0xa
0+7 <aam1>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 02 3f add \(%rdi\),%bh
[ ]*[a-f0-9]+: 02 .byte 0x2
0+9 <aas>:
[ ]*[a-f0-9]+: 3f \(bad\)
0+a <bound>:
[ ]*[a-f0-9]+: 62 \(bad\)
[ ]*[a-f0-9]+: 10 27 adc %ah,\(%rdi\)
[ ]*[a-f0-9]+: 62 .byte 0x62
[ ]*[a-f0-9]+: 10 .byte 0x10
0+c <daa>:
[ ]*[a-f0-9]+: 27 \(bad\)

View file

@ -12,26 +12,26 @@ Disassembly of section .text:
0+1 <aad0>:
[ ]*[a-f0-9]+: d5 \(bad\)
[ ]*[a-f0-9]+: 0a d5 or dl,ch
[ ]*[a-f0-9]+: 0a .byte 0xa
0+3 <aad1>:
[ ]*[a-f0-9]+: d5 \(bad\)
[ ]*[a-f0-9]+: 02 d4 add dl,ah
[ ]*[a-f0-9]+: 02 .byte 0x2
0+5 <aam0>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 0a d4 or dl,ah
[ ]*[a-f0-9]+: 0a .byte 0xa
0+7 <aam1>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 02 3f add bh,BYTE PTR \[rdi\]
[ ]*[a-f0-9]+: 02 .byte 0x2
0+9 <aas>:
[ ]*[a-f0-9]+: 3f \(bad\)
0+a <bound>:
[ ]*[a-f0-9]+: 62 \(bad\)
[ ]*[a-f0-9]+: 10 27 adc BYTE PTR \[rdi\],ah
[ ]*[a-f0-9]+: 62 .byte 0x62
[ ]*[a-f0-9]+: 10 .byte 0x10
0+c <daa>:
[ ]*[a-f0-9]+: 27 \(bad\)

View file

@ -11,26 +11,26 @@ Disassembly of section .text:
0+1 <aad0>:
[ ]*[a-f0-9]+: d5 \(bad\)
[ ]*[a-f0-9]+: 0a d5 or %ch,%dl
[ ]*[a-f0-9]+: 0a .byte 0xa
0+3 <aad1>:
[ ]*[a-f0-9]+: d5 \(bad\)
[ ]*[a-f0-9]+: 02 d4 add %ah,%dl
[ ]*[a-f0-9]+: 02 .byte 0x2
0+5 <aam0>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 0a d4 or %ah,%dl
[ ]*[a-f0-9]+: 0a .byte 0xa
0+7 <aam1>:
[ ]*[a-f0-9]+: d4 \(bad\)
[ ]*[a-f0-9]+: 02 3f add \(%rdi\),%bh
[ ]*[a-f0-9]+: 02 .byte 0x2
0+9 <aas>:
[ ]*[a-f0-9]+: 3f \(bad\)
0+a <bound>:
[ ]*[a-f0-9]+: 62 \(bad\)
[ ]*[a-f0-9]+: 10 27 adc %ah,\(%rdi\)
[ ]*[a-f0-9]+: 62 .byte 0x62
[ ]*[a-f0-9]+: 10 .byte 0x10
0+c <daa>:
[ ]*[a-f0-9]+: 27 \(bad\)

View file

@ -1,3 +1,7 @@
2015-06-22 Nick Clifton <nickc@redhat.com>
* dis-asm.h (struct disassemble_info): Add stop_vma field.
2015-05-28 Catherine Moore <clm@codesourcery.com>
include/

View file

@ -212,6 +212,14 @@ typedef struct disassemble_info
/* Command line options specific to the target disassembler. */
char * disassembler_options;
/* If non-zero then try not disassemble beyond this address, even if
there are values left in the buffer. This address is the address
of the nearest symbol forwards from the start of the disassembly,
and it is assumed that it lies on the boundary between instructions.
If an instruction spans this address then this is an error in the
file being disassembled. */
bfd_vma stop_vma;
} disassemble_info;

View file

@ -1,3 +1,17 @@
2015-06-22 Nick Clifton <nickc@redhat.com>
* dis-buf.c (buffer_read_memory): Fail is stop_vma is set and the
requested region lies beyond it.
* bfin-dis.c (print_insn_bfin): Ignore sysop instructions when
looking for 32-bit insns.
* mcore-dis.c (print_insn_mcore): Disable stop_vma when reading
data.
* sh-dis.c (print_insn_sh): Likewise.
* tic6x-dis.c (print_insn_tic6x): Disable stop_vma when reading
blocks of instructions.
* vax-dis.c (print_insn_vax): Check that the requested address
does not clash with the stop_vma.
2015-06-19 Peter Bergner <bergner@vnet.ibm.com>
* ppc-dis.h (skip_optional_operands): Use ppc_optional_operand_value.

View file

@ -4664,7 +4664,7 @@ _print_insn_bfin (bfd_vma pc, disassemble_info *outf)
return -1;
priv->iw0 = iw0;
if ((iw0 & 0xc000) == 0xc000)
if (((iw0 & 0xc000) == 0xc000) && ((iw0 & 0xff00) != 0xf800))
{
/* 32-bit insn. */
if (ifetch (pc + 2, outf, &iw1))

View file

@ -38,7 +38,9 @@ buffer_read_memory (bfd_vma memaddr,
if (memaddr < info->buffer_vma
|| memaddr - info->buffer_vma > max_addr_offset
|| memaddr - info->buffer_vma + end_addr_offset > max_addr_offset)
|| memaddr - info->buffer_vma + end_addr_offset > max_addr_offset
|| (info->stop_vma && (memaddr >= info->stop_vma
|| memaddr + end_addr_offset > info->stop_vma)))
/* Out of bounds. Use EIO because GDB uses it. */
return EIO;
memcpy (myaddr, info->buffer + octets, length);

View file

@ -88,9 +88,8 @@ static const char *crname[] = {
static const unsigned isiz[] = { 2, 0, 1, 0 };
int
print_insn_mcore (memaddr, info)
bfd_vma memaddr;
struct disassemble_info *info;
print_insn_mcore (bfd_vma memaddr,
struct disassemble_info *info)
{
unsigned char ibytes[4];
fprintf_ftype print_func = info->fprintf_func;
@ -233,6 +232,9 @@ print_insn_mcore (memaddr, info)
val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
/* We are not reading an instruction, so allow
reads to extend beyond the next symbol. */
info->stop_vma = 0;
status = info->read_memory_func (val, ibytes, 4, info);
if (status != 0)
{
@ -263,6 +265,9 @@ print_insn_mcore (memaddr, info)
val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
/* We are not reading an instruction, so allow
reads to extend beyond the next symbol. */
info->stop_vma = 0;
status = info->read_memory_func (val, ibytes, 4, info);
if (status != 0)
{

View file

@ -905,6 +905,8 @@ print_insn_sh (bfd_vma memaddr, struct disassemble_info *info)
size = 2;
else
size = 4;
/* Not reading an instruction - disable stop_vma. */
info->stop_vma = 0;
status = info->read_memory_func (disp_pc_addr, bytes, size, info);
if (status == 0)
{

View file

@ -249,6 +249,9 @@ print_insn_tic6x (bfd_vma addr, struct disassemble_info *info)
fp_offset = addr & 0x1f;
fp_addr = addr - fp_offset;
/* Read in a block of instructions. Since there might be a
symbol in the middle of this block, disable stop_vma. */
info->stop_vma = 0;
status = info->read_memory_func (fp_addr, fp, 32, info);
if (status)
{

View file

@ -402,7 +402,8 @@ print_insn_vax (bfd_vma memaddr, disassemble_info *info)
argp = NULL;
/* Check if the info buffer has more than one byte left since
the last opcode might be a single byte with no argument data. */
if (info->buffer_length - (memaddr - info->buffer_vma) > 1)
if (info->buffer_length - (memaddr - info->buffer_vma) > 1
&& (info->stop_vma == 0 || memaddr < (info->stop_vma - 1)))
{
FETCH_DATA (info, buffer + 2);
}