PR 10288
* arm-dis.c (print_insn_coprocessor): Check that a user specified ARM architecture supports the matched instruction. (print_insn_arm): Likewise. (select_arm_features): New function. Fills in the fields of an arm_feature_set structure based on a given arm machine number. (print_insn): Initialise an arm_feature_set structure. * objdump.c (disassemble_bytes): Set the USER_SPECIFIED_MACHINE_TYPE flag in the disassemble_info structure if the user has invoked the -m switch. * doc/binutils.texi: Document the additional behaviour of objdump's -m switch for ARM targets. * dis-asm.h (USER_SPECIFIED_MACHINE_TYPE): New value for the flags field of struct disassemble_info. * gas/arm/align.s: Add labels so that COFF based targets can correctly locate THUMB code. * gas/arm/copro.d: Do not pass --architecture switch to objdump.
This commit is contained in:
parent
470c710ef0
commit
0313a2b8d2
10 changed files with 556 additions and 422 deletions
|
@ -1,8 +1,18 @@
|
||||||
|
2009-06-18 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
PR 10288
|
||||||
|
* objdump.c (disassemble_bytes): Set the
|
||||||
|
USER_SPECIFIED_MACHINE_TYPE flag in the disassemble_info structure
|
||||||
|
if the user has invoked the -m switch.
|
||||||
|
* doc/binutils.texi: Document the additional behaviour of
|
||||||
|
objdump's -m switch for ARM targets.
|
||||||
|
|
||||||
2009-06-18 Dave Korn <dave.korn.cygwin@gmail.com>
|
2009-06-18 Dave Korn <dave.korn.cygwin@gmail.com>
|
||||||
|
|
||||||
Merge cegcc and mingw32ce target name changes from CeGCC project.
|
* configure.in: Merge cegcc and mingw32ce target name changes from
|
||||||
|
CeGCC project.
|
||||||
|
|
||||||
2007-12-25 Pedro Alves <pedro_alves@portugalmail.pt>
|
2007-12-25 Pedro Alves <pedro_alves@portugalmail.pt>
|
||||||
|
|
||||||
* configure.in: Add arm*-*-cegcc* and arm*-*-mingw32ce* targets.
|
* configure.in: Add arm*-*-cegcc* and arm*-*-mingw32ce* targets.
|
||||||
* configure: Regenerate.
|
* configure: Regenerate.
|
||||||
|
|
|
@ -1801,6 +1801,10 @@ expected to contain instructions.
|
||||||
Like @option{-d}, but disassemble the contents of all sections, not just
|
Like @option{-d}, but disassemble the contents of all sections, not just
|
||||||
those expected to contain instructions.
|
those expected to contain instructions.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
@item --prefix-addresses
|
@item --prefix-addresses
|
||||||
When disassembling, print the complete address on each line. This is
|
When disassembling, print the complete address on each line. This is
|
||||||
the older disassembly format.
|
the older disassembly format.
|
||||||
|
@ -1884,6 +1888,13 @@ can be useful when disassembling object files which do not describe
|
||||||
architecture information, such as S-records. You can list the available
|
architecture information, such as S-records. You can list the available
|
||||||
architectures with the @option{-i} option.
|
architectures with the @option{-i} option.
|
||||||
|
|
||||||
|
If the target is an ARM architecture then this switch has an
|
||||||
|
additional effect. It restricts the disassembly to only those
|
||||||
|
instructions supported by the architecture specified by @var{machine}.
|
||||||
|
If it is necessary to use this switch because the input file does not
|
||||||
|
contain any architecture information, but it is also desired to
|
||||||
|
disassemble all the instructions use @option{-marm}.
|
||||||
|
|
||||||
@item -M @var{options}
|
@item -M @var{options}
|
||||||
@itemx --disassembler-options=@var{options}
|
@itemx --disassembler-options=@var{options}
|
||||||
Pass target specific information to the disassembler. Only supported on
|
Pass target specific information to the disassembler. Only supported on
|
||||||
|
|
|
@ -1526,6 +1526,8 @@ disassemble_bytes (struct disassemble_info * info,
|
||||||
info->bytes_per_line = 0;
|
info->bytes_per_line = 0;
|
||||||
info->bytes_per_chunk = 0;
|
info->bytes_per_chunk = 0;
|
||||||
info->flags = disassemble_all ? DISASSEMBLE_DATA : 0;
|
info->flags = disassemble_all ? DISASSEMBLE_DATA : 0;
|
||||||
|
if (machine)
|
||||||
|
info->flags |= USER_SPECIFIED_MACHINE_TYPE;
|
||||||
|
|
||||||
if (info->disassembler_needs_relocs
|
if (info->disassembler_needs_relocs
|
||||||
&& (bfd_get_file_flags (aux->abfd) & EXEC_P) == 0
|
&& (bfd_get_file_flags (aux->abfd) & EXEC_P) == 0
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2009-06-18 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
PR 10288
|
||||||
|
* gas/arm/align.s: Add labels so that COFF based targets can
|
||||||
|
correctly locate THUMB code.
|
||||||
|
* gas/arm/copro.d: Do not pass --architecture switch to objdump.
|
||||||
|
|
||||||
2009-06-15 Nick Clifton <nickc@redhat.com>
|
2009-06-15 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
PR gas/10186
|
PR gas/10186
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
|
.global foo
|
||||||
|
foo:
|
||||||
nop
|
nop
|
||||||
mov r1,r2
|
mov r1,r2
|
||||||
.p2align 4
|
.p2align 4
|
||||||
|
@ -7,6 +9,8 @@
|
||||||
.p2align 3
|
.p2align 3
|
||||||
|
|
||||||
.arm
|
.arm
|
||||||
|
.global bar
|
||||||
|
bar:
|
||||||
nop
|
nop
|
||||||
mov r1,r2
|
mov r1,r2
|
||||||
.p2align 4
|
.p2align 4
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#objdump: -dr --prefix-addresses --show-raw-insn --architecture=armv5te
|
#objdump: -dr --prefix-addresses --show-raw-insn
|
||||||
#name: ARM CoProcessor Instructions
|
#name: ARM CoProcessor Instructions
|
||||||
#as: -march=armv5te -EL
|
#as: -march=armv5te -EL
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
|
2009-06-18 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* dis-asm.h (USER_SPECIFIED_MACHINE_TYPE): New value for the flags
|
||||||
|
field of struct disassemble_info.
|
||||||
|
|
||||||
2009-06-09 Ian Lance Taylor <ian@airs.com>
|
2009-06-09 Ian Lance Taylor <ian@airs.com>
|
||||||
|
|
||||||
* ansidecl.h (ATTRIBUTE_UNUSED_LABEL): Define for C++.
|
* ansidecl.h (ATTRIBUTE_UNUSED_LABEL): Define for C++.
|
||||||
|
|
||||||
2009-06-15 Nick Clifton <nickc@redhat.com>
|
2009-06-15 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* dis-asm.h (struct disassemble_info): New value for the flags
|
* dis-asm.h (DISASSEMBLE_DATA): New value for the flags field of
|
||||||
field.
|
struct disassemble_info.
|
||||||
|
|
||||||
2009-06-02 Ian Lance Taylor <iant@google.com>
|
2009-06-02 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,9 @@ typedef struct disassemble_info
|
||||||
#define INSN_HAS_RELOC (1 << 31)
|
#define INSN_HAS_RELOC (1 << 31)
|
||||||
/* Set if the user has requested the disassembly of data as well as code. */
|
/* Set if the user has requested the disassembly of data as well as code. */
|
||||||
#define DISASSEMBLE_DATA (1 << 30)
|
#define DISASSEMBLE_DATA (1 << 30)
|
||||||
|
/* Set if the user has specifically set the machine type encoded in the
|
||||||
|
mach field of this structure. */
|
||||||
|
#define USER_SPECIFIED_MACHINE_TYPE (1 << 29)
|
||||||
|
|
||||||
/* Use internally by the target specific disassembly code. */
|
/* Use internally by the target specific disassembly code. */
|
||||||
void *private_data;
|
void *private_data;
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
2009-06-18 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
PR 10288
|
||||||
|
* arm-dis.c (print_insn_coprocessor): Check that a user specified
|
||||||
|
ARM architecture supports the matched instruction.
|
||||||
|
(print_insn_arm): Likewise.
|
||||||
|
(select_arm_features): New function. Fills in the fields of an
|
||||||
|
arm_feature_set structure based on a given arm machine number.
|
||||||
|
(print_insn): Initialise an arm_feature_set structure.
|
||||||
|
|
||||||
2009-06-16 Maciej W. Rozycki <macro@linux-mips.org>
|
2009-06-16 Maciej W. Rozycki <macro@linux-mips.org>
|
||||||
|
|
||||||
* vax-dis.c (is_function_entry): Return success for synthetic
|
* vax-dis.c (is_function_entry): Return success for synthetic
|
||||||
|
|
|
@ -1635,6 +1635,8 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
|
||||||
|
|
||||||
for (insn = coprocessor_opcodes; insn->assembler; insn++)
|
for (insn = coprocessor_opcodes; insn->assembler; insn++)
|
||||||
{
|
{
|
||||||
|
const char *c;
|
||||||
|
|
||||||
if (insn->value == FIRST_IWMMXT_INSN
|
if (insn->value == FIRST_IWMMXT_INSN
|
||||||
&& info->mach != bfd_mach_arm_XScale
|
&& info->mach != bfd_mach_arm_XScale
|
||||||
&& info->mach != bfd_mach_arm_iWMMXt
|
&& info->mach != bfd_mach_arm_iWMMXt
|
||||||
|
@ -1671,9 +1673,12 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
|
||||||
cond = 16;
|
cond = 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((given & mask) == value)
|
|
||||||
{
|
if ((given & mask) != value)
|
||||||
const char *c;
|
continue;
|
||||||
|
|
||||||
|
if ((insn->arch & ((arm_feature_set *) info->private_data)->coproc) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (c = insn->assembler; *c; c++)
|
for (c = insn->assembler; *c; c++)
|
||||||
{
|
{
|
||||||
|
@ -1815,6 +1820,7 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Q':
|
case 'Q':
|
||||||
switch (given & 0x00408000)
|
switch (given & 0x00408000)
|
||||||
{
|
{
|
||||||
|
@ -1832,6 +1838,7 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R':
|
case 'R':
|
||||||
switch (given & 0x60)
|
switch (given & 0x60)
|
||||||
{
|
{
|
||||||
|
@ -2066,7 +2073,6 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
|
||||||
switch (puw_bits)
|
switch (puw_bits)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
/* fall through */
|
|
||||||
case 3:
|
case 3:
|
||||||
func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
|
func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
|
||||||
if (imm4)
|
if (imm4)
|
||||||
|
@ -2074,11 +2080,8 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
/* fall through */
|
|
||||||
case 5:
|
case 5:
|
||||||
/* fall through */
|
|
||||||
case 6:
|
case 6:
|
||||||
/* fall through */
|
|
||||||
case 7:
|
case 7:
|
||||||
func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
|
func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
|
||||||
if (imm4 > 0)
|
if (imm4 > 0)
|
||||||
|
@ -2112,7 +2115,6 @@ print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2221,7 +2223,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
|
||||||
{
|
{
|
||||||
if ((given & 0xef000000) == 0xef000000)
|
if ((given & 0xef000000) == 0xef000000)
|
||||||
{
|
{
|
||||||
/* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
|
/* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
|
||||||
unsigned long bit28 = given & (1 << 28);
|
unsigned long bit28 = given & (1 << 28);
|
||||||
|
|
||||||
given &= 0x00ffffff;
|
given &= 0x00ffffff;
|
||||||
|
@ -2687,13 +2689,18 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
|
||||||
&& info->mach != bfd_mach_arm_iWMMXt)
|
&& info->mach != bfd_mach_arm_iWMMXt)
|
||||||
insn = insn + IWMMXT_INSN_COUNT;
|
insn = insn + IWMMXT_INSN_COUNT;
|
||||||
|
|
||||||
if ((given & insn->mask) == insn->value
|
if ((given & insn->mask) != insn->value)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((insn->arch & ((arm_feature_set *) info->private_data)->core) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Special case: an instruction with all bits set in the condition field
|
/* Special case: an instruction with all bits set in the condition field
|
||||||
(0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
|
(0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
|
||||||
or by the catchall at the end of the table. */
|
or by the catchall at the end of the table. */
|
||||||
&& ((given & 0xF0000000) != 0xF0000000
|
if ((given & 0xF0000000) != 0xF0000000
|
||||||
|| (insn->mask & 0xF0000000) == 0xF0000000
|
|| (insn->mask & 0xF0000000) == 0xF0000000
|
||||||
|| (insn->mask == 0 && insn->value == 0)))
|
|| (insn->mask == 0 && insn->value == 0))
|
||||||
{
|
{
|
||||||
const char *c;
|
const char *c;
|
||||||
|
|
||||||
|
@ -3967,6 +3974,47 @@ get_sym_code_type (struct disassemble_info *info, int n,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given a bfd_mach_arm_XXX value, this function fills in the fields
|
||||||
|
of the supplied arm_feature_set structure with bitmasks indicating
|
||||||
|
the support base architectures and coprocessor extensions.
|
||||||
|
|
||||||
|
FIXME: This could more efficiently implemented as a constant array,
|
||||||
|
although it would also be less robust. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
select_arm_features (unsigned long mach,
|
||||||
|
arm_feature_set * features)
|
||||||
|
{
|
||||||
|
#undef ARM_FEATURE
|
||||||
|
#define ARM_FEATURE(ARCH,CEXT) \
|
||||||
|
features->core = (ARCH); \
|
||||||
|
features->coproc = (CEXT) | FPU_FPA; \
|
||||||
|
return
|
||||||
|
|
||||||
|
switch (mach)
|
||||||
|
{
|
||||||
|
case bfd_mach_arm_2: ARM_ARCH_V2;
|
||||||
|
case bfd_mach_arm_2a: ARM_ARCH_V2S;
|
||||||
|
case bfd_mach_arm_3: ARM_ARCH_V3;
|
||||||
|
case bfd_mach_arm_3M: ARM_ARCH_V3M;
|
||||||
|
case bfd_mach_arm_4: ARM_ARCH_V4;
|
||||||
|
case bfd_mach_arm_4T: ARM_ARCH_V4T;
|
||||||
|
case bfd_mach_arm_5: ARM_ARCH_V5;
|
||||||
|
case bfd_mach_arm_5T: ARM_ARCH_V5T;
|
||||||
|
case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
|
||||||
|
case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
|
||||||
|
case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
|
||||||
|
case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
|
||||||
|
case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
|
||||||
|
/* If the machine type is unknown allow all
|
||||||
|
architecture types and all extensions. */
|
||||||
|
case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* NOTE: There are no checks in these routines that
|
/* NOTE: There are no checks in these routines that
|
||||||
the relevant number of data bytes exist. */
|
the relevant number of data bytes exist. */
|
||||||
|
|
||||||
|
@ -3991,6 +4039,40 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
|
||||||
info->disassembler_options = NULL;
|
info->disassembler_options = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PR 10288: Control which instructions will be disassembled. */
|
||||||
|
if (info->private_data == NULL)
|
||||||
|
{
|
||||||
|
static arm_feature_set features;
|
||||||
|
|
||||||
|
if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
|
||||||
|
/* If the user did not use the -m command line switch then default to
|
||||||
|
disassembling all types of ARM instruction.
|
||||||
|
|
||||||
|
The info->mach value has to be ignored as this will be based on
|
||||||
|
the default archictecture for the target and/or hints in the notes
|
||||||
|
section, but it will never be greater than the current largest arm
|
||||||
|
machine value (iWMMXt2), which is only equivalent to the V5TE
|
||||||
|
architecture. ARM architectures have advanced beyond the machine
|
||||||
|
value encoding, and these newer architectures would be ignored if
|
||||||
|
the machine value was used.
|
||||||
|
|
||||||
|
Ie the -m switch is used to restrict which instructions will be
|
||||||
|
disassembled. If it is necessary to use the -m switch to tell
|
||||||
|
objdump that an ARM binary is being disassembled, eg because the
|
||||||
|
input is a raw binary file, but it is also desired to disassemble
|
||||||
|
all ARM instructions then use "-marm". This will select the
|
||||||
|
"unknown" arm architecture which is compatible with any ARM
|
||||||
|
instruction. */
|
||||||
|
info->mach = bfd_mach_arm_unknown;
|
||||||
|
|
||||||
|
/* Compute the architecture bitmask from the machine number.
|
||||||
|
Note: This assumes that the machine number will not change
|
||||||
|
during disassembly.... */
|
||||||
|
select_arm_features (info->mach, & features);
|
||||||
|
|
||||||
|
info->private_data = & features;
|
||||||
|
}
|
||||||
|
|
||||||
/* Decide if our code is going to be little-endian, despite what the
|
/* Decide if our code is going to be little-endian, despite what the
|
||||||
function argument might say. */
|
function argument might say. */
|
||||||
little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
|
little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
|
||||||
|
@ -4146,7 +4228,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
|
||||||
info->bytes_per_chunk = 4;
|
info->bytes_per_chunk = 4;
|
||||||
size = 4;
|
size = 4;
|
||||||
|
|
||||||
status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
|
status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
|
||||||
if (little_code)
|
if (little_code)
|
||||||
given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
|
given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
|
||||||
else
|
else
|
||||||
|
@ -4176,7 +4258,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
|
||||||
|| (given & 0xF800) == 0xF000
|
|| (given & 0xF800) == 0xF000
|
||||||
|| (given & 0xF800) == 0xE800)
|
|| (given & 0xF800) == 0xE800)
|
||||||
{
|
{
|
||||||
status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
|
status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
|
||||||
if (little_code)
|
if (little_code)
|
||||||
given = (b[0]) | (b[1] << 8) | (given << 16);
|
given = (b[0]) | (b[1] << 8) | (given << 16);
|
||||||
else
|
else
|
||||||
|
@ -4188,7 +4270,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifthen_address != pc)
|
if (ifthen_address != pc)
|
||||||
find_ifthen_state(pc, info, little_code);
|
find_ifthen_state (pc, info, little_code);
|
||||||
|
|
||||||
if (ifthen_state)
|
if (ifthen_state)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue