Fix handling of BLX instruction to conform to Operations definition in the
ARM ARM.
This commit is contained in:
parent
2984e11475
commit
baf0cc5e96
|
@ -1,5 +1,5 @@
|
||||||
/* Instruction printing code for the ARM
|
/* Instruction printing code for the ARM
|
||||||
Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
|
Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
|
||||||
Modification by James G. Smith (jsmith@cygnus.co.uk)
|
Modification by James G. Smith (jsmith@cygnus.co.uk)
|
||||||
|
@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
#include "libcoff.h"
|
#include "libcoff.h"
|
||||||
#include "opintl.h"
|
#include "opintl.h"
|
||||||
|
|
||||||
/* FIXME: This shouldn't be done here */
|
/* FIXME: This shouldn't be done here. */
|
||||||
#include "elf-bfd.h"
|
#include "elf-bfd.h"
|
||||||
#include "elf/internal.h"
|
#include "elf/internal.h"
|
||||||
#include "elf/arm.h"
|
#include "elf/arm.h"
|
||||||
|
@ -99,15 +99,16 @@ int get_arm_regnames (int option, const char **setname,
|
||||||
const char **setdescription,
|
const char **setdescription,
|
||||||
const char ***register_names);
|
const char ***register_names);
|
||||||
|
|
||||||
/* Functions. */
|
/* Functions. */
|
||||||
int
|
int
|
||||||
get_arm_regname_num_options (void)
|
get_arm_regname_num_options ()
|
||||||
{
|
{
|
||||||
return NUM_ARM_REGNAMES;
|
return NUM_ARM_REGNAMES;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
set_arm_regname_option (int option)
|
set_arm_regname_option (option)
|
||||||
|
int option;
|
||||||
{
|
{
|
||||||
int old = regname_selected;
|
int old = regname_selected;
|
||||||
regname_selected = option;
|
regname_selected = option;
|
||||||
|
@ -115,9 +116,11 @@ set_arm_regname_option (int option)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
get_arm_regnames (int option, const char **setname,
|
get_arm_regnames (option, setname, setdescription, register_names)
|
||||||
const char **setdescription,
|
int option;
|
||||||
const char ***register_names)
|
const char **setname;
|
||||||
|
const char **setdescription;
|
||||||
|
const char ***register_names;
|
||||||
{
|
{
|
||||||
*setname = regnames[option].name;
|
*setname = regnames[option].name;
|
||||||
*setdescription = regnames[option].description;
|
*setdescription = regnames[option].description;
|
||||||
|
@ -161,6 +164,7 @@ arm_decode_shift (given, func, stream)
|
||||||
|
|
||||||
/* Print one instruction from PC on INFO->STREAM.
|
/* Print one instruction from PC on INFO->STREAM.
|
||||||
Return the size of the instruction (always 4 on ARM). */
|
Return the size of the instruction (always 4 on ARM). */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_insn_arm (pc, info, given)
|
print_insn_arm (pc, info, given)
|
||||||
bfd_vma pc;
|
bfd_vma pc;
|
||||||
|
@ -200,7 +204,7 @@ print_insn_arm (pc, info, given)
|
||||||
if ((given & 0x00800000) == 0)
|
if ((given & 0x00800000) == 0)
|
||||||
offset = - offset;
|
offset = - offset;
|
||||||
|
|
||||||
/* pre-indexed */
|
/* Pre-indexed. */
|
||||||
func (stream, ", #%d]", offset);
|
func (stream, ", #%d]", offset);
|
||||||
|
|
||||||
offset += pc + 8;
|
offset += pc + 8;
|
||||||
|
@ -217,7 +221,8 @@ print_insn_arm (pc, info, given)
|
||||||
/* Post indexed. */
|
/* Post indexed. */
|
||||||
func (stream, "], #%d", offset);
|
func (stream, "], #%d", offset);
|
||||||
|
|
||||||
offset = pc + 8; /* ie ignore the offset. */
|
/* ie ignore the offset. */
|
||||||
|
offset = pc + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (stream, "\t; ");
|
func (stream, "\t; ");
|
||||||
|
@ -740,6 +745,7 @@ print_insn_arm (pc, info, given)
|
||||||
|
|
||||||
/* Print one instruction from PC on INFO->STREAM.
|
/* Print one instruction from PC on INFO->STREAM.
|
||||||
Return the size of the instruction. */
|
Return the size of the instruction. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_insn_thumb (pc, info, given)
|
print_insn_thumb (pc, info, given)
|
||||||
bfd_vma pc;
|
bfd_vma pc;
|
||||||
|
@ -765,26 +771,17 @@ print_insn_thumb (pc, info, given)
|
||||||
info->bytes_per_line = 4;
|
info->bytes_per_line = 4;
|
||||||
|
|
||||||
offset = BDISP23 (given);
|
offset = BDISP23 (given);
|
||||||
|
offset = offset * 2 + pc + 4;
|
||||||
|
|
||||||
if ((given & 0x10000000) == 0)
|
if ((given & 0x10000000) == 0)
|
||||||
{
|
{
|
||||||
func (stream, "blx\t");
|
func (stream, "blx\t");
|
||||||
|
offset &= 0xfffffffc;
|
||||||
/* The spec says that bit 1 of the branch's destination
|
|
||||||
address comes from bit 1 of the instruction's
|
|
||||||
address and not from the offset in the instruction. */
|
|
||||||
if (offset & 0x1)
|
|
||||||
{
|
|
||||||
/* func (stream, "*malformed!* "); */
|
|
||||||
offset &= ~ 0x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset |= ((pc & 0x2) >> 1);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
func (stream, "bl\t");
|
func (stream, "bl\t");
|
||||||
|
|
||||||
info->print_address_func (offset * 2 + pc + 4, info);
|
info->print_address_func (offset, info);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -988,6 +985,7 @@ print_insn_thumb (pc, info, given)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse an individual disassembler option. */
|
/* Parse an individual disassembler option. */
|
||||||
|
|
||||||
void
|
void
|
||||||
parse_arm_disassembler_option (option)
|
parse_arm_disassembler_option (option)
|
||||||
char * option;
|
char * option;
|
||||||
|
@ -1022,6 +1020,7 @@ parse_arm_disassembler_option (option)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse the string of disassembler options, spliting it at whitespaces. */
|
/* Parse the string of disassembler options, spliting it at whitespaces. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_disassembler_options (options)
|
parse_disassembler_options (options)
|
||||||
char * options;
|
char * options;
|
||||||
|
@ -1050,6 +1049,7 @@ parse_disassembler_options (options)
|
||||||
|
|
||||||
/* 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. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_insn (pc, info, little)
|
print_insn (pc, info, little)
|
||||||
bfd_vma pc;
|
bfd_vma pc;
|
||||||
|
|
Loading…
Reference in New Issue