X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-hppa.c;h=39da02ed17ee96cf96abd1f52debe100d214196a;hb=8ad30312fff34325113307cb27bcae49d220df15;hp=946831aa0285c6e4bc7bf869f23ccb3f60bcac6b;hpb=40d74fb122d7610447c2f34978ed35d749a4f118;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index 946831aa02..39da02ed17 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -1,6 +1,6 @@ /* tc-hppa.c -- Assemble for the PA Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002 Free Software Foundation, Inc. + 2002, 2003 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -622,6 +622,11 @@ static struct call_desc last_call_desc; /* handle of the OPCODE hash table */ static struct hash_control *op_hash = NULL; +/* These characters can be suffixes of opcode names and they may be + followed by meaningful whitespace. We don't include `,' and `!' + as they never appear followed by meaningful whitespace. */ +const char hppa_symbol_chars[] = "*?=<>"; + /* Table of pseudo ops for the PA. FIXME -- how many of these are now redundant with the overall GAS and the object file dependent tables? */ @@ -667,9 +672,6 @@ const pseudo_typeS md_pseudo_table[] = {"equ", pa_equ, 0}, {"exit", pa_exit, 0}, {"export", pa_export, 0}, -#ifdef OBJ_ELF - {"file", dwarf2_directive_file, 0 }, -#endif {"fill", pa_fill, 0}, {"float", pa_float_cons, 'f'}, {"half", pa_cons, 2}, @@ -679,9 +681,6 @@ const pseudo_typeS md_pseudo_table[] = {"lcomm", pa_lcomm, 0}, {"leave", pa_leave, 0}, {"level", pa_level, 0}, -#ifdef OBJ_ELF - {"loc", dwarf2_directive_loc, 0 }, -#endif {"long", pa_cons, 4}, {"lsym", pa_lsym, 0}, #ifdef OBJ_SOM @@ -1289,10 +1288,10 @@ pa_undefine_label () { if (1 #ifdef OBJ_SOM - && current_space == label_chain->lss_space && label_chain->lss_label + && current_space == label_chain->lss_space && label_chain->lss_label #endif #ifdef OBJ_ELF - && now_seg == label_chain->lss_segment && label_chain->lss_label + && now_seg == label_chain->lss_segment && label_chain->lss_label #endif ) { @@ -2334,16 +2333,16 @@ pa_ip (str) args++; switch (*args) { - /* Handle FP compare conditions. */ - case 'f': - cond = pa_parse_fp_cmp_cond (&s); - INSERT_FIELD_AND_CONTINUE (opcode, cond, 0); + /* Handle FP compare conditions. */ + case 'f': + cond = pa_parse_fp_cmp_cond (&s); + INSERT_FIELD_AND_CONTINUE (opcode, cond, 0); /* Handle an add condition. */ case 'A': case 'a': - cmpltr = 0; - flag = 0; + cmpltr = 0; + flag = 0; if (*s == ',') { s++; @@ -3251,7 +3250,7 @@ pa_ip (str) the_insn.pcrel = 1; if (!the_insn.exp.X_add_symbol || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), - "L$0\001")) + FAKE_LABEL_NAME)) { num = evaluate_absolute (&the_insn); if (num % 4) @@ -3283,7 +3282,7 @@ pa_ip (str) the_insn.pcrel = 1; if (!the_insn.exp.X_add_symbol || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), - "L$0\001")) + FAKE_LABEL_NAME)) { num = evaluate_absolute (&the_insn); if (num % 4) @@ -3314,7 +3313,7 @@ pa_ip (str) the_insn.pcrel = 1; if (!the_insn.exp.X_add_symbol || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), - "L$0\001")) + FAKE_LABEL_NAME)) { num = evaluate_absolute (&the_insn); if (num % 4) @@ -3344,7 +3343,7 @@ pa_ip (str) the_insn.pcrel = 0; if (!the_insn.exp.X_add_symbol || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), - "L$0\001")) + FAKE_LABEL_NAME)) { num = evaluate_absolute (&the_insn); if (num % 4) @@ -3949,7 +3948,7 @@ pa_ip (str) failed: /* Check if the args matched. */ - if (match == FALSE) + if (!match) { if (&insn[1] - pa_opcodes < (int) NUMOPCODES && !strcmp (insn->name, insn[1].name)) @@ -4240,8 +4239,8 @@ tc_gen_reloc (section, fixp) case R_N0SEL: case R_N1SEL: /* There is no symbol or addend associated with these fixups. */ - relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); - *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol); + relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol); relocs[i]->addend = 0; break; @@ -4249,8 +4248,8 @@ tc_gen_reloc (section, fixp) case R_ENTRY: case R_EXIT: /* There is no symbol associated with these fixups. */ - relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); - *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol); + relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol); relocs[i]->addend = fixp->fx_offset; break; @@ -4419,9 +4418,6 @@ md_apply_fix3 (fixP, valP, seg) offsetT new_val; int insn, val, fmt; - if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) - fixP->fx_done = 1; - /* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can never be "applied" (they are just markers). Likewise for R_HPPA_BEGIN_BRTAB and R_HPPA_END_BRTAB. */ @@ -4448,6 +4444,9 @@ md_apply_fix3 (fixP, valP, seg) return; #endif + if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) + fixP->fx_done = 1; + /* There should have been an HPPA specific fixup associated with the GAS fixup. */ hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data; @@ -4483,13 +4482,6 @@ md_apply_fix3 (fixP, valP, seg) || hppa_fixP->fx_r_field == e_rtsel || hppa_fixP->fx_r_field == e_ltsel) new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0); - /* This is truly disgusting. The machine independent code blindly - adds in the value of the symbol being relocated against. Damn! */ - else if (fmt == 32 - && fixP->fx_addsy != NULL - && S_GET_SEGMENT (fixP->fx_addsy) != bfd_com_section_ptr) - new_val = hppa_field_adjust (* valP - S_GET_VALUE (fixP->fx_addsy), - 0, hppa_fixP->fx_r_field); #endif else new_val = hppa_field_adjust (* valP, 0, hppa_fixP->fx_r_field); @@ -4687,7 +4679,7 @@ pa_parse_number (s, is_float) symbolS *sym; int status; char *p = *s; - boolean have_prefix; + bfd_boolean have_prefix; /* Skip whitespace before the number. */ while (*p == ' ' || *p == '\t') @@ -4826,7 +4818,7 @@ pa_parse_number (s, is_float) num = S_GET_VALUE (sym); /* Well, we don't really have one, but we do have a register, so... */ - have_prefix = true; + have_prefix = TRUE; } else if (S_GET_SEGMENT (sym) == &bfd_abs_section) num = S_GET_VALUE (sym); @@ -5227,7 +5219,7 @@ pa_get_absolute_expression (insn, strp) input_line_pointer = *strp; s = *strp; while (*s != ',' && *s != ' ' && *s != '\t') - s++; + s++; c = *s; *s = 0; @@ -8426,10 +8418,6 @@ hppa_fix_adjustable (fixp) } #endif - if (fixp->fx_addsy && (S_IS_EXTERNAL (fixp->fx_addsy) - || S_IS_WEAK (fixp->fx_addsy))) - return 0; - /* Reject reductions of symbols in sym1-sym2 expressions when the fixup will occur in a CODE subspace. @@ -8439,11 +8427,7 @@ hppa_fix_adjustable (fixp) if (fixp->fx_addsy && fixp->fx_subsy && (hppa_fix->segment->flags & SEC_CODE)) - { - /* Apparently sy_used_in_reloc never gets set for sub symbols. */ - symbol_mark_used_in_reloc (fixp->fx_subsy); - return 0; - } + return 0; /* We can't adjust any relocs that use LR% and RR% field selectors. @@ -8533,7 +8517,7 @@ hppa_force_relocation (fixp) /* Ensure we emit a relocation for global symbols so that dynamic linking works. */ - if (S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)) + if (S_FORCE_RELOC (fixp->fx_addsy, 1)) return 1; /* It is necessary to force PC-relative calls/jumps to have a relocation @@ -8547,15 +8531,27 @@ hppa_force_relocation (fixp) /* Now check to see if we're going to need a long-branch stub. */ if (fixp->fx_r_type == (int) R_HPPA_PCREL_CALL) { - valueT distance; + long pc = md_pcrel_from (fixp); + valueT distance, min_stub_distance; - distance = (fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy) - - md_pcrel_from (fixp) - 8); - if (distance + 8388608 >= 16777216 - || (hppa_fixp->fx_r_format == 17 && distance + 262144 >= 524288) -#ifdef OBJ_ELF - || (hppa_fixp->fx_r_format == 12 && distance + 8192 >= 16384) + distance = fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy) - pc - 8; + + /* Distance to the closest possible stub. This will detect most + but not all circumstances where a stub will not work. */ + min_stub_distance = pc + 16; +#ifdef OBJ_SOM + if (last_call_info != NULL) + min_stub_distance -= S_GET_VALUE (last_call_info->start_symbol); #endif + + if ((distance + 8388608 >= 16777216 + && min_stub_distance <= 8388608) + || (hppa_fixp->fx_r_format == 17 + && distance + 262144 >= 524288 + && min_stub_distance <= 262144) + || (hppa_fixp->fx_r_format == 12 + && distance + 8192 >= 16384 + && min_stub_distance <= 8192) ) return 1; } @@ -8570,7 +8566,7 @@ hppa_force_relocation (fixp) /* Now for some ELF specific code. FIXME. */ #ifdef OBJ_ELF /* Mark the end of a function so that it's possible to compute - the size of the function in hppa_elf_final_processing. */ + the size of the function in elf_hppa_final_processing. */ static void hppa_elf_mark_end_of_function ()