From aa8b30edeb0dd5ecea841dbd03bfbfa99ba85ae8 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Thu, 28 Oct 1993 20:41:49 +0000 Subject: [PATCH] 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. --- gas/config/tc-hppa.c | 308 +++++++++++++------------------------------ 1 file changed, 89 insertions(+), 219 deletions(-) diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index a175b13082a..aee2c83bdae 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -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 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; -- 2.30.2