From ad1079af05c5820e0f4e9d1ba24d30c03bff98f6 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sun, 9 Jul 2000 08:16:21 +0000 Subject: Add linux-elf flavour to pseudos in tc-hppa.c and some tidying and bug fixes. Handle wide mode relocs. Don't select target size based on BFD64. --- gas/config/tc-hppa.c | 409 +++++++++++++++++++++++++++----------------- gas/config/tc-hppa.h | 20 +-- gas/config/te-hppa.h | 3 + gas/config/te-hppa64.h | 6 + gas/config/te-hppalinux64.h | 5 + 5 files changed, 272 insertions(+), 171 deletions(-) create mode 100644 gas/config/te-hppa64.h create mode 100644 gas/config/te-hppalinux64.h (limited to 'gas/config') diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index 61f42c1..6506ec4 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -1,5 +1,5 @@ /* tc-hppa.c -- Assemble for the PA - Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 1999 + Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -30,7 +30,6 @@ #include "subsegs.h" #include "bfd/libhppa.h" -#include "bfd/libbfd.h" /* Be careful, this file includes data *declarations*. */ #include "opcode/hppa.h" @@ -45,18 +44,19 @@ error only one of OBJ_ELF and OBJ_SOM can be defined #ifdef OBJ_ELF #include "dwarf2dbg.h" struct dwarf2_line_info debug_line; -#endif /* A "convient" place to put object file dependencies which do not need to be seen outside of tc-hppa.c. */ -#ifdef OBJ_ELF + /* Object file formats specify relocation types. */ -typedef elf_hppa_reloc_type reloc_type; +typedef enum elf_hppa_reloc_type reloc_type; /* Object file formats specify BFD symbol types. */ typedef elf_symbol_type obj_symbol_type; +#define symbol_arg_reloc_info(sym)\ + (((obj_symbol_type *) symbol_get_bfdsym (sym))->tc_data.hppa_arg_reloc) -#ifdef BFD64 +#if TARGET_ARCH_SIZE == 64 /* How to generate a relocation. */ #define hppa_gen_reloc_type _bfd_elf64_hppa_gen_reloc_type #else @@ -69,7 +69,7 @@ typedef elf_symbol_type obj_symbol_type; #define obj_copyright obj_elf_version #define UNWIND_SECTION_NAME ".PARISC.unwind" -#endif +#endif /* OBJ_ELF */ #ifdef OBJ_SOM /* Names of various debugging spaces/subspaces. */ @@ -90,12 +90,13 @@ typedef int reloc_type; /* Object file formats specify BFD symbol types. */ typedef som_symbol_type obj_symbol_type; +#define symbol_arg_reloc_info(sym)\ + (((obj_symbol_type *) symbol_get_bfdsym (sym))->tc_data.ap.hppa_arg_reloc) /* This apparently isn't in older versions of hpux reloc.h. */ #ifndef R_DLT_REL #define R_DLT_REL 0x78 #endif -#endif #ifndef R_N0SEL #define R_N0SEL 0xd8 @@ -104,6 +105,7 @@ typedef som_symbol_type obj_symbol_type; #ifndef R_N1SEL #define R_N1SEL 0xd9 #endif +#endif /* OBJ_SOM */ /* Various structures and types used internally in tc-hppa.c. */ @@ -219,7 +221,7 @@ struct pa_it /* Holds any argument relocation bits associated with this instruction. (instruction should be some sort of call). */ - long arg_reloc; + unsigned int arg_reloc; /* The format specification for this instruction. */ int format; @@ -438,7 +440,7 @@ struct hppa_fix_struct int fx_r_format; /* Argument relocation bits. */ - long fx_arg_reloc; + unsigned int fx_arg_reloc; /* The segment this fixup appears in. */ segT segment; @@ -474,15 +476,18 @@ struct selector_entry static void pa_check_current_space_and_subspace PARAMS ((void)); #endif +#if !(defined (OBJ_ELF) && defined (TE_LINUX)) +static void pa_text PARAMS ((int)); +static void pa_data PARAMS ((int)); +static void pa_comm PARAMS ((int)); +#endif static fp_operand_format pa_parse_fp_format PARAMS ((char **s)); static void pa_cons PARAMS ((int)); -static void pa_data PARAMS ((int)); static void pa_float_cons PARAMS ((int)); static void pa_fill PARAMS ((int)); static void pa_lcomm PARAMS ((int)); static void pa_lsym PARAMS ((int)); static void pa_stringer PARAMS ((int)); -static void pa_text PARAMS ((int)); static void pa_version PARAMS ((int)); static int pa_parse_fp_cmp_cond PARAMS ((char **)); static int get_expression PARAMS ((char *)); @@ -504,8 +509,6 @@ static void pa_try PARAMS ((int)); static void pa_call PARAMS ((int)); static void pa_call_args PARAMS ((struct call_desc *)); static void pa_callinfo PARAMS ((int)); -static void pa_code PARAMS ((int)); -static void pa_comm PARAMS ((int)); static void pa_copyright PARAMS ((int)); static void pa_end PARAMS ((int)); static void pa_enter PARAMS ((int)); @@ -560,10 +563,10 @@ static void pa_spaces_begin PARAMS ((void)); #endif static void pa_ip PARAMS ((char *)); static void fix_new_hppa PARAMS ((fragS *, int, int, symbolS *, - long, expressionS *, int, + offsetT, expressionS *, int, bfd_reloc_code_real_type, enum hppa_reloc_field_selector_type_alt, - int, long, int *)); + int, unsigned int, int *)); static int is_end_of_statement PARAMS ((void)); static int reg_name_search PARAMS ((char *)); static int pa_chk_field_selector PARAMS ((char **)); @@ -604,10 +607,6 @@ static struct call_desc last_call_desc; /* handle of the OPCODE hash table */ static struct hash_control *op_hash = NULL; -/* This array holds the chars that always start a comment. If the - pre-processor is disabled, these aren't very useful. */ -const char comment_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? */ @@ -628,25 +627,33 @@ const pseudo_typeS md_pseudo_table[] = {"byte", pa_cons, 1}, {"call", pa_call, 0}, {"callinfo", pa_callinfo, 0}, - {"code", pa_code, 0}, +#if defined (OBJ_ELF) && defined (TE_LINUX) + {"code", obj_elf_text, 0}, +#else + {"code", pa_text, 0}, {"comm", pa_comm, 0}, +#endif #ifdef OBJ_SOM {"compiler", pa_compiler, 0}, #endif {"copyright", pa_copyright, 0}, +#if !(defined (OBJ_ELF) && defined (TE_LINUX)) {"data", pa_data, 0}, +#endif {"double", pa_float_cons, 'd'}, {"dword", pa_cons, 8}, {"end", pa_end, 0}, {"end_brtab", pa_brtab, 0}, +#if !(defined (OBJ_ELF) && defined (TE_LINUX)) {"end_try", pa_try, 0}, +#endif {"enter", pa_enter, 0}, {"entry", pa_entry, 0}, {"equ", pa_equ, 0}, {"exit", pa_exit, 0}, {"export", pa_export, 0}, #ifdef OBJ_ELF - { "file", dwarf2_directive_file, 0 }, + {"file", dwarf2_directive_file, 0 }, #endif {"fill", pa_fill, 0}, {"float", pa_float_cons, 'f'}, @@ -658,7 +665,7 @@ const pseudo_typeS md_pseudo_table[] = {"leave", pa_leave, 0}, {"level", pa_level, 0}, #ifdef OBJ_ELF - { "loc", dwarf2_directive_loc, 0 }, + {"loc", dwarf2_directive_loc, 0 }, #endif {"long", pa_cons, 4}, {"lsym", pa_lsym, 0}, @@ -684,7 +691,9 @@ const pseudo_typeS md_pseudo_table[] = #ifdef OBJ_SOM {"subspa", pa_subspace, 0}, #endif +#if !(defined (OBJ_ELF) && defined (TE_LINUX)) {"text", pa_text, 0}, +#endif {"version", pa_version, 0}, {"word", pa_cons, 4}, {NULL, 0, 0} @@ -701,6 +710,10 @@ const pseudo_typeS md_pseudo_table[] = Also note that C style comments will always work. */ const char line_comment_chars[] = "#"; +/* This array holds the chars that always start a comment. If the + pre-processor is disabled, these aren't very useful. */ +const char comment_chars[] = ";"; + /* This array holds the characters which act as line separators. */ const char line_separator_chars[] = "!"; @@ -731,7 +744,7 @@ static int within_entry_exit; /* Nonzero if the assembler is currently within a procedure definition. */ static int within_procedure; -/* Handle on strucutre which keep track of the last symbol +/* Handle on structure which keep track of the last symbol seen in each subspace. */ static label_symbol_struct *label_symbols_rootp = NULL; @@ -1264,13 +1277,13 @@ fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel, int where; int size; symbolS *add_symbol; - long offset; + offsetT offset; expressionS *exp; int pcrel; bfd_reloc_code_real_type r_type; enum hppa_reloc_field_selector_type_alt r_field; int r_format; - long arg_reloc; + unsigned int arg_reloc; int* unwind_bits ATTRIBUTE_UNUSED; { fixS *new_fix; @@ -1333,7 +1346,10 @@ cons_fix_new_hppa (frag, where, size, exp) rel_type = R_HPPA; if (hppa_field_selector != e_psel && hppa_field_selector != e_fsel) - as_warn (_("Invalid field selector. Assuming F%%.")); + { + as_warn (_("Invalid field selector. Assuming F%%.")); + hppa_field_selector = e_fsel; + } fix_new_hppa (frag, where, size, (symbolS *) NULL, (offsetT) 0, exp, 0, rel_type, @@ -1711,7 +1727,7 @@ pa_ip (str) s = expr_end; /* When in strict mode, we want to just reject this match instead of giving an out of range error. */ - CHECK_FIELD (num, 15, -16, strict) + CHECK_FIELD (num, 15, -16, strict); num = low_sign_unext (num, 5); INSERT_FIELD_AND_CONTINUE (opcode, num, 0); @@ -1721,8 +1737,8 @@ pa_ip (str) if (strict && the_insn.exp.X_op != O_constant) break; s = expr_end; - CHECK_FIELD (num, 31, 0, 0); - INSERT_FIELD_AND_CONTINUE (opcode, num, strict); + CHECK_FIELD (num, 31, 0, strict); + INSERT_FIELD_AND_CONTINUE (opcode, num, 0); /* Handle an unsigned 5 bit immediate at 15. */ case 'R': @@ -1758,7 +1774,7 @@ pa_ip (str) break; num = pa_parse_number (&s, 0); CHECK_FIELD (num, 7, 0, 1); - opcode = re_assemble_3 (opcode, num); + opcode |= re_assemble_3 (num); continue; /* Handle all completers. */ @@ -2622,7 +2638,6 @@ pa_ip (str) } else if (*s == '*') break; - name = s; name = s; while (*s != ',' && *s != ' ' && *s != '\t') @@ -2630,7 +2645,6 @@ pa_ip (str) c = *s; *s = 0x00; - if (strcmp (name, "=") == 0) cmpltr = 1; else if (strcmp (name, "<") == 0) @@ -2691,7 +2705,6 @@ pa_ip (str) } else if (*s == '*') break; - name = s; name = s; while (*s != ',' && *s != ' ' && *s != '\t') @@ -2987,7 +3000,7 @@ pa_ip (str) break; } - /* Handle 14 bit immediated, shifted left three times. */ + /* Handle 14 bit immediate, shifted left three times. */ case '#': the_insn.field_selector = pa_chk_field_selector (&s); get_expression (s); @@ -3079,7 +3092,7 @@ pa_ip (str) { num = evaluate_absolute (&the_insn); CHECK_FIELD (num >> 11, 1048575, -1048576, 0); - opcode = re_assemble_21 (opcode, num); + opcode |= re_assemble_21 (num); continue; } else @@ -3103,7 +3116,7 @@ pa_ip (str) { num = evaluate_absolute (&the_insn); CHECK_FIELD (num, 32767, -32768, 0); - opcode = re_assemble_16 (opcode, num, 1); + opcode |= re_assemble_16 (num); continue; } else @@ -3129,7 +3142,7 @@ pa_ip (str) num = evaluate_absolute (&the_insn); CHECK_FIELD (num, 32767, -32768, 0); CHECK_ALIGN (num, 4, 0); - opcode = re_assemble_16 (opcode, num, 1); + opcode |= re_assemble_16 (num); continue; } else @@ -3155,7 +3168,7 @@ pa_ip (str) num = evaluate_absolute (&the_insn); CHECK_FIELD (num, 32767, -32768, 0); CHECK_ALIGN (num, 8, 0); - opcode = re_assemble_16 (opcode, num, 1); + opcode |= re_assemble_16 (num); continue; } else @@ -3187,7 +3200,7 @@ pa_ip (str) } CHECK_FIELD (num, 8199, -8184, 0); - opcode = re_assemble_12 (opcode, (num - 8) >> 2); + opcode |= re_assemble_12 ((num - 8) >> 2); continue; } else @@ -3221,7 +3234,7 @@ pa_ip (str) if (the_insn.exp.X_add_symbol) num -= 8; - opcode = re_assemble_17 (opcode, num >> 2); + opcode |= re_assemble_17 (num >> 2); continue; } else @@ -3254,7 +3267,7 @@ pa_ip (str) if (the_insn.exp.X_add_symbol) num -= 8; - opcode = re_assemble_22 (opcode, num >> 2); + opcode |= re_assemble_22 (num >> 2); } else { @@ -3286,7 +3299,7 @@ pa_ip (str) if (the_insn.exp.X_add_symbol) num -= 8; - opcode = re_assemble_17 (opcode, num >> 2); + opcode |= re_assemble_17 (num >> 2); continue; } else @@ -4021,16 +4034,17 @@ tc_gen_reloc (section, fixp) { arelent *reloc; struct hppa_fix_struct *hppa_fixp; - bfd_reloc_code_real_type code; static arelent *no_relocs = NULL; arelent **relocs; - bfd_reloc_code_real_type **codes; + reloc_type **codes; + reloc_type code; int n_relocs; int i; hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data; if (fixp->fx_addsy == 0) return &no_relocs; + assert (hppa_fixp != 0); assert (section != 0); @@ -4038,7 +4052,7 @@ tc_gen_reloc (section, fixp) reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); - codes = (bfd_reloc_code_real_type **) hppa_gen_reloc_type (stdoutput, + codes = hppa_gen_reloc_type (stdoutput, fixp->fx_r_type, hppa_fixp->fx_r_format, hppa_fixp->fx_r_field, @@ -4068,11 +4082,11 @@ tc_gen_reloc (section, fixp) reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); - reloc->howto = bfd_reloc_type_lookup (stdoutput, code); + reloc->howto = bfd_reloc_type_lookup (stdoutput, + (bfd_reloc_code_real_type) code); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; - reloc->addend = 0; /* default */ - assert (reloc->howto && code == reloc->howto->type); + assert (reloc->howto && (unsigned int) code == reloc->howto->type); /* Now, do any processing that is dependent on the relocation type. */ switch (code) @@ -4095,15 +4109,61 @@ tc_gen_reloc (section, fixp) reloc->addend = 0; break; - case R_PARISC_PCREL21L: +#ifdef ELF_ARG_RELOC case R_PARISC_PCREL17R: case R_PARISC_PCREL17F: case R_PARISC_PCREL17C: - case R_PARISC_PCREL14R: - case R_PARISC_PCREL14F: - /* The constant is stored in the instruction. */ - reloc->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, 0); + case R_PARISC_DIR17R: + case R_PARISC_DIR17F: + { + char *buf = fixp->fx_where + fixp->fx_frag->fr_literal; + int insn = bfd_get_32 (stdoutput, buf); + +#ifdef ELF_ARG_RELOC_INSN + /* Store the arg reloc in the instruction. */ + insn = ((insn & ~ 0x1ff8) + | ((hppa_fixp->fx_arg_reloc << 3) & 0x1ff8)); + bfd_put_32 (stdoutput, insn, buf); + reloc->addend = fixp->fx_offset; +#else + /* The high 22 bits of the constant are stored in the + reloc. The remaining 10 bits can be retrieved from the + instruction. */ + insn = (insn & ~ 0x7f8) | ((fixp->fx_offset & 0x3fc) << 1); + bfd_put_32 (stdoutput, insn, buf); + reloc->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, + fixp->fx_offset >> 10); +#endif + } break; + + case R_PARISC_PCREL21L: + case R_PARISC_DIR21L: + { + char *buf = fixp->fx_where + fixp->fx_frag->fr_literal; + int insn = bfd_get_32 (stdoutput, buf); + +#ifdef ELF_ARG_RELOC_INSN + /* Store the arg reloc in the instruction. */ + insn = ((insn & ~ 0xff9) + | ((hppa_fixp->fx_arg_reloc >> 9) & 1) + | ((hppa_fixp->fx_arg_reloc << 3) & 0xff8)); + bfd_put_32 (stdoutput, insn, buf); + reloc->addend = fixp->fx_offset; +#else + /* In this case, the instruction stores the high bits, so + the reloc stores the low 22 bits. */ + insn = ((insn & ~ 0xff9) + | ((fixp->fx_offset >> 31) & 1) + | ((fixp->fx_offset >> 19) & 0xff8)); + bfd_put_32 (stdoutput, insn, buf); + reloc->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, + fixp->fx_offset); +#endif + } + break; +#endif + default: reloc->addend = fixp->fx_offset; break; @@ -4119,7 +4179,9 @@ tc_gen_reloc (section, fixp) relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); - relocs[i]->howto = bfd_reloc_type_lookup (stdoutput, code); + relocs[i]->howto = + bfd_reloc_type_lookup (stdoutput, + (bfd_reloc_code_real_type) code); relocs[i]->address = fixp->fx_frag->fr_address + fixp->fx_where; switch (code) @@ -4130,25 +4192,35 @@ tc_gen_reloc (section, fixp) relocs now and break out of the loop. */ assert (i == 1); relocs[0]->sym_ptr_ptr = (asymbol **) &(bfd_abs_symbol); - relocs[0]->howto = bfd_reloc_type_lookup (stdoutput, *codes[0]); + relocs[0]->howto = + bfd_reloc_type_lookup (stdoutput, + (bfd_reloc_code_real_type) *codes[0]); relocs[0]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[0]->addend = 0; relocs[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); *relocs[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); - relocs[1]->howto = bfd_reloc_type_lookup (stdoutput, *codes[1]); + relocs[1]->howto = + bfd_reloc_type_lookup (stdoutput, + (bfd_reloc_code_real_type) *codes[1]); relocs[1]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[1]->addend = 0; relocs[2]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); *relocs[2]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy); - relocs[2]->howto = bfd_reloc_type_lookup (stdoutput, *codes[2]); + relocs[2]->howto = + bfd_reloc_type_lookup (stdoutput, + (bfd_reloc_code_real_type) *codes[2]); relocs[2]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[2]->addend = 0; relocs[3]->sym_ptr_ptr = (asymbol **) &(bfd_abs_symbol); - relocs[3]->howto = bfd_reloc_type_lookup (stdoutput, *codes[3]); + relocs[3]->howto = + bfd_reloc_type_lookup (stdoutput, + (bfd_reloc_code_real_type) *codes[3]); relocs[3]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[3]->addend = 0; relocs[4]->sym_ptr_ptr = (asymbol **) &(bfd_abs_symbol); - relocs[4]->howto = bfd_reloc_type_lookup (stdoutput, *codes[4]); + relocs[4]->howto = + bfd_reloc_type_lookup (stdoutput, + (bfd_reloc_code_real_type) *codes[4]); relocs[4]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[4]->addend = 0; goto done; @@ -4272,7 +4344,12 @@ md_estimate_size_before_relax (fragP, segment) return size; } -CONST char *md_shortopts = ""; +#ifdef OBJ_ELF +const char *md_shortopts = "V"; +#else +const char *md_shortopts = ""; +#endif + struct option md_longopts[] = { {NULL, no_argument, NULL, 0} }; @@ -4283,7 +4360,19 @@ md_parse_option (c, arg) int c ATTRIBUTE_UNUSED; char *arg ATTRIBUTE_UNUSED; { - return 0; + switch (c) + { + default: + return 0; + +#ifdef OBJ_ELF + case 'V': + print_version_id (); + break; +#endif + } + + return 1; } void @@ -4301,6 +4390,13 @@ md_undefined_symbol (name) return 0; } +#if defined (SOM) || defined (ELF_ARG_RELOC) +#define arg_reloc_stub_needed(CALLER, CALLEE) \ + ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER))) +#else +#define arg_reloc_stub_needed(CALLER, CALLEE) 0 +#endif + /* Apply a fixup to an instruction. */ int @@ -4311,7 +4407,7 @@ md_apply_fix (fixP, valp) char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; struct hppa_fix_struct *hppa_fixP; offsetT new_val; - unsigned int insn, val; + int insn, val; hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data; /* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can @@ -4335,19 +4431,19 @@ md_apply_fix (fixP, valp) } #endif + insn = bfd_get_32 (stdoutput, (unsigned char *)buf); /* There should have been an HPPA specific fixup associated with the GAS fixup. */ if (hppa_fixP) { - unsigned long buf_wd = bfd_get_32 (stdoutput, buf); - int fmt = bfd_hppa_insn2fmt (buf_wd); + int fmt = bfd_hppa_insn2fmt (stdoutput, insn); /* If there is a symbol associated with this fixup, then it's something which will need a SOM relocation (except for some PC-relative relocs). In such cases we should treat the "val" or "addend" as zero since it will be added in as needed from fx_offset in tc_gen_reloc. */ if ((fixP->fx_addsy != NULL - || fixP->fx_r_type == R_HPPA_NONE) + || fixP->fx_r_type == (int) R_HPPA_NONE) #ifdef OBJ_SOM && fmt != 32 #endif @@ -4374,25 +4470,19 @@ md_apply_fix (fixP, valp) new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field); /* Handle pc-relative exceptions from above. */ -#define arg_reloc_stub_needed(CALLER, CALLEE) \ - ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER))) if ((fmt == 12 || fmt == 17 || fmt == 22) && fixP->fx_addsy && fixP->fx_pcrel -#ifdef OBJ_SOM - && !arg_reloc_stub_needed ((long) ((obj_symbol_type *) - symbol_get_bfdsym (fixP->fx_addsy))->tc_data.ap.hppa_arg_reloc, - hppa_fixP->fx_arg_reloc) -#endif - && (((int)(*valp) > -262144 && (int)(*valp) < 262143) && fmt != 22) + && !arg_reloc_stub_needed (symbol_arg_reloc_info (fixP->fx_addsy), + hppa_fixP->fx_arg_reloc) + && (*valp + 262144) < 524288 && S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment && !(fixP->fx_subsy && S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment)) - - new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field); -#undef arg_reloc_stub_needed + { + new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field); + } - insn = bfd_get_32 (stdoutput, buf); switch (fmt) { case 10: @@ -4419,10 +4509,10 @@ md_apply_fix (fixP, valp) /* Handle all opcodes with the 'k' operand type. */ case 21: - CHECK_FIELD (new_val, 1048576, -1048576, 0); + CHECK_FIELD (new_val, 1048575, -1048576, 0); val = new_val; - insn = re_assemble_21 (insn & ~ 0x1fffff, val); + insn = (insn & ~ 0x1fffff) | re_assemble_21 (val); break; /* Handle all the opcodes with the 'i' operand type. */ @@ -4438,7 +4528,7 @@ md_apply_fix (fixP, valp) CHECK_FIELD (new_val, 8199, -8184, 0); val = new_val; - insn = re_assemble_12 (insn & ~ 0x1ffd, (val - 8) >> 2); + insn = (insn & ~ 0x1ffd) | re_assemble_12 ((val - 8) >> 2); break; /* Handle some of the opcodes with the 'W' operand type. */ @@ -4448,14 +4538,14 @@ md_apply_fix (fixP, valp) /* If this is an absolute branch (ie no link) with an out of range target, then we want to complain. */ - if (fixP->fx_r_type == R_HPPA_PCREL_CALL + if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL && (insn & 0xffe00000) == 0xe8000000) CHECK_FIELD (distance, 262143, -262144, 0); CHECK_FIELD (new_val, 262143, -262144, 0); val = new_val; - insn = re_assemble_17 (insn & ~ 0x1f1ffd, (val - 8) >> 2); + insn = (insn & ~ 0x1f1ffd) | re_assemble_17 ((val - 8) >> 2); break; } @@ -4465,17 +4555,32 @@ md_apply_fix (fixP, valp) /* If this is an absolute branch (ie no link) with an out of range target, then we want to complain. */ - if (fixP->fx_r_type == R_HPPA_PCREL_CALL + if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL && (insn & 0xffe00000) == 0xe8000000) CHECK_FIELD (distance, 8388607, -8388608, 0); CHECK_FIELD (new_val, 8388607, -8388608, 0); val = new_val; - insn = re_assemble_22 (insn & ~ 0x3ff1ffd, (val - 8) >> 2); + insn = (insn & ~ 0x3ff1ffd) | re_assemble_22 ((val - 8) >> 2); break; } + case -10: + val = new_val; + insn = (insn & ~ 0xfff1) | re_assemble_16 (val & -8); + break; + + case -16: + val = new_val; + insn = (insn & ~ 0xfff9) | re_assemble_16 (val & -4); + break; + + case 16: + val = new_val; + insn = (insn & ~ 0xffff) | re_assemble_16 (val); + break; + case 32: insn = new_val; break; @@ -4486,7 +4591,7 @@ md_apply_fix (fixP, valp) } /* Insert the relocation. */ - bfd_put_32 (stdoutput, insn, buf); + bfd_put_32 (stdoutput, insn, (unsigned char *) buf); return 1; } else @@ -6217,10 +6322,11 @@ pa_callinfo (unused) demand_empty_rest_of_line (); } -/* Switch into the code subspace. */ - +#if !(defined (OBJ_ELF) && defined (TE_LINUX)) +/* Switch to the text space. Like s_text, but delete our + label when finished. */ static void -pa_code (unused) +pa_text (unused) int unused ATTRIBUTE_UNUSED; { #ifdef OBJ_SOM @@ -6228,10 +6334,25 @@ pa_code (unused) current_subspace = pa_subsegment_to_subspace (current_space->sd_seg, 0); #endif + s_text (0); pa_undefine_label (); } +/* Switch to the data space. As usual delete our label. */ +static void +pa_data (unused) + int unused ATTRIBUTE_UNUSED; +{ +#ifdef OBJ_SOM + current_space = is_defined_space ("$PRIVATE$"); + current_subspace + = pa_subsegment_to_subspace (current_space->sd_seg, 0); +#endif + s_data (0); + pa_undefine_label (); +} + /* This is different than the standard GAS s_comm(). On HP9000/800 machines, the .comm pseudo-op has the following symtax: @@ -6281,6 +6402,7 @@ pa_comm (unused) } demand_empty_rest_of_line (); } +#endif /* !(defined (OBJ_ELF) && defined (TE_LINUX)) */ /* Process a .END pseudo-op. */ @@ -6495,9 +6617,6 @@ pa_type_args (symbolP, is_export) char *name, c, *p; unsigned int temp, arg_reloc; pa_symbol_type type = SYMBOL_TYPE_UNKNOWN; -#ifdef OBJ_SOM - obj_symbol_type *symbol = (obj_symbol_type *) symbol_get_bfdsym (symbolP); -#endif if (strncasecmp (input_line_pointer, "absolute", 8) == 0) @@ -6594,8 +6713,8 @@ pa_type_args (symbolP, is_export) name = input_line_pointer; c = get_symbol_end (); arg_reloc = pa_align_arg_reloc (temp, pa_build_arg_reloc (name)); -#ifdef OBJ_SOM - symbol->tc_data.ap.hppa_arg_reloc |= arg_reloc; +#if defined (SOM) || defined (ELF_ARG_RELOC) + symbol_arg_reloc_info (symbolP) |= arg_reloc; #endif *input_line_pointer = c; } @@ -6608,8 +6727,8 @@ pa_type_args (symbolP, is_export) name = input_line_pointer; c = get_symbol_end (); arg_reloc = pa_build_arg_reloc (name); -#ifdef OBJ_SOM - symbol->tc_data.ap.hppa_arg_reloc |= arg_reloc; +#if defined (SOM) || defined (ELF_ARG_RELOC) + symbol_arg_reloc_info (symbolP) |= arg_reloc; #endif *input_line_pointer = c; } @@ -6621,7 +6740,8 @@ pa_type_args (symbolP, is_export) input_line_pointer++; temp = atoi (input_line_pointer); #ifdef OBJ_SOM - symbol->tc_data.ap.hppa_priv_level = temp; + ((obj_symbol_type *) symbol_get_bfdsym (symbolP)) + ->tc_data.ap.hppa_priv_level = temp; #endif c = get_symbol_end (); *input_line_pointer = c; @@ -6828,7 +6948,7 @@ pa_param (unused) } /* Handle a .PROC pseudo-op. It is used to mark the beginning - of a procedure from a syntatical point of view. */ + of a procedure from a syntactical point of view. */ static void pa_proc (unused) @@ -7990,11 +8110,6 @@ pa_stringer_aux (s) { unsigned int c = *s & CHAR_MASK; -#ifdef OBJ_SOM - /* We must have a valid space and subspace. */ - pa_check_current_space_and_subspace (); -#endif - switch (c) { case '\"': @@ -8017,9 +8132,14 @@ pa_stringer (append_zero) int i; /* Preprocess the string to handle PA-specific escape sequences. - For example, \xDD where DD is a hexidecimal number should be + For example, \xDD where DD is a hexadecimal number should be changed to \OOO where OOO is an octal number. */ +#ifdef OBJ_SOM + /* We must have a valid space and subspace. */ + pa_check_current_space_and_subspace (); +#endif + /* Skip the opening quote. */ s = input_line_pointer + 1; @@ -8038,7 +8158,7 @@ pa_stringer (append_zero) char dg; char *s_start = s; - /* Get pas the 'x'. */ + /* Get past the 'x'. */ s++; for (num_digit = 0, number = 0, dg = *s; num_digit < 2 @@ -8128,21 +8248,6 @@ pa_cons (nbytes) pa_undefine_label (); } -/* Switch to the data space. As usual delete our label. */ - -static void -pa_data (unused) - int unused ATTRIBUTE_UNUSED; -{ -#ifdef OBJ_SOM - current_space = is_defined_space ("$PRIVATE$"); - current_subspace - = pa_subsegment_to_subspace (current_space->sd_seg, 0); -#endif - s_data (0); - pa_undefine_label (); -} - /* Like float_cons, but we need to undefine our label. */ static void @@ -8198,22 +8303,6 @@ pa_lsym (unused) pa_undefine_label (); } -/* Switch to the text space. Like s_text, but delete our - label when finished. */ -static void -pa_text (unused) - int unused ATTRIBUTE_UNUSED; -{ -#ifdef OBJ_SOM - current_space = is_defined_space ("$TEXT$"); - current_subspace - = pa_subsegment_to_subspace (current_space->sd_seg, 0); -#endif - - s_text (0); - 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. @@ -8305,46 +8394,41 @@ hppa_fix_adjustable (fixp) int hppa_force_relocation (fixp) - fixS *fixp; + struct fix *fixp; { struct hppa_fix_struct *hppa_fixp; int distance; hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data; #ifdef OBJ_SOM - if (fixp->fx_r_type == R_HPPA_ENTRY || fixp->fx_r_type == R_HPPA_EXIT - || fixp->fx_r_type == R_HPPA_BEGIN_BRTAB - || fixp->fx_r_type == R_HPPA_END_BRTAB - || fixp->fx_r_type == R_HPPA_BEGIN_TRY - || fixp->fx_r_type == R_HPPA_END_TRY + if (fixp->fx_r_type == (int) R_HPPA_ENTRY + || fixp->fx_r_type == (int) R_HPPA_EXIT + || fixp->fx_r_type == (int) R_HPPA_BEGIN_BRTAB + || fixp->fx_r_type == (int) R_HPPA_END_BRTAB + || fixp->fx_r_type == (int) R_HPPA_BEGIN_TRY + || fixp->fx_r_type == (int) R_HPPA_END_TRY || (fixp->fx_addsy != NULL && fixp->fx_subsy != NULL && (hppa_fixp->segment->flags & SEC_CODE) != 0)) return 1; #endif -#define arg_reloc_stub_needed(CALLER, CALLEE) \ - ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER))) - -#ifdef OBJ_SOM /* 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 call stub. FIXME. Can't we need the same for absolute calls? */ if (fixp->fx_pcrel && fixp->fx_addsy - && (arg_reloc_stub_needed ((long) ((obj_symbol_type *) - symbol_get_bfdsym (fixp->fx_addsy))->tc_data.ap.hppa_arg_reloc, - hppa_fixp->fx_arg_reloc))) + && (arg_reloc_stub_needed (symbol_arg_reloc_info (fixp->fx_addsy), + hppa_fixp->fx_arg_reloc))) return 1; -#endif + 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 + if (fixp->fx_r_type == (int) R_HPPA_PCREL_CALL && (distance > 262143 || distance < -262144)) return 1; - if (fixp->fx_r_type == R_HPPA_ABS_CALL) + if (fixp->fx_r_type == (int) R_HPPA_ABS_CALL) return 1; -#undef arg_reloc_stub_needed /* No need (yet) to force another relocations to be emitted. */ return 0; @@ -8360,10 +8444,18 @@ hppa_elf_mark_end_of_function () { /* ELF does not have EXIT relocations. All we do is create a temporary symbol marking the end of the function. */ - char *name = (char *) - xmalloc (strlen ("L$\001end_") + - strlen (S_GET_NAME (last_call_info->start_symbol)) + 1); + char *name; + + if (last_call_info == NULL || last_call_info->start_symbol == NULL) + { + /* We have already warned about a missing label, + or other problems. */ + return; + } + name = (char *) xmalloc (strlen ("L$\001end_") + + strlen (S_GET_NAME (last_call_info->start_symbol)) + + 1); if (name) { symbolS *symbolP; @@ -8428,10 +8520,9 @@ elf_hppa_final_processing () - S_GET_VALUE (call_info_pointer->start_symbol) + 4; } } -#endif -#ifdef OBJ_ELF -void pa_end_of_source () +void +pa_end_of_source () { if (debug_type == DEBUG_DWARF2) dwarf2_finish (); diff --git a/gas/config/tc-hppa.h b/gas/config/tc-hppa.h index fce147c..69de41a 100644 --- a/gas/config/tc-hppa.h +++ b/gas/config/tc-hppa.h @@ -47,7 +47,7 @@ #define WORKING_DOT_WORD #ifdef OBJ_ELF -#if BFD_ARCH_SIZE == 64 +#if TARGET_ARCH_SIZE == 64 #include "bfd/elf64-hppa.h" #define TARGET_FORMAT "elf64-hppa" #else @@ -69,18 +69,12 @@ #define ASEC_NULL (asection *)0 -/* Labels are not required to have a colon for a suffix. */ -#define LABELS_WITHOUT_COLONS 1 +/* pa_define_label gets used outside of tc-hppa.c via tc_frob_label. */ +extern void pa_define_label PARAMS ((symbolS *)); -/* FIXME. This should be static and declared in tc-hppa.c, but - pa_define_label gets used outside of tc-hppa.c via tc_frob_label. - Should also be PARAMized, but symbolS isn't available here. */ -extern void pa_define_label (); - -/* FIXME. Types not available here, so they can't be PARAMized. */ -extern void parse_cons_expression_hppa (); -extern void cons_fix_new_hppa (); -extern int hppa_force_relocation (); +extern void parse_cons_expression_hppa PARAMS ((expressionS *)); +extern void cons_fix_new_hppa PARAMS ((fragS *, int, int, expressionS *)); +extern int hppa_force_relocation PARAMS ((struct fix *)); /* This gets called before writing the object file to make sure things like entry/exit and proc/procend pairs match. */ @@ -101,6 +95,7 @@ extern void pa_check_eof PARAMS ((void)); #ifdef OBJ_ELF #define elf_tc_final_processing elf_hppa_final_processing void elf_hppa_final_processing PARAMS ((void)); +void pa_end_of_source PARAMS ((void)); #endif /* The PA needs to parse field selectors in .byte, etc. */ @@ -120,6 +115,7 @@ void elf_hppa_final_processing PARAMS ((void)); it will always follow a comma. */ #define TC_EOL_IN_INSN(PTR) (*(PTR) == '!' && (PTR)[-1] == ',') +int hppa_fix_adjustable PARAMS((struct fix *)); #define tc_fix_adjustable hppa_fix_adjustable /* Because of the strange PA calling conventions, it is sometimes diff --git a/gas/config/te-hppa.h b/gas/config/te-hppa.h index 466f5f9..f250b4e 100644 --- a/gas/config/te-hppa.h +++ b/gas/config/te-hppa.h @@ -21,5 +21,8 @@ /* HP PA-RISC and OSF/1 support was contributed by the Center for Software Science at the University of Utah. */ +/* Labels are not required to have a colon for a suffix. */ +#define LABELS_WITHOUT_COLONS 1 + /* These define interfaces. */ #include "obj-format.h" diff --git a/gas/config/te-hppa64.h b/gas/config/te-hppa64.h new file mode 100644 index 0000000..dfeb62b --- /dev/null +++ b/gas/config/te-hppa64.h @@ -0,0 +1,6 @@ +#define TARGET_ARCH_SIZE 64 + +/* Labels are not required to have a colon for a suffix. */ +#define LABELS_WITHOUT_COLONS 1 + +#include "obj-format.h" diff --git a/gas/config/te-hppalinux64.h b/gas/config/te-hppalinux64.h new file mode 100644 index 0000000..4d67c95 --- /dev/null +++ b/gas/config/te-hppalinux64.h @@ -0,0 +1,5 @@ +#define TE_LINUX +#define TARGET_ARCH_SIZE 64 +#define LOCAL_LABELS_FB 1 + +#include "obj-format.h" -- cgit v1.1