mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-10 19:24:29 +00:00
* config/tc-hppa.c (md_apply_fix): Do nothing for an out of range
PC relative call since those only occur in cases where the linker can fix them up. (hppa_force_relocation): Force relocations for out of range PC relative calls.
This commit is contained in:
parent
fa9dea803d
commit
4829cd65a7
@ -1,3 +1,11 @@
|
|||||||
|
Wed May 3 13:08:53 1995 Jeff Law (law@snake.cs.utah.edu)
|
||||||
|
|
||||||
|
* config/tc-hppa.c (md_apply_fix): Do nothing for an out of range
|
||||||
|
PC relative call since those only occur in cases where the linker
|
||||||
|
can fix them up.
|
||||||
|
(hppa_force_relocation): Force relocations for out of range PC
|
||||||
|
relative calls.
|
||||||
|
|
||||||
Tue May 2 16:34:47 1995 Jeff Law (law@snake.cs.utah.edu)
|
Tue May 2 16:34:47 1995 Jeff Law (law@snake.cs.utah.edu)
|
||||||
|
|
||||||
* configure (hppa*-*-lites*): Handle just like hppa*-*-*elf*.
|
* configure (hppa*-*-lites*): Handle just like hppa*-*-*elf*.
|
||||||
|
@ -236,9 +236,9 @@ struct pa_it
|
|||||||
handles the L/R notation and returns the correct
|
handles the L/R notation and returns the correct
|
||||||
value to put into the instruction register field.
|
value to put into the instruction register field.
|
||||||
The correct value to put into the instruction is
|
The correct value to put into the instruction is
|
||||||
encoded in the structure 'pa_89_fp_reg_struct'. */
|
encoded in the structure 'pa_11_fp_reg_struct'. */
|
||||||
|
|
||||||
struct pa_89_fp_reg_struct
|
struct pa_11_fp_reg_struct
|
||||||
{
|
{
|
||||||
/* The register number. */
|
/* The register number. */
|
||||||
char number_part;
|
char number_part;
|
||||||
@ -499,9 +499,9 @@ static void pa_spnum PARAMS ((int));
|
|||||||
static void pa_subspace PARAMS ((int));
|
static void pa_subspace PARAMS ((int));
|
||||||
static void pa_param PARAMS ((int));
|
static void pa_param PARAMS ((int));
|
||||||
static void pa_undefine_label PARAMS ((void));
|
static void pa_undefine_label PARAMS ((void));
|
||||||
static int need_89_opcode PARAMS ((struct pa_it *,
|
static int need_pa11_opcode PARAMS ((struct pa_it *,
|
||||||
struct pa_89_fp_reg_struct *));
|
struct pa_11_fp_reg_struct *));
|
||||||
static int pa_parse_number PARAMS ((char **, struct pa_89_fp_reg_struct *));
|
static int pa_parse_number PARAMS ((char **, struct pa_11_fp_reg_struct *));
|
||||||
static label_symbol_struct *pa_get_label PARAMS ((void));
|
static label_symbol_struct *pa_get_label PARAMS ((void));
|
||||||
static sd_chain_struct *create_new_space PARAMS ((char *, int, int,
|
static sd_chain_struct *create_new_space PARAMS ((char *, int, int,
|
||||||
int, int, int,
|
int, int, int,
|
||||||
@ -562,10 +562,6 @@ static struct call_info *last_call_info;
|
|||||||
/* The last call description (for actual calls). */
|
/* The last call description (for actual calls). */
|
||||||
static struct call_desc last_call_desc;
|
static struct call_desc last_call_desc;
|
||||||
|
|
||||||
/* Relaxation isn't supported for the PA yet. */
|
|
||||||
const relax_typeS md_relax_table[] =
|
|
||||||
{0};
|
|
||||||
|
|
||||||
/* Jumps are always the same size -- one instruction. */
|
/* Jumps are always the same size -- one instruction. */
|
||||||
int md_short_jump_size = 4;
|
int md_short_jump_size = 4;
|
||||||
int md_long_jump_size = 4;
|
int md_long_jump_size = 4;
|
||||||
@ -1265,6 +1261,10 @@ md_begin ()
|
|||||||
last_call_info = NULL;
|
last_call_info = NULL;
|
||||||
call_info_root = NULL;
|
call_info_root = NULL;
|
||||||
|
|
||||||
|
/* Set the default machine type. */
|
||||||
|
if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 10))
|
||||||
|
as_warn ("could not set architecture and machine");
|
||||||
|
|
||||||
/* Folding of text and data segments fails miserably on the PA.
|
/* Folding of text and data segments fails miserably on the PA.
|
||||||
Warn user and disable "-R" option. */
|
Warn user and disable "-R" option. */
|
||||||
if (flag_readonly_data_in_text)
|
if (flag_readonly_data_in_text)
|
||||||
@ -1451,6 +1451,14 @@ pa_ip (str)
|
|||||||
|
|
||||||
the_insn.reloc = R_HPPA_NONE;
|
the_insn.reloc = R_HPPA_NONE;
|
||||||
|
|
||||||
|
/* If this instruction is specific to a particular architecture,
|
||||||
|
then set a new architecture. */
|
||||||
|
if (bfd_get_mach (stdoutput) < insn->arch)
|
||||||
|
{
|
||||||
|
if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, insn->arch))
|
||||||
|
as_warn ("could not update architecture and machine");
|
||||||
|
}
|
||||||
|
|
||||||
/* Build the opcode, checking as we go to make
|
/* Build the opcode, checking as we go to make
|
||||||
sure that the operands match. */
|
sure that the operands match. */
|
||||||
for (args = insn->args;; ++args)
|
for (args = insn->args;; ++args)
|
||||||
@ -2298,7 +2306,7 @@ pa_ip (str)
|
|||||||
/* Handle L/R register halves like 't'. */
|
/* Handle L/R register halves like 't'. */
|
||||||
case 'v':
|
case 'v':
|
||||||
{
|
{
|
||||||
struct pa_89_fp_reg_struct result;
|
struct pa_11_fp_reg_struct result;
|
||||||
|
|
||||||
pa_parse_number (&s, &result);
|
pa_parse_number (&s, &result);
|
||||||
CHECK_FIELD (result.number_part, 31, 0, 0);
|
CHECK_FIELD (result.number_part, 31, 0, 0);
|
||||||
@ -2307,7 +2315,7 @@ pa_ip (str)
|
|||||||
/* 0x30 opcodes are FP arithmetic operation opcodes
|
/* 0x30 opcodes are FP arithmetic operation opcodes
|
||||||
and need to be turned into 0x38 opcodes. This
|
and need to be turned into 0x38 opcodes. This
|
||||||
is not necessary for loads/stores. */
|
is not necessary for loads/stores. */
|
||||||
if (need_89_opcode (&the_insn, &result)
|
if (need_pa11_opcode (&the_insn, &result)
|
||||||
&& ((opcode & 0xfc000000) == 0x30000000))
|
&& ((opcode & 0xfc000000) == 0x30000000))
|
||||||
opcode |= 1 << 27;
|
opcode |= 1 << 27;
|
||||||
|
|
||||||
@ -2317,12 +2325,12 @@ pa_ip (str)
|
|||||||
/* Handle L/R register halves like 'b'. */
|
/* Handle L/R register halves like 'b'. */
|
||||||
case 'E':
|
case 'E':
|
||||||
{
|
{
|
||||||
struct pa_89_fp_reg_struct result;
|
struct pa_11_fp_reg_struct result;
|
||||||
|
|
||||||
pa_parse_number (&s, &result);
|
pa_parse_number (&s, &result);
|
||||||
CHECK_FIELD (result.number_part, 31, 0, 0);
|
CHECK_FIELD (result.number_part, 31, 0, 0);
|
||||||
opcode |= result.number_part << 21;
|
opcode |= result.number_part << 21;
|
||||||
if (need_89_opcode (&the_insn, &result))
|
if (need_pa11_opcode (&the_insn, &result))
|
||||||
{
|
{
|
||||||
opcode |= (result.l_r_select & 1) << 7;
|
opcode |= (result.l_r_select & 1) << 7;
|
||||||
opcode |= 1 << 27;
|
opcode |= 1 << 27;
|
||||||
@ -2333,12 +2341,12 @@ pa_ip (str)
|
|||||||
/* Handle L/R register halves like 'x'. */
|
/* Handle L/R register halves like 'x'. */
|
||||||
case 'X':
|
case 'X':
|
||||||
{
|
{
|
||||||
struct pa_89_fp_reg_struct result;
|
struct pa_11_fp_reg_struct result;
|
||||||
|
|
||||||
pa_parse_number (&s, &result);
|
pa_parse_number (&s, &result);
|
||||||
CHECK_FIELD (result.number_part, 31, 0, 0);
|
CHECK_FIELD (result.number_part, 31, 0, 0);
|
||||||
opcode |= (result.number_part & 0x1f) << 16;
|
opcode |= (result.number_part & 0x1f) << 16;
|
||||||
if (need_89_opcode (&the_insn, &result))
|
if (need_pa11_opcode (&the_insn, &result))
|
||||||
{
|
{
|
||||||
opcode |= (result.l_r_select & 1) << 12;
|
opcode |= (result.l_r_select & 1) << 12;
|
||||||
opcode |= 1 << 27;
|
opcode |= 1 << 27;
|
||||||
@ -2349,7 +2357,7 @@ pa_ip (str)
|
|||||||
/* Handle a 5 bit register field at 10. */
|
/* Handle a 5 bit register field at 10. */
|
||||||
case '4':
|
case '4':
|
||||||
{
|
{
|
||||||
struct pa_89_fp_reg_struct result;
|
struct pa_11_fp_reg_struct result;
|
||||||
|
|
||||||
pa_parse_number (&s, &result);
|
pa_parse_number (&s, &result);
|
||||||
CHECK_FIELD (result.number_part, 31, 0, 0);
|
CHECK_FIELD (result.number_part, 31, 0, 0);
|
||||||
@ -2364,7 +2372,7 @@ pa_ip (str)
|
|||||||
/* Handle a 5 bit register field at 15. */
|
/* Handle a 5 bit register field at 15. */
|
||||||
case '6':
|
case '6':
|
||||||
{
|
{
|
||||||
struct pa_89_fp_reg_struct result;
|
struct pa_11_fp_reg_struct result;
|
||||||
|
|
||||||
pa_parse_number (&s, &result);
|
pa_parse_number (&s, &result);
|
||||||
CHECK_FIELD (result.number_part, 31, 0, 0);
|
CHECK_FIELD (result.number_part, 31, 0, 0);
|
||||||
@ -2379,7 +2387,7 @@ pa_ip (str)
|
|||||||
/* Handle a 5 bit register field at 31. */
|
/* Handle a 5 bit register field at 31. */
|
||||||
case '7':
|
case '7':
|
||||||
{
|
{
|
||||||
struct pa_89_fp_reg_struct result;
|
struct pa_11_fp_reg_struct result;
|
||||||
|
|
||||||
pa_parse_number (&s, &result);
|
pa_parse_number (&s, &result);
|
||||||
CHECK_FIELD (result.number_part, 31, 0, 0);
|
CHECK_FIELD (result.number_part, 31, 0, 0);
|
||||||
@ -2394,7 +2402,7 @@ pa_ip (str)
|
|||||||
/* Handle a 5 bit register field at 20. */
|
/* Handle a 5 bit register field at 20. */
|
||||||
case '8':
|
case '8':
|
||||||
{
|
{
|
||||||
struct pa_89_fp_reg_struct result;
|
struct pa_11_fp_reg_struct result;
|
||||||
|
|
||||||
pa_parse_number (&s, &result);
|
pa_parse_number (&s, &result);
|
||||||
CHECK_FIELD (result.number_part, 31, 0, 0);
|
CHECK_FIELD (result.number_part, 31, 0, 0);
|
||||||
@ -2409,7 +2417,7 @@ pa_ip (str)
|
|||||||
/* Handle a 5 bit register field at 25. */
|
/* Handle a 5 bit register field at 25. */
|
||||||
case '9':
|
case '9':
|
||||||
{
|
{
|
||||||
struct pa_89_fp_reg_struct result;
|
struct pa_11_fp_reg_struct result;
|
||||||
|
|
||||||
pa_parse_number (&s, &result);
|
pa_parse_number (&s, &result);
|
||||||
CHECK_FIELD (result.number_part, 31, 0, 0);
|
CHECK_FIELD (result.number_part, 31, 0, 0);
|
||||||
@ -2873,20 +2881,21 @@ md_apply_fix (fixP, valp)
|
|||||||
new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
|
new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
|
||||||
|
|
||||||
/* Handle pc-relative exceptions from above. */
|
/* Handle pc-relative exceptions from above. */
|
||||||
#define stub_needed(CALLER, CALLEE) \
|
#define arg_reloc_stub_needed(CALLER, CALLEE) \
|
||||||
((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
|
((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
|
||||||
if ((fmt == 12 || fmt == 17)
|
if ((fmt == 12 || fmt == 17)
|
||||||
&& fixP->fx_addsy
|
&& fixP->fx_addsy
|
||||||
&& fixP->fx_pcrel
|
&& fixP->fx_pcrel
|
||||||
&& !stub_needed (((obj_symbol_type *)
|
&& !arg_reloc_stub_needed (((obj_symbol_type *)
|
||||||
fixP->fx_addsy->bsym)->tc_data.hppa_arg_reloc,
|
fixP->fx_addsy->bsym)->tc_data.hppa_arg_reloc,
|
||||||
hppa_fixP->fx_arg_reloc)
|
hppa_fixP->fx_arg_reloc)
|
||||||
|
&& (*valp > -262144 && *valp < 262143)
|
||||||
&& S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment
|
&& S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment
|
||||||
&& !(fixP->fx_subsy
|
&& !(fixP->fx_subsy
|
||||||
&& S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment))
|
&& S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment))
|
||||||
|
|
||||||
new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
|
new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
|
||||||
#undef stub_needed
|
#undef arg_reloc_stub_needed
|
||||||
|
|
||||||
switch (fmt)
|
switch (fmt)
|
||||||
{
|
{
|
||||||
@ -3009,7 +3018,7 @@ is_end_of_statement ()
|
|||||||
static int
|
static int
|
||||||
pa_parse_number (s, result)
|
pa_parse_number (s, result)
|
||||||
char **s;
|
char **s;
|
||||||
struct pa_89_fp_reg_struct *result;
|
struct pa_11_fp_reg_struct *result;
|
||||||
{
|
{
|
||||||
int num;
|
int num;
|
||||||
char *name;
|
char *name;
|
||||||
@ -3242,15 +3251,24 @@ reg_name_search (name)
|
|||||||
|
|
||||||
|
|
||||||
/* Return nonzero if the given INSN and L/R information will require
|
/* Return nonzero if the given INSN and L/R information will require
|
||||||
a new PA-89 opcode. */
|
a new PA-1.1 opcode. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
need_89_opcode (insn, result)
|
need_pa11_opcode (insn, result)
|
||||||
struct pa_it *insn;
|
struct pa_it *insn;
|
||||||
struct pa_89_fp_reg_struct *result;
|
struct pa_11_fp_reg_struct *result;
|
||||||
{
|
{
|
||||||
if (result->l_r_select == 1 && !(insn->fpof1 == DBL && insn->fpof2 == DBL))
|
if (result->l_r_select == 1 && !(insn->fpof1 == DBL && insn->fpof2 == DBL))
|
||||||
return TRUE;
|
{
|
||||||
|
/* If this instruction is specific to a particular architecture,
|
||||||
|
then set a new architecture. */
|
||||||
|
if (bfd_get_mach (stdoutput) < pa11)
|
||||||
|
{
|
||||||
|
if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, pa11))
|
||||||
|
as_warn ("could not update architecture and machine");
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -4248,7 +4266,17 @@ pa_code (unused)
|
|||||||
where <label> is optional and is a symbol whose address will be the start of
|
where <label> is optional and is a symbol whose address will be the start of
|
||||||
a block of memory <length> bytes long. <length> must be an absolute
|
a block of memory <length> bytes long. <length> must be an absolute
|
||||||
expression. <length> bytes will be allocated in the current space
|
expression. <length> bytes will be allocated in the current space
|
||||||
and subspace. */
|
and subspace.
|
||||||
|
|
||||||
|
Also note the label may not even be on the same line as the .comm.
|
||||||
|
|
||||||
|
This difference in syntax means the colon function will be called
|
||||||
|
on the symbol before we arrive in pa_comm. colon will set a number
|
||||||
|
of attributes of the symbol that need to be fixed here. In particular
|
||||||
|
the value, section pointer, fragment pointer, flags, etc. What
|
||||||
|
a pain.
|
||||||
|
|
||||||
|
This also makes error detection all but impossible. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pa_comm (unused)
|
pa_comm (unused)
|
||||||
@ -4268,30 +4296,14 @@ pa_comm (unused)
|
|||||||
|
|
||||||
if (symbol)
|
if (symbol)
|
||||||
{
|
{
|
||||||
/* It is incorrect to check S_IS_DEFINED at this point as
|
S_SET_VALUE (symbol, size);
|
||||||
the symbol will *always* be defined. FIXME. How to
|
S_SET_SEGMENT (symbol, bfd_und_section_ptr);
|
||||||
correctly determine when this label really as been
|
S_SET_EXTERNAL (symbol);
|
||||||
defined before. */
|
|
||||||
if (S_GET_VALUE (symbol))
|
|
||||||
{
|
|
||||||
if (S_GET_VALUE (symbol) != size)
|
|
||||||
{
|
|
||||||
as_warn ("Length of .comm \"%s\" is already %ld. Not changed.",
|
|
||||||
S_GET_NAME (symbol), S_GET_VALUE (symbol));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
S_SET_VALUE (symbol, size);
|
|
||||||
S_SET_SEGMENT (symbol, bfd_und_section_ptr);
|
|
||||||
S_SET_EXTERNAL (symbol);
|
|
||||||
|
|
||||||
/* colon() has already set the frag to the current location in the
|
/* colon() has already set the frag to the current location in the
|
||||||
$BSS$ subspace; we need to reset the fragment to the zero address
|
current subspace; we need to reset the fragment to the zero address
|
||||||
fragment. */
|
fragment. We also need to reset the segment pointer. */
|
||||||
symbol->sy_frag = &zero_address_frag;
|
symbol->sy_frag = &zero_address_frag;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
@ -6187,6 +6199,7 @@ hppa_force_relocation (fixp)
|
|||||||
fixS *fixp;
|
fixS *fixp;
|
||||||
{
|
{
|
||||||
struct hppa_fix_struct *hppa_fixp;
|
struct hppa_fix_struct *hppa_fixp;
|
||||||
|
unsigned int distance;
|
||||||
|
|
||||||
hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data;
|
hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data;
|
||||||
#ifdef OBJ_SOM
|
#ifdef OBJ_SOM
|
||||||
@ -6194,19 +6207,26 @@ hppa_force_relocation (fixp)
|
|||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define stub_needed(CALLER, CALLEE) \
|
#define arg_reloc_stub_needed(CALLER, CALLEE) \
|
||||||
((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
|
((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
|
||||||
|
|
||||||
/* It is necessary to force PC-relative calls/jumps to have a relocation
|
/* It is necessary to force PC-relative calls/jumps to have a relocation
|
||||||
entry if they're going to need either a argument relocation or long
|
entry if they're going to need either a argument relocation or long
|
||||||
call stub. FIXME. Can't we need the same for absolute calls? */
|
call stub. FIXME. Can't we need the same for absolute calls? */
|
||||||
if (fixp->fx_pcrel && fixp->fx_addsy
|
if (fixp->fx_pcrel && fixp->fx_addsy
|
||||||
&& (stub_needed (((obj_symbol_type *)
|
&& (arg_reloc_stub_needed (((obj_symbol_type *)
|
||||||
fixp->fx_addsy->bsym)->tc_data.hppa_arg_reloc,
|
fixp->fx_addsy->bsym)->tc_data.hppa_arg_reloc,
|
||||||
hppa_fixp->fx_arg_reloc)))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
#undef stub_needed
|
hppa_fixp->fx_arg_reloc)))
|
||||||
|
return 1;
|
||||||
|
distance = (fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy)
|
||||||
|
- md_pcrel_from (fixp));
|
||||||
|
/* Now check and see if we're going to need a long-branch stub. */
|
||||||
|
if (fixp->fx_r_type == R_HPPA_PCREL_CALL
|
||||||
|
&& (distance > 262143 || distance < -262144))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
#undef arg_reloc_stub_needed
|
||||||
|
|
||||||
/* No need (yet) to force another relocations to be emitted. */
|
/* No need (yet) to force another relocations to be emitted. */
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user