Merge with current Utah code:
* config/tc-hppa.c (pa_space): Do not report an error for a .space directive which does not define a "well-known" space and does not include a space number as an argument. * config/tc-hppa.c (pa_def_subspaces): Correct initialization of the "defined", "loadable", "code_only" and "space_index" fields. (pa_def_spaces): Correct initialization of the "spnum", "defined", and "private" fields. * config/tc-hppa.c (hppa_fix_struct): Delete unnecessary fix_fixP and fx_next fields. (hppa_find_hppa_fix): Delete unnecessary function. Fix all callers to get HPPA fixup information from the tc_fix_data field in the GAS fixup. (hppa_fix_root): Delete unnecessary variable. (fix_new_hppa): Attach HPPA fixup data to the GAS fixup. * config/tc-hppa.c (pa_set_start_symbol); Delete unwanted function. Fix all callers. (subspace_dictionary_chain): Delete unused ssd_start_sym field. * config/tc-hppa.c (hppa_fix_adjustable): New function to determine if a particular fixup is adjustable. * config/tc-hppa.c (log2): Renamed from is_power_of_2. Fix all callers. Now returns log2 (N) for positive N which are an exact power of two or -1 for an error. * config/tc-hppa.c (pa_callinfo): Range check values provided for ENTRY_GR, ENTRY_FR and ENTRY_SR. Properly adjust vaues before inserting them into the unwind table. * config/tc-hppa.c (NEEDS_FIXUP): Delete definition and all references. (hppa_gen_reloc_type): New object format dependent macro. (pa_ip): Delete tons of code which was either OBJ_SOM or OBJ_ELF conditional. The code can (and will) be shared between SOM & ELF formats in the near future. (cons_fix_new_hppa, md_apply_fix_1): Likewise. (pa_build_unwind_subspace, process_exit, pa_exit): Likewise. (tc_gen_reloc): Use hppa_gen_reloc rather than an object format specific call. * config/tc-hppa.c (pa_comm): Set the segment for a common symbol to bfd_und_section. * config/tc-hppa.c (pa_big_cons): Delete function and its declaration. All callers changed to use pa_cons. From Pete Hoogenboom: * config/tc-hppa.c (md_atof): Return a NULL on success rather than an empty string.
This commit is contained in:
parent
14aa9a78c3
commit
aa8b30edeb
1 changed files with 89 additions and 219 deletions
|
@ -43,14 +43,15 @@
|
|||
#define UNWIND_SECTION_NAME ".hppa_unwind"
|
||||
/* Nonzero if CODE is a fixup code needing further processing. */
|
||||
|
||||
#define NEEDS_FIXUP(CODE) ((CODE) != R_HPPA_NONE)
|
||||
|
||||
/* Object file formats specify relocation types. */
|
||||
typedef elf32_hppa_reloc_type reloc_type;
|
||||
|
||||
/* Object file formats specify BFD symbol types. */
|
||||
typedef elf_symbol_type obj_symbol_type;
|
||||
|
||||
/* How to generate a relocation. */
|
||||
#define hppa_gen_reloc_type hppa_elf_gen_reloc_type
|
||||
|
||||
/* Who knows. */
|
||||
#define obj_version obj_elf_version
|
||||
|
||||
|
@ -72,8 +73,8 @@ typedef int reloc_type;
|
|||
/* Who knows. */
|
||||
#define obj_version obj_som_version
|
||||
|
||||
/* Nonzero if CODE is a fixup code needing further processing. */
|
||||
#define NEEDS_FIXUP(CODE) ((CODE) != R_NO_RELOCATION)
|
||||
/* How to generate a relocation. */
|
||||
#define hppa_gen_reloc_type hppa_som_gen_reloc_type
|
||||
|
||||
/* Object file formats specify BFD symbol types. */
|
||||
typedef som_symbol_type obj_symbol_type;
|
||||
|
@ -315,9 +316,6 @@ struct subspace_dictionary_chain
|
|||
/* The size of the last alignment request for this subspace. */
|
||||
int ssd_last_align;
|
||||
|
||||
/* The symbol associated with the start of this subspace. */
|
||||
struct symbol *ssd_start_sym;
|
||||
|
||||
/* Next space in the subspace dictionary chain. */
|
||||
struct subspace_dictionary_chain *ssd_next;
|
||||
};
|
||||
|
@ -470,9 +468,6 @@ struct default_space_dict
|
|||
/* Extra information needed to perform fixups (relocations) on the PA. */
|
||||
struct hppa_fix_struct
|
||||
{
|
||||
/* A pointer to the GAS fixup. */
|
||||
fixS *fx_fixP;
|
||||
|
||||
/* The field selector. */
|
||||
int fx_r_field;
|
||||
|
||||
|
@ -487,9 +482,6 @@ struct hppa_fix_struct
|
|||
|
||||
/* The unwind descriptor associated with this fixup. */
|
||||
char fx_unwind[8];
|
||||
|
||||
/* Next entry in the chain. */
|
||||
struct hppa_fix_struct *fx_next;
|
||||
};
|
||||
|
||||
/* Structure to hold information about predefined registers. */
|
||||
|
@ -519,7 +511,6 @@ struct selector_entry
|
|||
/* Prototypes for functions local to tc-hppa.c. */
|
||||
|
||||
static fp_operand_format pa_parse_fp_format PARAMS ((char **s));
|
||||
static void pa_big_cons PARAMS ((int));
|
||||
static void pa_cons PARAMS ((int));
|
||||
static void pa_data PARAMS ((int));
|
||||
static void pa_desc PARAMS ((int));
|
||||
|
@ -588,13 +579,11 @@ static ssd_chain_struct * pa_subsegment_to_subspace PARAMS ((asection *,
|
|||
subsegT));
|
||||
static sd_chain_struct *pa_find_space_by_number PARAMS ((int));
|
||||
static unsigned int pa_subspace_start PARAMS ((sd_chain_struct *, int));
|
||||
static symbolS *pa_set_start_symbol PARAMS ((asection *, subsegT));
|
||||
static void pa_ip PARAMS ((char *));
|
||||
static void fix_new_hppa PARAMS ((fragS *, int, short int, symbolS *,
|
||||
long, expressionS *, int,
|
||||
bfd_reloc_code_real_type, long,
|
||||
int, long, char *));
|
||||
static struct hppa_fix_struct *hppa_find_hppa_fix PARAMS ((fixS *));
|
||||
static void md_apply_fix_1 PARAMS ((fixS *, long));
|
||||
static int is_end_of_statement PARAMS ((void));
|
||||
static int reg_name_search PARAMS ((char *));
|
||||
|
@ -604,7 +593,7 @@ static void pa_build_unwind_subspace PARAMS ((struct call_info *));
|
|||
static void process_exit PARAMS ((void));
|
||||
static sd_chain_struct *pa_parse_space_stmt PARAMS ((char *, int));
|
||||
static void pa_align_subseg PARAMS ((asection *, subsegT));
|
||||
static int is_power_of_2 PARAMS ((int));
|
||||
static int log2 PARAMS ((int));
|
||||
static int pa_next_subseg PARAMS ((sd_chain_struct *));
|
||||
static unsigned int pa_stringer_aux PARAMS ((char *));
|
||||
static void pa_spaces_begin PARAMS ((void));
|
||||
|
@ -708,8 +697,8 @@ const pseudo_typeS md_pseudo_table[] =
|
|||
{"LONG", pa_cons, 4},
|
||||
{"lsym", pa_lsym, 0},
|
||||
{"LSYM", pa_lsym, 0},
|
||||
{"octa", pa_big_cons, 16},
|
||||
{"OCTA", pa_big_cons, 16},
|
||||
{"octa", pa_cons, 16},
|
||||
{"OCTA", pa_cons, 16},
|
||||
{"org", pa_origin, 0},
|
||||
{"ORG", pa_origin, 0},
|
||||
{"origin", pa_origin, 0},
|
||||
|
@ -720,8 +709,8 @@ const pseudo_typeS md_pseudo_table[] =
|
|||
{"PROC", pa_proc, 0},
|
||||
{"procend", pa_procend, 0},
|
||||
{"PROCEND", pa_procend, 0},
|
||||
{"quad", pa_big_cons, 8},
|
||||
{"QUAD", pa_big_cons, 8},
|
||||
{"quad", pa_cons, 8},
|
||||
{"QUAD", pa_cons, 8},
|
||||
{"reg", pa_equ, 1},
|
||||
{"REG", pa_equ, 1},
|
||||
{"short", pa_cons, 2},
|
||||
|
@ -796,9 +785,6 @@ static int within_procedure;
|
|||
seen in each subspace. */
|
||||
static label_symbol_struct *label_symbols_rootp = NULL;
|
||||
|
||||
/* Root of the hppa fixup information. */
|
||||
static struct hppa_fix_struct *hppa_fix_root;
|
||||
|
||||
/* Holds the last field selector. */
|
||||
static int hppa_field_selector;
|
||||
|
||||
|
@ -1129,18 +1115,18 @@ static const struct selector_entry selector_table[] =
|
|||
|
||||
static struct default_subspace_dict pa_def_subspaces[] =
|
||||
{
|
||||
{"$CODE$", 0, 1, 0, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_CODE},
|
||||
{"$DATA$", 0, 1, 0, 0, 0, 0, 24, 0x1f, 0, 8, 1, 1, ".data", SUBSEG_DATA},
|
||||
{"$LIT$", 0, 1, 0, 0, 0, 0, 16, 0x0c, 0, 8, 0, 0, ".text", SUBSEG_LIT},
|
||||
{"$BSS$", 0, 1, 0, 0, 0, 1, 80, 0x1f, 0, 8, 1, 1, ".bss", SUBSEG_BSS},
|
||||
{"$UNWIND$", 0, 1, 0, 0, 0, 0, 64, 0x0c, 0, 4, 0, 0, ".hppa_unwind", SUBSEG_UNWIND},
|
||||
{"$CODE$", 1, 1, 1, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_CODE},
|
||||
{"$DATA$", 1, 1, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, ".data", SUBSEG_DATA},
|
||||
{"$LIT$", 1, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_LIT},
|
||||
{"$BSS$", 1, 1, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, ".bss", SUBSEG_BSS},
|
||||
{"$UNWIND$", 1, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, 0, ".hppa_unwind", SUBSEG_UNWIND},
|
||||
{NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0}
|
||||
};
|
||||
|
||||
static struct default_space_dict pa_def_spaces[] =
|
||||
{
|
||||
{"$TEXT$", 0, 1, 0, 0, 8, ASEC_NULL, ".text"},
|
||||
{"$PRIVATE$", 0, 1, 0, 0, 16, ASEC_NULL, ".data"},
|
||||
{"$TEXT$", 0, 1, 1, 0, 8, ASEC_NULL, ".text"},
|
||||
{"$PRIVATE$", 1, 1, 1, 1, 16, ASEC_NULL, ".data"},
|
||||
{NULL, 0, 0, 0, 0, 0, ASEC_NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -1268,7 +1254,8 @@ pa_undefine_label ()
|
|||
code needs to keep track of some extra stuff. Each call to fix_new_hppa
|
||||
results in the creation of an instance of an hppa_fix_struct. An
|
||||
hppa_fix_struct stores the extra information along with a pointer to the
|
||||
original fixS. */
|
||||
original fixS. This is attached to the original fixup via the
|
||||
tc_fix_data field. */
|
||||
|
||||
static void
|
||||
fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel,
|
||||
|
@ -1295,19 +1282,14 @@ fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel,
|
|||
new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
|
||||
else
|
||||
new_fix = fix_new (frag, where, size, add_symbol, offset, pcrel, r_type);
|
||||
hppa_fix->fx_fixP = new_fix;
|
||||
new_fix->tc_fix_data = hppa_fix;
|
||||
hppa_fix->fx_r_type = r_type;
|
||||
hppa_fix->fx_r_field = r_field;
|
||||
hppa_fix->fx_r_format = r_format;
|
||||
hppa_fix->fx_arg_reloc = arg_reloc;
|
||||
hppa_fix->fx_next = NULL;
|
||||
if (unwind_desc)
|
||||
bcopy (unwind_desc, hppa_fix->fx_unwind, 8);
|
||||
|
||||
if (hppa_fix_root)
|
||||
hppa_fix->fx_next = hppa_fix_root;
|
||||
|
||||
hppa_fix_root = hppa_fix;
|
||||
}
|
||||
|
||||
/* Parse a .byte, .word, .long expression for the HPPA. Called by
|
||||
|
@ -1333,10 +1315,6 @@ cons_fix_new_hppa (frag, where, size, exp)
|
|||
{
|
||||
unsigned int reloc_type;
|
||||
|
||||
#ifdef OBJ_SOM
|
||||
abort ();
|
||||
#else
|
||||
|
||||
if (is_DP_relative (*exp))
|
||||
reloc_type = R_HPPA_GOTOFF;
|
||||
else if (is_complex (*exp))
|
||||
|
@ -1350,24 +1328,6 @@ cons_fix_new_hppa (frag, where, size, exp)
|
|||
fix_new_hppa (frag, where, size,
|
||||
(symbolS *) NULL, (offsetT) 0, exp, 0, reloc_type,
|
||||
hppa_field_selector, 32, 0, (char *) 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Given a FixS, find the hppa_fix_struct associated with it. */
|
||||
|
||||
static struct hppa_fix_struct *
|
||||
hppa_find_hppa_fix (fix)
|
||||
fixS *fix;
|
||||
{
|
||||
struct hppa_fix_struct *hppa_fix;
|
||||
|
||||
for (hppa_fix = hppa_fix_root; hppa_fix; hppa_fix = hppa_fix->fx_next)
|
||||
{
|
||||
if (hppa_fix->fx_fixP == fix)
|
||||
return hppa_fix;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This function is called once, at assembler startup time. It should
|
||||
|
@ -1445,7 +1405,7 @@ md_assemble (str)
|
|||
md_number_to_chars (to, the_insn.opcode, 4);
|
||||
|
||||
/* If necessary output more stuff. */
|
||||
if (NEEDS_FIXUP (the_insn.reloc))
|
||||
if (the_insn.reloc != R_HPPA_NONE)
|
||||
fix_new_hppa (frag_now, (to - frag_now->fr_literal), 4, NULL,
|
||||
(offsetT) 0, &the_insn.exp, the_insn.pcrel,
|
||||
the_insn.reloc, the_insn.field_selector,
|
||||
|
@ -1528,12 +1488,7 @@ pa_ip (str)
|
|||
opcode = insn->match;
|
||||
bzero (&the_insn, sizeof (the_insn));
|
||||
|
||||
/* FIXME. */
|
||||
#ifdef OBJ_SOM
|
||||
the_insn.reloc = R_NO_RELOCATION;
|
||||
#else
|
||||
the_insn.reloc = R_HPPA_NONE;
|
||||
#endif
|
||||
|
||||
/* Build the opcode, checking as we go to make
|
||||
sure that the operands match. */
|
||||
|
@ -2142,10 +2097,6 @@ pa_ip (str)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef OBJ_SOM
|
||||
the_insn.reloc = R_CODE_ONE_SYMBOL;
|
||||
the_insn.format = 'i';
|
||||
#else
|
||||
if (is_DP_relative (the_insn.exp))
|
||||
the_insn.reloc = R_HPPA_GOTOFF;
|
||||
else if (is_PC_relative (the_insn.exp))
|
||||
|
@ -2155,7 +2106,6 @@ pa_ip (str)
|
|||
else
|
||||
the_insn.reloc = R_HPPA;
|
||||
the_insn.format = 11;
|
||||
#endif
|
||||
}
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
@ -2176,10 +2126,6 @@ pa_ip (str)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef OBJ_SOM
|
||||
the_insn.reloc = R_CODE_ONE_SYMBOL;
|
||||
the_insn.format = 'j';
|
||||
#else
|
||||
if (is_DP_relative (the_insn.exp))
|
||||
the_insn.reloc = R_HPPA_GOTOFF;
|
||||
else if (is_PC_relative (the_insn.exp))
|
||||
|
@ -2189,7 +2135,6 @@ pa_ip (str)
|
|||
else
|
||||
the_insn.reloc = R_HPPA;
|
||||
the_insn.format = 14;
|
||||
#endif
|
||||
}
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
@ -2207,10 +2152,6 @@ pa_ip (str)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef OBJ_SOM
|
||||
the_insn.reloc = R_CODE_ONE_SYMBOL;
|
||||
the_insn.format = 'k';
|
||||
#else
|
||||
if (is_DP_relative (the_insn.exp))
|
||||
the_insn.reloc = R_HPPA_GOTOFF;
|
||||
else if (is_PC_relative (the_insn.exp))
|
||||
|
@ -2220,7 +2161,6 @@ pa_ip (str)
|
|||
else
|
||||
the_insn.reloc = R_HPPA;
|
||||
the_insn.format = 21;
|
||||
#endif
|
||||
}
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
@ -2247,16 +2187,11 @@ pa_ip (str)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef OBJ_SOM
|
||||
the_insn.reloc = R_PCREL_CALL;
|
||||
the_insn.format = 'w';
|
||||
#else
|
||||
if (is_complex (the_insn.exp))
|
||||
the_insn.reloc = R_HPPA_COMPLEX_PCREL_CALL;
|
||||
else
|
||||
the_insn.reloc = R_HPPA_PCREL_CALL;
|
||||
the_insn.format = 12;
|
||||
#endif
|
||||
the_insn.arg_reloc = last_call_desc.arg_reloc;
|
||||
bzero (&last_call_desc, sizeof (struct call_desc));
|
||||
}
|
||||
|
@ -2282,16 +2217,11 @@ pa_ip (str)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef OBJ_SOM
|
||||
the_insn.reloc = R_PCREL_CALL;
|
||||
the_insn.format = 'W';
|
||||
#else
|
||||
if (is_complex (the_insn.exp))
|
||||
the_insn.reloc = R_HPPA_COMPLEX_PCREL_CALL;
|
||||
else
|
||||
the_insn.reloc = R_HPPA_PCREL_CALL;
|
||||
the_insn.format = 17;
|
||||
#endif
|
||||
the_insn.arg_reloc = last_call_desc.arg_reloc;
|
||||
bzero (&last_call_desc, sizeof (struct call_desc));
|
||||
}
|
||||
|
@ -2326,16 +2256,11 @@ pa_ip (str)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef OBJ_SOM
|
||||
the_insn.reloc = R_PCREL_CALL;
|
||||
the_insn.format = 'W';
|
||||
#else
|
||||
if (is_complex (the_insn.exp))
|
||||
the_insn.reloc = R_HPPA_COMPLEX_ABS_CALL;
|
||||
else
|
||||
the_insn.reloc = R_HPPA_ABS_CALL;
|
||||
the_insn.format = 17;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2728,7 +2653,7 @@ md_atof (type, litP, sizeP)
|
|||
md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
|
||||
litP += sizeof (LITTLENUM_TYPE);
|
||||
}
|
||||
return "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Write out big-endian. */
|
||||
|
@ -2766,7 +2691,7 @@ tc_gen_reloc (section, fixp)
|
|||
fixS *fixp;
|
||||
{
|
||||
arelent *reloc;
|
||||
struct hppa_fix_struct *hppa_fixp = hppa_find_hppa_fix (fixp);
|
||||
struct hppa_fix_struct *hppa_fixp = fixp->tc_fix_data;
|
||||
bfd_reloc_code_real_type code;
|
||||
static int unwind_reloc_fixp_cnt = 0;
|
||||
static arelent *unwind_reloc_entryP = NULL;
|
||||
|
@ -2830,10 +2755,10 @@ tc_gen_reloc (section, fixp)
|
|||
assert (reloc != 0);
|
||||
|
||||
reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
|
||||
codes = hppa_elf_gen_reloc_type (stdoutput,
|
||||
fixp->fx_r_type,
|
||||
hppa_fixp->fx_r_format,
|
||||
hppa_fixp->fx_r_field);
|
||||
codes = hppa_gen_reloc_type (stdoutput,
|
||||
fixp->fx_r_type,
|
||||
hppa_fixp->fx_r_format,
|
||||
hppa_fixp->fx_r_field);
|
||||
|
||||
for (n_relocs = 0; codes[n_relocs]; n_relocs++)
|
||||
;
|
||||
|
@ -3090,17 +3015,6 @@ md_operand (expressionP)
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef OBJ_SOM
|
||||
/* FIXME. Documentation missing. Needs to be implemented. */
|
||||
static void
|
||||
md_apply_fix_1 (fixP, val)
|
||||
fixS *fixP;
|
||||
long val;
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
#else
|
||||
|
||||
/* Helper function for md_apply_fix. Actually determine if the fix
|
||||
can be applied, and if so, apply it.
|
||||
|
||||
|
@ -3113,7 +3027,7 @@ md_apply_fix_1 (fixP, val)
|
|||
long val;
|
||||
{
|
||||
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
|
||||
struct hppa_fix_struct *hppa_fixP = hppa_find_hppa_fix (fixP);
|
||||
struct hppa_fix_struct *hppa_fixP = fixP->tc_fix_data;
|
||||
long new_val, result;
|
||||
unsigned int w1, w2, w;
|
||||
|
||||
|
@ -3122,11 +3036,12 @@ md_apply_fix_1 (fixP, val)
|
|||
if (hppa_fixP)
|
||||
{
|
||||
unsigned long buf_wd = bfd_get_32 (stdoutput, buf);
|
||||
unsigned char fmt = hppa_elf_insn2fmt (fixP->fx_r_type, buf_wd);
|
||||
unsigned char fmt = bfd_hppa_insn2fmt (buf_wd);
|
||||
|
||||
/* Sanity check the fixup type. */
|
||||
assert (fixP->fx_r_type < R_HPPA_UNIMPLEMENTED);
|
||||
assert (fixP->fx_r_type >= R_HPPA_NONE);
|
||||
/* Is this really necessary? */
|
||||
if (fixP->fx_r_type == R_HPPA_NONE)
|
||||
fmt = 0;
|
||||
|
||||
/* Remember this value for emit_reloc. FIXME, is this braindamage
|
||||
documented anywhere!?! */
|
||||
|
@ -3201,7 +3116,7 @@ md_apply_fix_1 (fixP, val)
|
|||
needed, then we can not apply this relocation, instead
|
||||
the linker must handle it. */
|
||||
if (too_far (val, 18)
|
||||
|| stub_needed (((elf_symbol_type *)
|
||||
|| stub_needed (((obj_symbol_type *)
|
||||
fixP->fx_addsy->bsym)->tc_data.hppa_arg_reloc,
|
||||
hppa_fixP->fx_arg_reloc))
|
||||
return;
|
||||
|
@ -3223,10 +3138,12 @@ md_apply_fix_1 (fixP, val)
|
|||
#undef stub_needed
|
||||
|
||||
case 32:
|
||||
#ifdef OBJ_ELF
|
||||
if (hppa_fixP->fx_r_type == R_HPPA_UNWIND_ENTRY
|
||||
|| hppa_fixP->fx_r_type == R_HPPA_UNWIND_ENTRIES)
|
||||
result = fixP->fx_addnumber;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
result = 0;
|
||||
fixP->fx_addnumber = fixP->fx_offset;
|
||||
|
@ -3254,7 +3171,6 @@ md_apply_fix_1 (fixP, val)
|
|||
printf ("no hppa_fixup entry for this fixup (fixP = 0x%x, type = 0x%x)\n",
|
||||
(unsigned int) fixP, fixP->fx_r_type);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Apply a fix into a frag's data (if possible). */
|
||||
|
||||
|
@ -4304,17 +4220,10 @@ pa_build_unwind_subspace (call_info)
|
|||
call_info->start_frag_where = p - frag_now->fr_literal;
|
||||
|
||||
/* Relocation info. for start offset of the function. */
|
||||
#ifdef OBJ_SOM
|
||||
fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
|
||||
call_info->start_symbol, (offsetT) 0,
|
||||
(expressionS *) NULL, 0, R_DATA_ONE_SYMBOL, e_fsel, 0, 0,
|
||||
(char *) 0);
|
||||
#else
|
||||
fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
|
||||
call_info->start_symbol, (offsetT) 0,
|
||||
(expressionS *) NULL, 0, R_HPPA_UNWIND, e_fsel, 32, 0,
|
||||
(char *) 0);
|
||||
#endif
|
||||
|
||||
/* We need to search for the first relocation involving the start_symbol of
|
||||
this call_info descriptor. */
|
||||
|
@ -4338,18 +4247,10 @@ pa_build_unwind_subspace (call_info)
|
|||
call_info->end_frag_where = p - frag_now->fr_literal;
|
||||
|
||||
/* Relocation info. for end offset of the function. */
|
||||
#ifdef OBJ_SOM
|
||||
fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
|
||||
call_info->start_symbol, (offsetT) 0,
|
||||
(expressionS *) NULL, 0, R_DATA_ONE_SYMBOL, e_fsel, 0, 0,
|
||||
(char *) 0);
|
||||
|
||||
#else
|
||||
fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
|
||||
call_info->end_symbol, (offsetT) 0,
|
||||
(expressionS *) NULL, 0, R_HPPA_UNWIND, e_fsel, 32, 0,
|
||||
(char *) 0);
|
||||
#endif
|
||||
|
||||
/* We need to search for the first relocation involving the end_symbol of
|
||||
this call_info descriptor. */
|
||||
|
@ -4430,7 +4331,12 @@ pa_callinfo (unused)
|
|||
*p = c;
|
||||
input_line_pointer++;
|
||||
temp = get_absolute_expression ();
|
||||
last_call_info->ci_unwind.descriptor.entry_gr = temp;
|
||||
/* The HP assembler accepts 19 as the high bound for ENTRY_GR
|
||||
even though %r19 is caller saved. I think this is a bug in
|
||||
the HP assembler, and we are not going to emulate it. */
|
||||
if (temp < 3 || temp > 18)
|
||||
as_bad ("Value for ENTRY_GR must be in the range 3..18\n");
|
||||
last_call_info->ci_unwind.descriptor.entry_gr = temp - 2;
|
||||
}
|
||||
else if ((strncasecmp (name, "entry_fr", 8) == 0))
|
||||
{
|
||||
|
@ -4438,7 +4344,11 @@ pa_callinfo (unused)
|
|||
*p = c;
|
||||
input_line_pointer++;
|
||||
temp = get_absolute_expression ();
|
||||
last_call_info->ci_unwind.descriptor.entry_fr = temp;
|
||||
/* Similarly the HP assembler takes 31 as the high bound even
|
||||
though %fr21 is the last callee saved floating point register. */
|
||||
if (temp < 12 || temp > 21)
|
||||
as_bad ("Value for ENTRY_FR must be in the range 12..21\n");
|
||||
last_call_info->ci_unwind.descriptor.entry_fr = temp - 11;
|
||||
}
|
||||
else if ((strncasecmp (name, "entry_sr", 8) == 0))
|
||||
{
|
||||
|
@ -4446,7 +4356,9 @@ pa_callinfo (unused)
|
|||
*p = c;
|
||||
input_line_pointer++;
|
||||
temp = get_absolute_expression ();
|
||||
last_call_info->entry_sr = temp;
|
||||
if (temp != 3)
|
||||
as_bad ("Value for ENTRY_SR must be 3\n");
|
||||
last_call_info->entry_sr = temp - 2;
|
||||
}
|
||||
/* Note whether or not this function performs any calls. */
|
||||
else if ((strncasecmp (name, "calls", 5) == 0) ||
|
||||
|
@ -4577,7 +4489,7 @@ pa_comm (unused)
|
|||
else
|
||||
{
|
||||
S_SET_VALUE (symbol, size);
|
||||
S_SET_SEGMENT (symbol, bss_section);
|
||||
S_SET_SEGMENT (symbol, &bfd_und_section);
|
||||
S_SET_EXTERNAL (symbol);
|
||||
}
|
||||
}
|
||||
|
@ -4661,12 +4573,6 @@ pa_entry (unused)
|
|||
It will not be on if no .EXPORT pseudo-op exists (static function). */
|
||||
last_call_info->start_symbol->bsym->flags |= BSF_FUNCTION;
|
||||
|
||||
#ifdef OBJ_SOM
|
||||
fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
|
||||
last_call_info->start_symbol, (offsetT) 0,
|
||||
(expressionS *) NULL, 0, R_ENTRY, e_fsel, 0, 0,
|
||||
(char *) &last_call_info->ci_unwind.descriptor);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4708,13 +4614,7 @@ process_exit ()
|
|||
char *where;
|
||||
|
||||
where = frag_more (0);
|
||||
#ifdef OBJ_SOM
|
||||
fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
|
||||
last_call_info->start_symbol, (offsetT) 0,
|
||||
(expressionS *) NULL, 0, R_EXIT, e_fsel, 0, 0,
|
||||
(char *) NULL);
|
||||
#endif
|
||||
#ifdef OBJ_ELF
|
||||
|
||||
/* ELF does not have EXIT relocations. All we do is create a
|
||||
temporary symbol marking the end of the function. */
|
||||
{
|
||||
|
@ -4753,7 +4653,6 @@ process_exit ()
|
|||
else
|
||||
as_bad ("No memory for symbol name.");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Stuff away the location of the frag for the end of the function,
|
||||
and call pa_build_unwind_subspace to add an entry in the unwind
|
||||
|
@ -5282,7 +5181,7 @@ static void
|
|||
pa_space (unused)
|
||||
int unused;
|
||||
{
|
||||
char *name, c, *space_name;
|
||||
char *name, c, *space_name, *save_s;
|
||||
int temp;
|
||||
sd_chain_struct *sd_chain;
|
||||
|
||||
|
@ -5372,7 +5271,8 @@ pa_space (unused)
|
|||
}
|
||||
|
||||
/* It could be a space specified by number. */
|
||||
|
||||
print_errors = 0;
|
||||
save_s = input_line_pointer;
|
||||
if ((temp = pa_parse_number (&input_line_pointer, 0)) >= 0)
|
||||
{
|
||||
if (sd_chain = pa_find_space_by_number (temp))
|
||||
|
@ -5391,7 +5291,8 @@ pa_space (unused)
|
|||
}
|
||||
|
||||
/* Not a number, attempt to create a new space. */
|
||||
|
||||
print_errors = 1;
|
||||
input_line_pointer = save_s;
|
||||
name = input_line_pointer;
|
||||
c = get_symbol_end ();
|
||||
space_name = xmalloc (strlen (name) + 1);
|
||||
|
@ -5439,10 +5340,10 @@ pa_spnum (unused)
|
|||
}
|
||||
|
||||
/* If VALUE is an exact power of two between zero and 2^31, then
|
||||
return nonzero. Else return 0. */
|
||||
return log2 (VALUE). Else return -1. */
|
||||
|
||||
static int
|
||||
is_power_of_2 (value)
|
||||
log2 (value)
|
||||
int value;
|
||||
{
|
||||
int shift = 0;
|
||||
|
@ -5451,9 +5352,9 @@ is_power_of_2 (value)
|
|||
shift++;
|
||||
|
||||
if (shift >= 32)
|
||||
return 0;
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
return shift;
|
||||
}
|
||||
|
||||
/* Handle a .SPACE pseudo-op; this switches the current subspace to the
|
||||
|
@ -5551,7 +5452,7 @@ pa_subspace (unused)
|
|||
*input_line_pointer = c;
|
||||
input_line_pointer++;
|
||||
alignment = get_absolute_expression ();
|
||||
if (!is_power_of_2 (alignment))
|
||||
if (log2 (alignment) == -1)
|
||||
{
|
||||
as_bad ("Alignment must be a power of 2");
|
||||
alignment = 1;
|
||||
|
@ -5855,9 +5756,6 @@ create_new_subspace (space, name, loadable, code_only, common,
|
|||
}
|
||||
}
|
||||
|
||||
start_symbol = pa_set_start_symbol (seg, space->sd_last_subseg);
|
||||
chain_entry->ssd_start_sym = start_symbol;
|
||||
|
||||
return chain_entry;
|
||||
|
||||
}
|
||||
|
@ -6068,52 +5966,6 @@ pa_next_subseg (space)
|
|||
return space->sd_last_subseg;
|
||||
}
|
||||
|
||||
/* Function to define a symbol whose address is the beginning of a subspace.
|
||||
This function assumes the symbol is to be defined for the current
|
||||
subspace. */
|
||||
|
||||
static symbolS *
|
||||
pa_set_start_symbol (seg, subseg)
|
||||
asection *seg;
|
||||
subsegT subseg;
|
||||
{
|
||||
symbolS *start_symbol;
|
||||
ssd_chain_struct *ssd;
|
||||
char *symbol_name;
|
||||
|
||||
symbol_name = (char *)
|
||||
xmalloc (strlen ("LS$START__000000$") + strlen (seg->name) + 1);
|
||||
|
||||
sprintf (symbol_name, "LS$START_%s_%03d$", seg->name, subseg);
|
||||
|
||||
start_symbol
|
||||
= symbol_new (symbol_name, seg, 0, frag_now);
|
||||
|
||||
start_symbol->bsym->flags = BSF_LOCAL;
|
||||
|
||||
/* each time a new space is created, build a symbol called
|
||||
LS$START_seg_subseg$ where <space-name> is the name of the space
|
||||
the start symbol will be SS_LOCAL and ST_CODE
|
||||
This function assumes that (seg,subseg) is a new subsegment(subspace) */
|
||||
if (seg == bfd_make_section_old_way (stdoutput, ".text") ||
|
||||
seg == bfd_make_section_old_way (stdoutput, ".data") ||
|
||||
seg == bfd_make_section_old_way (stdoutput, GDB_DEBUG_SPACE_NAME))
|
||||
{
|
||||
ssd = pa_subsegment_to_subspace (seg, subseg);
|
||||
if (ssd)
|
||||
{
|
||||
ssd->ssd_start_sym = start_symbol;
|
||||
}
|
||||
else
|
||||
as_fatal ("Internal error: missing subspace for %s", seg->name);
|
||||
}
|
||||
else
|
||||
as_fatal ("Internal error: attempt to define start symbol for unloadable segment: '%s'",
|
||||
seg->name);
|
||||
|
||||
return start_symbol;
|
||||
}
|
||||
|
||||
/* Helper function for pa_stringer. Used to find the end of
|
||||
a string. */
|
||||
|
||||
|
@ -6290,16 +6142,6 @@ pa_lsym (unused)
|
|||
pa_undefine_label ();
|
||||
}
|
||||
|
||||
/* Like big_cons, but delete our label when finished. */
|
||||
|
||||
static void
|
||||
pa_big_cons (nbytes)
|
||||
int nbytes;
|
||||
{
|
||||
big_cons (nbytes);
|
||||
pa_undefine_label ();
|
||||
}
|
||||
|
||||
/* Switch to the text space. Like s_text, but delete our
|
||||
label when finished. */
|
||||
static void
|
||||
|
@ -6310,6 +6152,34 @@ pa_text (unused)
|
|||
pa_undefine_label ();
|
||||
}
|
||||
|
||||
/* On the PA relocations which involve function symbols must not be
|
||||
adjusted. This so that the linker can know when/how to create argument
|
||||
relocation stubs for indirect calls and calls to static functions.
|
||||
|
||||
FIXME. Also reject R_HPPA relocations which are 32 bits
|
||||
wide. Helps with code lables in arrays for SOM. (SOM BFD code
|
||||
needs to generate relocations to push the addend and symbol value
|
||||
onto the stack, add them, then pop the value off the stack and
|
||||
use it in a relocation -- yuk. */
|
||||
|
||||
int
|
||||
hppa_fix_adjustable (fixp)
|
||||
fixS *fixp;
|
||||
{
|
||||
struct hppa_fix_struct *hppa_fix;
|
||||
|
||||
hppa_fix = fixp->tc_fix_data;
|
||||
|
||||
if (fixp->fx_r_type == R_HPPA && hppa_fix->fx_r_format == 32)
|
||||
return 0;
|
||||
|
||||
if (fixp->fx_addsy == 0
|
||||
|| (fixp->fx_addsy->bsym->flags & BSF_FUNCTION) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now for some ELF specific code. FIXME. */
|
||||
#ifdef OBJ_ELF
|
||||
static symext_chainS *symext_rootP;
|
||||
|
|
Loading…
Reference in a new issue