From 5cf4cd1b8bbd68c2fb21a42d0a58b3ef595156f8 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Fri, 3 Sep 1993 22:36:26 +0000 Subject: [PATCH] more Utah changes, some cleanup of mine --- gas/config/obj-elf.c | 17 +- gas/config/tc-hppa.c | 789 ++++++++++++++++++++++++++----------------- gas/config/tc-hppa.h | 111 +++--- 3 files changed, 537 insertions(+), 380 deletions(-) diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 629b92b0013..9914db5b562 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -545,7 +545,8 @@ elf_stab_symbol_string (string, secname) if (seg == 0) { seg = bfd_make_section_old_way (stdoutput, newsecname); - bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_ALLOC); + bfd_set_section_flags (stdoutput, seg, + SEC_LOAD | SEC_READONLY | SEC_ALLOC); } /* free (newsecname);*/ } @@ -610,7 +611,7 @@ obj_elf_stab_generic (what, secname) asection *seg; subsegT subseg = now_subseg; -#if 1 +#if 0 /* This function doesn't work yet. Actually, this function is okay, but some finalizations are @@ -629,7 +630,7 @@ obj_elf_stab_generic (what, secname) { seg = subseg_new (secname, 0); bfd_set_section_flags (stdoutput, seg, - SEC_READONLY | SEC_ALLOC | SEC_RELOC); + SEC_LOAD | SEC_READONLY | SEC_ALLOC | SEC_RELOC); subseg_set (saved_seg, subseg); seg_is_new = 1; } @@ -751,7 +752,7 @@ obj_elf_stab_generic (what, secname) else { char *p = frag_more (4); - md_number_to_chars (p, 0, 0); + md_number_to_chars (p, 0, 4); } subseg_new ((char *) saved_seg->name, subseg); @@ -908,7 +909,7 @@ obj_elf_version () note_secp = bfd_make_section_old_way (stdoutput, ".note"); bfd_set_section_flags (stdoutput, note_secp, - SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS); + SEC_LOAD | SEC_HAS_CONTENTS | SEC_READONLY); } /* process the version string */ @@ -1107,18 +1108,18 @@ elf_frob_file () int i; for (i = 0; i < stdoutput->symcount; i++) - elf_tc_symbol (stdoutput, (elf_symbol_type *) (stdoutput->outsymbols[i]), + elf_tc_symbol (stdoutput, (PTR) (stdoutput->outsymbols[i]), i + 1); } #endif #ifdef elf_tc_final_processing - elf_tc_final_processing_hook (); + elf_tc_final_processing (); #endif /* Finally, we must make any target-specific sections. */ #ifdef elf_tc_make_sections - elf_tc_make_sections (stdoutput, NULL); + elf_tc_make_sections (stdoutput); #endif } diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index 581a0bf294e..7be90ec606a 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -29,7 +29,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "as.h" #include "subsegs.h" -/* #include "../bfd/libhppa.h" */ +#include "../bfd/libhppa.h" + +#ifdef OBJ_ELF +#include "../bfd/elf32-hppa.h" +#endif + /* * Unwind table and descriptor. */ @@ -156,9 +161,9 @@ void md_number_to_field (); void md_ri_to_chars (); void emit_relocations (); static void pa_ip (); +static void hppa_tc_make_symextn_section (); -const relax_typeS md_relax_table[] = -{0}; +const relax_typeS md_relax_table[] = {0}; /* handle of the OPCODE hash table */ static struct hash_control *op_hash = NULL; @@ -234,6 +239,8 @@ const pseudo_typeS {"ORG", pa_origin, 0}, {"origin", pa_origin, 0}, {"ORIGIN", pa_origin, 0}, + {"param", pa_param, 0}, + {"PARAM", pa_param, 0}, {"proc", pa_proc, 0}, {"PROC", pa_proc, 0}, {"procend", pa_procend, 0}, @@ -307,10 +314,10 @@ struct pa_it the_insn = 0, /* opcode */ NULL, /* nlistp */ { + O_illegal, /* exp.X_op */ NULL, /* exp.X_add_symbol */ - NULL, /* exp.X_subtract_symbol */ + NULL, /* exp.X_op_symbol */ 0, /* exp.X_add_number */ - NULL /* exp.asection */ }, 0, /* pcrel */ 0, /* fpof1 */ @@ -340,22 +347,25 @@ void print_insn (); #endif char *expr_end; -symbolS *label_symbolP; /* the last label symbol encountered */ +static symbolS *label_symbolP; /* the last label symbol encountered */ /* saved here in case a .equ is encountered */ -int label_symbol_defined; +static int label_symbol_defined; -int callinfo_found; /* T if a .callinfo appeared within the current */ -/* procedure definition and F otherwise */ +/* T if a .callinfo appeared within the current procedure definition + and F otherwise. */ +static int callinfo_found; -int within_entry_exit; /* T if the assembler is currently within a */ -/* .entry/.exit pair and F otherwise */ +/* T if the assembler is currently within a .entry/.exit pair and F + otherwise. */ +static int within_entry_exit; -int exit_processing_complete; /* T is the assembler has completed exit */ -/* processing for the current procedure */ -/* and F otherwise */ +/* T is the assembler has completed exit processing for the current + procedure and F otherwise. */ +static int exit_processing_complete; -int within_procedure; /* T if the assembler is currently within a */ -/* a procedure definition and F otherwise */ +/* T if the assembler is currently within a procedure definition and + F otherwise. */ +static int within_procedure; void ignore_rest_of_line (); /* a useful function in read.c */ @@ -365,54 +375,44 @@ void ignore_rest_of_line (); /* a useful function in read.c */ #define GDB_STRINGS GDB_STRINGS_SUBSPACE_NAME #if defined(OBJ_ELF) -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, 0x2c, 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, 0x2c, 0, 4, 0, 0, ".hppa_unwind", SUBSEG_UNWIND}, - {GDB_STRINGS, 0, 0, 0, 0, 0, 0, 254, 0x1f, 0, 4, 0, 2, ".stabstr", SUBSEG_GDB_STRINGS}, - {GDB_SYMBOLS, 0, 0, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 2, ".stab", SUBSEG_GDB_SYMBOLS}, - {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0} +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, 0x2c, 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, 0x2c, 0, 4, 0, 0, ".hppa_unwind", SUBSEG_UNWIND}, + {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0, 0} }; -struct default_space_dict pa_def_spaces[] = +static struct default_space_dict pa_def_spaces[] = { - {"$TEXT$", 0, 1, 0, 0, 8, ASEC_NULL, ".text"}, + {"$TEXT$", 0, 1, 0, 0, 8, ASEC_NULL, ".text"}, {"$PRIVATE$", 0, 1, 0, 0, 16, ASEC_NULL, ".data"}, - {GDB_DEBUG_SPACE_NAME, 0, 0, 0, 0, 255, ASEC_NULL, ".stab"}, - {NULL, 0, 0, 0, 0, 0, ASEC_NULL, NULL} + {NULL, 0, 0, 0, 0, 0, ASEC_NULL, NULL} }; #else -struct default_subspace_dict pa_def_subspaces[] = -{ - {"$CODE$", 0, 1, 0, 0, 0, 0, 24, 0x2c, 0, 8, 0, SEG_TEXT, SUBSEG_CODE}, - {"$DATA$", 0, 1, 0, 0, 0, 0, 24, 0x1f, 0, 8, 1, SEG_DATA, SUBSEG_DATA}, - {"$LIT$", 0, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, SEG_TEXT, SUBSEG_LIT}, - {"$BSS$", 0, 1, 0, 0, 0, 1, 80, 0x1f, 0, 8, 1, SEG_DATA, SUBSEG_BSS}, - {"$UNWIND$", 0, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, SEG_TEXT, SUBSEG_UNWIND}, - {GDB_STRINGS, 0, 0, 0, 0, 0, 0, 254, 0x1f, 0, 4, 0, SEG_GDB, SUBSEG_GDB_STRINGS - }, - {GDB_SYMBOLS, 0, 0, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, SEG_GDB, SUBSEG_GDB_SYMBOLS - }, - {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, SEG_GOOF, 0} +static struct default_subspace_dict pa_def_subspaces[] = +{ + {"$CODE$", 0, 1, 0, 0, 0, 0, 24, 0x2c, 0, 8, 0, SEG_TEXT, SUBSEG_CODE}, + {"$DATA$", 0, 1, 0, 0, 0, 0, 24, 0x1f, 0, 8, 1, SEG_DATA, SUBSEG_DATA}, + {"$LIT$", 0, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, SEG_TEXT, SUBSEG_LIT}, + {"$BSS$", 0, 1, 0, 0, 0, 1, 80, 0x1f, 0, 8, 1, SEG_DATA, SUBSEG_BSS}, + {"$UNWIND$", 0, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, SEG_TEXT, SUBSEG_UNWIND}, + {GDB_STRINGS, 0, 0, 0, 0, 0, 0, 254, 0x1f, 0, 4, 0, SEG_GDB, SUBSEG_GDB_STRINGS}, + {GDB_SYMBOLS, 0, 0, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, SEG_GDB, SUBSEG_GDB_SYMBOLS}, + {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, SEG_GOOF, 0} }; -struct default_space_dict pa_def_spaces[] = +static struct default_space_dict pa_def_spaces[] = { - {"$TEXT$", 0, 1, 0, 0, 8, SEG_TEXT}, - {"$PRIVATE$", 0, 1, 0, 0, 16, SEG_DATA}, + {"$TEXT$", 0, 1, 0, 0, 8, SEG_TEXT}, + {"$PRIVATE$", 0, 1, 0, 0, 16, SEG_DATA}, {GDB_DEBUG_SPACE_NAME, 0, 0, 0, 0, 255, SEG_GDB}, - {NULL, 0, 0, 0, 0, 0, SEG_GOOF} + {NULL, 0, 0, 0, 0, 0, SEG_GOOF} }; #endif -#ifdef USG -#define bcmp(b1,b2,n) memcmp((b1),(b2),(n)) -#define index strchr -#endif - #ifndef FALSE #define FALSE (0) #define TRUE (!FALSE) @@ -432,7 +432,7 @@ struct default_space_dict pa_def_spaces[] = location. */ -static const char *movers[] = +static const char *const movers[] = { /* these entries from 'static pseudo_typeS potable[]' in pa-read.c */ "ascii", "asciz", @@ -460,7 +460,7 @@ static const char *movers[] = NULL /* end sentinel */ }; -int +static int pa_pseudo_op_moves_pc (name) char *name; { @@ -474,14 +474,12 @@ pa_pseudo_op_moves_pc (name) return 0; } -/* - Support for keeping track of the most recent label in each - space. - */ +/* Support for keeping track of the most recent label in each + space. */ /* XXX: NOTE: label_symbolS is defined in pa.h */ -label_symbolS *label_symbols_rootP = NULL; +static label_symbolS *label_symbols_rootP; /* PA_GET_LABEL @@ -489,7 +487,7 @@ label_symbolS *label_symbols_rootP = NULL; Returns a pointer to the label_symbolS for the current space. */ -label_symbolS * +static label_symbolS * pa_get_label () { label_symbolS *lssP; @@ -511,7 +509,7 @@ pa_get_label () the current space. */ -int +static int pa_label_is_defined () { return (int) pa_get_label (); @@ -557,7 +555,7 @@ pa_define_label (symbolP) If there is no label_symbolS entry, then no action is taken. */ -void +static void pa_undefine_label () { label_symbolS *lssP; @@ -583,10 +581,10 @@ pa_undefine_label () /* end of label symbol support. */ -/* An HPPA-specific version of fix_new. This is required because the HPPA */ -/* 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_fixS. An hppa_fixS */ -/* stores the extra information along with a pointer to the original fixS. */ +/* An HPPA-specific version of fix_new. This is required because the HPPA + 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_fixS. An hppa_fixS + stores the extra information along with a pointer to the original fixS. */ typedef struct hppa_fix_struct { @@ -600,17 +598,17 @@ typedef struct hppa_fix_struct struct hppa_fix_struct *fx_next; } hppa_fixS; -hppa_fixS *hppa_fix_root = NULL; +static hppa_fixS *hppa_fix_root; void -fix_new_hppa (frag, where, size, add_symbol, sub_symbol, offset, pcrel, +fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel, r_type, r_field, r_format, arg_reloc, unwind_desc) fragS *frag; /* Which frag? */ int where; /* Where in that frag? */ short int size; /* 1, 2 or 4 usually. */ symbolS *add_symbol; /* X_add_symbol. */ - symbolS *sub_symbol; /* X_subtract_symbol. */ long offset; /* X_add_number. */ + expressionS *exp; /* expression (if non-null) */ int pcrel; /* TRUE if PC-relative relocation. */ #ifdef BFD_ASSEMBLER bfd_reloc_code_real_type r_type; /* Relocation type */ @@ -622,12 +620,14 @@ fix_new_hppa (frag, where, size, add_symbol, sub_symbol, offset, pcrel, long arg_reloc; char *unwind_desc; { - fixS *new_fix = fix_new (frag, where, size, - add_symbol, sub_symbol, - offset, pcrel, r_type); + fixS *new_fix; hppa_fixS *hppa_fix = (hppa_fixS *) obstack_alloc (¬es, sizeof (hppa_fixS)); + if (exp != NULL) + 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; hppa_fix->fx_r_field = r_field; hppa_fix->fx_r_format = r_format; @@ -663,7 +663,7 @@ parse_cons_expression_hppa (exp) expressionS *exp; { hppa_field_selector = pa_chk_field_selector (&input_line_pointer); - expression (&exp); + expression (exp); } /* This fix_new is called by cons via TC_CONS_FIX_NEW. @@ -688,10 +688,8 @@ cons_fix_new_hppa (frag, where, size, exp) if (hppa_field_selector != e_psel && hppa_field_selector != e_fsel) as_warn("Invalid field selector. Assuming F%%."); - fix_new_hppa (frag, where, size - exp->X_add_symbol, - exp->X_subtract_symbol, - exp->X_add_number, 0, reloc_type, + fix_new_hppa (frag, where, size, + (symbolS *) NULL, (offsetT) 0, exp, 0, reloc_type, hppa_field_selector, 32, 0, (char *) 0); } @@ -801,9 +799,9 @@ md_assemble (str) fix_new_hppa (frag_now, /* which frag */ (toP - frag_now->fr_literal), /* where */ 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, + (symbolS *) NULL, + (offsetT) 0, + &the_insn.exp, the_insn.pcrel, the_insn.reloc, the_insn.field_selector, @@ -815,9 +813,9 @@ md_assemble (str) fix_new (frag_now, /* which frag */ (toP - frag_now->fr_literal), /* where */ 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, + (symbolS *) NULL, + (offsetT) 0, + &the_insn.exp, the_insn.pcrel, the_insn.reloc, the_insn.field_selector, @@ -980,6 +978,8 @@ pa_ip (str) continue; } break; + + case 'y': /* Same as 't'. */ case 't': /* 5 bit register field at 31 */ reg = pa_parse_number (&s); if (reg < 32 && reg >= 0) @@ -993,7 +993,7 @@ pa_ip (str) reg = pa_parse_number(&s); */ getAbsoluteExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) { reg = the_insn.exp.X_add_number; if (reg <= 32 && reg > 0) @@ -1129,7 +1129,7 @@ pa_ip (str) opcode |= a << 13; continue; case '<': /* non-negated compare/subtract conditions. */ - cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s); + cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1); if (cmpltr < 0) { as_bad ("Unrecognized Compare/Subtract Condition: %c", *s); @@ -1140,11 +1140,11 @@ pa_ip (str) case '?': /* negated or non-negated cmp/sub conditions. */ /* used only by ``comb'' and ``comib'' pseudo-ops */ save_s = s; - cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s); + cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1); if (cmpltr < 0) { s = save_s; - cmpltr = pa_parse_neg_cmpsub_cmpltr (&s); + cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1); if (cmpltr < 0) { as_bad ("Unrecognized Compare/Subtract Condition: %c", *s); @@ -1164,11 +1164,11 @@ pa_ip (str) case '!': /* negated or non-negated add conditions. */ /* used only by ``addb'' and ``addib'' pseudo-ops */ save_s = s; - cmpltr = pa_parse_nonneg_add_cmpltr (&s); + cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1); if (cmpltr < 0) { s = save_s; - cmpltr = pa_parse_neg_add_cmpltr (&s); + cmpltr = pa_parse_neg_add_cmpltr (&s, 1); if (cmpltr < 0) { as_bad ("Unrecognized Compare/Subtract Condition: %c", *s); @@ -1176,11 +1176,11 @@ pa_ip (str) } else { - opcode |= 1 << 27; /* required opcode change to make - COMIBT into a COMIBF or a - COMBT into a COMBF or a - ADDBT into a ADDBF or a - ADDIBT into a ADDIBF */ + opcode |= 1 << 27; /* required opcode change to make + COMIBT into a COMIBF or a + COMBT into a COMBF or a + ADDBT into a ADDBF or a + ADDIBT into a ADDIBF */ } } opcode |= cmpltr << 13; @@ -1191,12 +1191,12 @@ pa_ip (str) save_s = s; if (*s == ',') { - cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s); + cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 0); if (cmpltr < 0) { f = 1; s = save_s; - cmpltr = pa_parse_neg_cmpsub_cmpltr (&s); + cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 0); if (cmpltr < 0) { as_bad ("Unrecognized Compare/Subtract Condition"); @@ -1431,11 +1431,12 @@ pa_ip (str) opcode |= cmpltr << 13; opcode |= f << 12; continue; + case '|': /* shift/extract/deposit in conditional. */ case '>': /* shift/extract/deposit conditions. */ cmpltr = 0; if (*s == ',') { - s++; + char *save_s = s++; name = s; while (*s != ',' && *s != ' ' && *s != '\t') s += 1; @@ -1469,6 +1470,14 @@ pa_ip (str) { cmpltr = 7; } + /* Handle movb,n. Put things back the way they were. + This includes moving s back to where it started. */ + else if (strcasecmp (name, "n") == 0 && *args == '|') + { + *s = c; + s = save_s; + continue; + } else as_bad ("Unrecognized Shift/Extract/Deposit Condition: %s", name); *s = c; @@ -1529,7 +1538,7 @@ pa_ip (str) case 'i': /* 11 bit immediate at 31 */ #ifdef OBJ_SOM getExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) { low_sign_unext (evaluateAbsolute (the_insn.exp, the_insn.field_selector), 11, &im11); @@ -1546,7 +1555,7 @@ pa_ip (str) #else the_insn.field_selector = pa_chk_field_selector (&s); getExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) { low_sign_unext (evaluateAbsolute (the_insn.exp, the_insn.field_selector), 11, &im11); @@ -1570,7 +1579,7 @@ pa_ip (str) case 'j': /* 14 bit immediate at 31 */ #ifdef OBJ_SOM getExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) { low_sign_unext (evaluateAbsolute (the_insn.exp, field_selector), 14, &im14); @@ -1590,7 +1599,7 @@ pa_ip (str) #else the_insn.field_selector = pa_chk_field_selector (&s); getExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) { low_sign_unext (evaluateAbsolute (the_insn.exp, the_insn.field_selector), 14, &im14); @@ -1618,7 +1627,7 @@ pa_ip (str) case 'k': /* 21 bit immediate at 31 */ #ifdef OBJ_SOM getExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) { dis_assemble_21 (evaluateAbsolute (the_insn.exp, the_insn.field_selector), &im21); @@ -1635,7 +1644,7 @@ pa_ip (str) #else the_insn.field_selector = pa_chk_field_selector (&s); getExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) { dis_assemble_21 (evaluateAbsolute (the_insn.exp, the_insn.field_selector), &im21); @@ -1822,8 +1831,8 @@ pa_ip (str) instructions.) */ if (strcasecmp (prev_str, "ldil") == 0 && prev_insn.exp.X_add_symbol == the_insn.exp.X_add_symbol && - prev_insn.exp.X_subtract_symbol == the_insn.exp.X_subtract_symbol && - prev_insn.exp.X_seg == the_insn.exp.X_seg && + prev_insn.exp.X_op == the_insn.exp.X_op && + prev_insn.exp.X_op_symbol == the_insn.exp.X_op_symbol && prev_insn.exp.X_add_number == the_insn.exp.X_add_number && prev_fix != NULL) prev_fix->fx_r_type = the_insn.reloc; @@ -1848,7 +1857,7 @@ pa_ip (str) /* value is encoded in instr. as 31-p where p is */ /* the value scanned here */ getExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) { opcode |= (((31 - the_insn.exp.X_add_number) & 0x1f) << 5); } @@ -1856,7 +1865,7 @@ pa_ip (str) continue; case 'P': /* 5-bit bit position at 26 */ getExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) { opcode |= (the_insn.exp.X_add_number & 0x1f) << 5; } @@ -1876,7 +1885,7 @@ pa_ip (str) continue; case 'A': /* 13 bit immediate at 18 (to support BREAK instr.) */ getAbsoluteExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) opcode |= (the_insn.exp.X_add_number & 0x1fff) << 13; s = expr_end; continue; @@ -1901,7 +1910,7 @@ pa_ip (str) the_insn.field_selector = pa_chk_field_selector (&s); #endif getExpression (s); - if (the_insn.exp.X_seg == &bfd_abs_section) + if (the_insn.exp.X_op == O_constant) { opcode |= ((evaluateAbsolute (the_insn.exp, the_insn.field_selector) & 0x1ffffff) << 1); #ifdef NEW_SOM /* XXX what replaces this? */ @@ -2179,7 +2188,7 @@ pa_ip (str) the_insn.opcode = opcode; #ifdef PA_DEBUG - if (the_insn.exp.X_add_symbol && the_insn.exp.X_subtract_symbol) + if (the_insn.exp.X_add_symbol && the_insn.exp.X_op_symbol) print_insn_short (&the_insn); fprintf (stderr, "*********** END OF STATEMENT\n"); #endif @@ -2738,19 +2747,6 @@ md_apply_fix_1 (fixP, val) || (fixP->fx_subsy && fixP->fx_subsy->bsym->section == &bfd_und_section)) return; - /* Perform some processing particular to unwind */ - /* relocations */ - - if (hppa_fixP->fx_call_infop - && (((fixP == hppa_fixP->fx_call_infop->start_fix) - && (fixP->fx_addsy == - hppa_fixP->fx_call_infop->start_symbol)) - || ((fixP == hppa_fixP->fx_call_infop->end_fix) - && (fixP->fx_addsy == - hppa_fixP->fx_call_infop->end_symbol)) - )) - val += fixP->fx_addsy->sy_frag->fr_address; - switch (fmt) { @@ -2759,7 +2755,6 @@ md_apply_fix_1 (fixP, val) /* need to check for overflow here */ /* mask off 14 bits to be changed */ - /* *(long *)buf = *(long *)buf & 0xffffc000; */ bfd_put_32 (stdoutput, bfd_get_32 (stdoutput, buf) & 0xffffc000, buf); @@ -2771,7 +2766,6 @@ md_apply_fix_1 (fixP, val) /* need to check for overflow here */ /* mask off 21 bits to be changed */ - /* *(long *)buf = *(long *)buf & 0xffe00000; */ bfd_put_32 (stdoutput, bfd_get_32 (stdoutput, buf) & 0xffe00000, buf); @@ -2783,7 +2777,6 @@ md_apply_fix_1 (fixP, val) /* need to check for overflow here */ /* mask off 11 bits to be changed */ - /* *(long *)buf = *(long *)buf & 0xffff800; */ bfd_put_32 (stdoutput, bfd_get_32 (stdoutput, buf) & 0xffff800, buf); @@ -2795,34 +2788,53 @@ md_apply_fix_1 (fixP, val) /* mask off 11 bits to be changed */ sign_unext ((new_val - 8) >> 2, 12, &result); - /* *(long *)buf = *(long *)buf & 0xffffe002; */ bfd_put_32 (stdoutput, bfd_get_32 (stdoutput, buf) & 0xffffe002, buf); dis_assemble_12 (result, &w1, &w); result = ((w1 << 2) | w); + fixP->fx_addsy = NULL; /* No relocations please. */ break; +#define too_far(VAL, NUM_BITS) \ + (((int)(VAL) > (1 << (NUM_BITS)) - 1) || ((int)(VAL) < (-1 << (NUM_BITS)))) + +#define stub_needed(CALLER, CALLEE) \ + ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER))) + case 17: /* some of the opcodes with the 'W' operand type */ + if (too_far (val, 18) + || stub_needed (((elf32_symbol_type *) fixP->fx_addsy->bsym)->tc_data.hppa_arg_reloc, + hppa_fixP->fx_arg_reloc)) + /* Keep the relocation because we can't reach the target with + a short call, or if an argument relocation stub is needed. */ + return; + new_val = apply_field_selector (val, 0, hppa_fixP->fx_r_field); /* need to check for overflow here */ /* mask off 17 bits to be changed */ - /* *(long *)buf = *(long *)buf & 0xffe0e002; */ bfd_put_32 (stdoutput, bfd_get_32 (stdoutput, buf) & 0xffe0e002, buf); sign_unext ((new_val - 8) >> 2, 17, &result); dis_assemble_17 (result, &w1, &w2, &w); result = ((w2 << 2) | (w1 << 16) | w); + fixP->fx_addsy = NULL; /* No relocations please. */ break; case 32: - new_val = apply_field_selector (val, 0, hppa_fixP->fx_r_field); - result = new_val; /* no transformation on result */ - /* *(long *)buf = 0; *//* clear out everything */ - bfd_put_32 (stdoutput, 0, buf); /* clear out everything */ + if (hppa_fixP->fx_r_type == R_HPPA_UNWIND_ENTRY + || hppa_fixP->fx_r_type == R_HPPA_UNWIND_ENTRIES) + result = fixP->fx_addnumber; + else + { + result = 0; + fixP->fx_addnumber = fixP->fx_offset; + bfd_put_32 (stdoutput, 0, buf); /* clear out everything */ + return; /* still need the relocation */ + } break; case 0: @@ -2852,7 +2864,7 @@ md_apply_fix_1 (fixP, val) int md_apply_fix (fixP, valp) fixS *fixP; - long *valp; + valueT *valp; { md_apply_fix_1 (fixP, *valp); return 1; @@ -3778,15 +3790,9 @@ getExpression (str) save_in = input_line_pointer; input_line_pointer = str; seg = expression (&the_insn.exp); - - if (!(seg == &bfd_abs_section - || seg == &bfd_und_section - || seg == text_section - || seg == data_section - || seg == bss_section - || seg == diff_section - || seg == big_section - || seg == absent_section)) + if (!(seg == absolute_section + || seg == undefined_section + || SEG_NORMAL (seg))) { the_insn.error = "bad segment"; expr_end = input_line_pointer; @@ -3798,29 +3804,6 @@ getExpression (str) return 0; } -int -getAbsoluteExpression (str) - char *str; -{ - char *save_in; - asection *seg; - - save_in = input_line_pointer; - input_line_pointer = str; - seg = expression (&the_insn.exp); - - if (seg != &bfd_abs_section) - { - the_insn.error = "segment should be ABSOLUTE"; - expr_end = input_line_pointer; - input_line_pointer = save_in; - return 1; - } - expr_end = input_line_pointer; - input_line_pointer = save_in; - return 0; -} - #else int getExpression (str) @@ -3831,22 +3814,11 @@ getExpression (str) save_in = input_line_pointer; input_line_pointer = str; - switch (seg = expression (&the_insn.exp)) + seg = expression (&the_insn.exp); + if (!(seg == absolute_section + || seg == undefined_section + || SEG_NORMAL (seg))) { - - case SEG_ABSOLUTE: - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - case SEG_BIG: - case SEG_GDB: - case SEG_MILLICODE: - case SEG_NONE: - break; - - default: the_insn.error = "illegal segment"; expr_end = input_line_pointer; input_line_pointer = save_in; @@ -3857,22 +3829,19 @@ getExpression (str) return 0; } +#endif + int getAbsoluteExpression (str) char *str; { char *save_in; - segT seg; save_in = input_line_pointer; input_line_pointer = str; - switch (seg = expression (&the_insn.exp)) + expression (&the_insn.exp); + if (the_insn.exp.X_op != O_constant) { - - case SEG_ABSOLUTE: - break; - - default: the_insn.error = "segment should be ABSOLUTE"; expr_end = input_line_pointer; input_line_pointer = save_in; @@ -3883,8 +3852,6 @@ getAbsoluteExpression (str) return 0; } -#endif - int evaluateAbsolute (exp, field_selector) expressionS exp; @@ -3894,15 +3861,6 @@ evaluateAbsolute (exp, field_selector) value = exp.X_add_number; - if (exp.X_add_symbol) - { - value += S_GET_VALUE (exp.X_add_symbol); - } - if (exp.X_subtract_symbol) - { - value -= S_GET_VALUE (exp.X_subtract_symbol); - } - switch (field_selector) { case e_fsel: /* F : no change */ @@ -4040,21 +3998,20 @@ pa_parse_nullif (s) return nullif; } -#if 0 int -pa_parse_nonneg_cmpsub_cmpltr (s) +pa_parse_nonneg_cmpsub_cmpltr (s, isbranch) char **s; + int isbranch; { int cmpltr; - char *name; + char *name = *s + 1; char c; + char *save_s = *s; - cmpltr = -1; - /** cmpltr = 0; **/ + cmpltr = 0; if (**s == ',') { *s += 1; - name = *s; while (**s != ',' && **s != ' ' && **s != '\t') *s += 1; c = **s; @@ -4087,69 +4044,16 @@ pa_parse_nonneg_cmpsub_cmpltr (s) { cmpltr = 7; } - /** - else - cmpltr = -1; - **/ - **s = c; - } - if (cmpltr >= 0) - { - while (**s == ' ' || **s == '\t') - *s = *s + 1; - } - - return cmpltr; -} - -#endif -int -pa_parse_nonneg_cmpsub_cmpltr (s) - char **s; -{ - int cmpltr; - char *name; - char c; - - cmpltr = 0; - if (**s == ',') - { - *s += 1; - name = *s; - while (**s != ',' && **s != ' ' && **s != '\t') - *s += 1; - c = **s; - **s = 0x00; - if (strcmp (name, "=") == 0) - { - cmpltr = 1; - } - else if (strcmp (name, "<") == 0) - { - cmpltr = 2; - } - else if (strcmp (name, "<=") == 0) + /* If we have something like addb,n then there is no condition + completer. */ + else if (strcasecmp (name, "n") == 0 && isbranch) { - cmpltr = 3; - } - else if (strcmp (name, "<<") == 0) - { - cmpltr = 4; - } - else if (strcmp (name, "<<=") == 0) - { - cmpltr = 5; - } - else if (strcasecmp (name, "sv") == 0) - { - cmpltr = 6; + cmpltr = 0; } - else if (strcasecmp (name, "od") == 0) + else { - cmpltr = 7; + cmpltr = -1; } - else - cmpltr = -1; **s = c; } if (cmpltr >= 0) @@ -4158,22 +4062,27 @@ pa_parse_nonneg_cmpsub_cmpltr (s) *s = *s + 1; } + /* Reset pointers if this was really a ,n for a branch instruction. */ + if (cmpltr == 0 && *name == 'n' && isbranch) + *s = save_s; + return cmpltr; } int -pa_parse_neg_cmpsub_cmpltr (s) +pa_parse_neg_cmpsub_cmpltr (s, isbranch) char **s; + int isbranch; { int cmpltr; - char *name; + char *name = *s + 1; char c; + char *save_s = *s; - cmpltr = -1; + cmpltr = 0; if (**s == ',') { *s += 1; - name = *s; while (**s != ',' && **s != ' ' && **s != '\t') *s += 1; c = **s; @@ -4210,6 +4119,16 @@ pa_parse_neg_cmpsub_cmpltr (s) { cmpltr = 7; } + /* If we have something like addb,n then there is no condition + completer. */ + else if (strcasecmp (name, "n") == 0 && isbranch) + { + cmpltr = 0; + } + else + { + cmpltr = -1; + } **s = c; } if (cmpltr >= 0) @@ -4218,22 +4137,27 @@ pa_parse_neg_cmpsub_cmpltr (s) *s = *s + 1; } + /* Reset pointers if this was really a ,n for a branch instruction. */ + if (cmpltr == 0 && *name == 'n' && isbranch) + *s = save_s; + return cmpltr; } int -pa_parse_nonneg_add_cmpltr (s) +pa_parse_nonneg_add_cmpltr (s, isbranch) char **s; + int isbranch; { int cmpltr; - char *name; + char *name = *s + 1; char c; + char *save_s = *s; - cmpltr = -1; + cmpltr = 0; if (**s == ',') { *s += 1; - name = *s; while (**s != ',' && **s != ' ' && **s != '\t') *s += 1; c = **s; @@ -4266,6 +4190,16 @@ pa_parse_nonneg_add_cmpltr (s) { cmpltr = 7; } + /* If we have something like addb,n then there is no condition + completer. */ + else if (strcasecmp (name, "n") == 0 && isbranch) + { + cmpltr = 0; + } + else + { + cmpltr = -1; + } **s = c; } if (cmpltr >= 0) @@ -4274,22 +4208,27 @@ pa_parse_nonneg_add_cmpltr (s) *s = *s + 1; } + /* Reset pointers if this was really a ,n for a branch instruction. */ + if (cmpltr == 0 && *name == 'n' && isbranch) + *s = save_s; + return cmpltr; } int -pa_parse_neg_add_cmpltr (s) +pa_parse_neg_add_cmpltr (s, isbranch) char **s; + int isbranch; { int cmpltr; - char *name; + char *name = *s + 1; char c; + char *save_s = *s; - cmpltr = -1; + cmpltr = 0; if (**s == ',') { *s += 1; - name = *s; while (**s != ',' && **s != ' ' && **s != '\t') *s += 1; c = **s; @@ -4326,6 +4265,16 @@ pa_parse_neg_add_cmpltr (s) { cmpltr = 7; } + /* If we have something like addb,n then there is no condition + completer. */ + else if (strcasecmp (name, "n") == 0 && isbranch) + { + cmpltr = 0; + } + else + { + cmpltr = -1; + } **s = c; } if (cmpltr >= 0) @@ -4334,6 +4283,10 @@ pa_parse_neg_add_cmpltr (s) *s = *s + 1; } + /* Reset pointers if this was really a ,n for a branch instruction. */ + if (cmpltr == 0 && *name == 'n' && isbranch) + *s = save_s; + return cmpltr; } @@ -4539,9 +4492,9 @@ pa_build_unwind_subspace (call_info) { seg = bfd_make_section_old_way (stdoutput, UNWIND_SECTION_NAME); } - bfd_set_section_flags (stdoutput, - seg, - SEC_READONLY | SEC_ALLOC | SEC_LOAD | SEC_RELOC); + bfd_set_section_flags (stdoutput, seg, + (SEC_READONLY | SEC_HAS_CONTENTS + | SEC_LOAD | SEC_RELOC)); /* callinfo.frame is in bytes and unwind_desc is in 8 byte units */ call_info->ci_unwind.descriptor.frame_size = call_info->frame / 8; @@ -4561,8 +4514,9 @@ pa_build_unwind_subspace (call_info) /* relocation info. for start offset of the function */ fix_new_hppa (frag_now, p - frag_now->fr_literal, 4, - call_info->start_symbol, (symbolS *) NULL, - 0, 0, R_HPPA, e_fsel, 32, 0, (char *) 0); + call_info->start_symbol, (offsetT) 0, + (expressionS *) NULL, 0, R_HPPA_UNWIND, e_fsel, 32, 0, + (char *) 0); /** we need to search for the first relocation involving the start_symbol of **/ /** this call_info descriptor **/ @@ -4589,8 +4543,9 @@ pa_build_unwind_subspace (call_info) /* relocation info. for end offset of the function */ fix_new_hppa (frag_now, p - frag_now->fr_literal, 4, - call_info->end_symbol, (symbolS *) NULL, - 0, 0, R_HPPA, e_fsel, 32, 0, (char *) 0); + call_info->end_symbol, (offsetT) 0, + (expressionS *) NULL, 0, R_HPPA_UNWIND, e_fsel, 32, 0, + (char *) 0); /** we need to search for the first relocation involving the start_symbol of **/ /** this call_info descriptor **/ @@ -4686,8 +4641,9 @@ pa_build_unwind_subspace (call_info) /* relocation info. for start offset of the function */ fix_new (frag_now, p - frag_now->fr_literal, 4, - call_info->start_symbol, (symbolS *) NULL, - 0, 0, R_DATA_ONE_SYMBOL, e_fsel, 0, 0, (char *) 0); + call_info->start_symbol, (offsetT) 0, + (expressionS *) NULL, 0, R_DATA_ONE_SYMBOL, e_fsel, 0, 0, + (char *) 0); /** we need to search for the first relocation involving the start_symbol of **/ /** this call_info descriptor **/ @@ -4722,8 +4678,9 @@ pa_build_unwind_subspace (call_info) /* relocation info. for end offset of the function */ fix_new (frag_now, p - frag_now->fr_literal, 4, - call_info->start_symbol, (symbolS *) NULL, - 0, 0, R_DATA_ONE_SYMBOL, e_fsel, 0, 0, (char *) 0); + call_info->start_symbol, (offsetT) 0, + (expressionS *) NULL, 0, R_DATA_ONE_SYMBOL, e_fsel, 0, 0, + (char *) 0); /** we need to search for the first relocation involving the start_symbol of **/ /** this call_info descriptor **/ @@ -5010,7 +4967,7 @@ pa_copyright () char *company_name = name; char *date_part; - date_part = (char *) index (name, ','); + date_part = (char *) strchr (name, ','); if (date_part) { *date_part = 0x00; @@ -5109,15 +5066,17 @@ pa_entry () within_entry_exit = TRUE; where = frag_more (0); #ifdef OBJ_SOM - fix_new (frag_now, where - frag_now->fr_literal, 0, - last_call_info->start_symbol, (symbolS *) NULL, 0, 0, - R_ENTRY, e_fsel, 0, 0, (char *) &last_call_info->ci_unwind.descriptor); + 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); #else #ifdef OBJ_ELF /* XXX: no ENTRY relocation for PA ELF. What do we do instead? */ #else fix_new_hppa (frag_now, where - frag_now->fr_literal, 0, - last_call_info->start_symbol, (symbolS *) NULL, 0, 0, + last_call_info->start_symbol, (offsetT) 0, + (expressionS *) NULL, 0, R_HPPA_ENTRY, 0, 0, 0, (char *) &last_call_info->ci_unwind.descriptor); #endif @@ -5165,9 +5124,10 @@ process_exit () where = frag_more (0); #ifdef OBJ_SOM - fix_new (frag_now, where - frag_now->fr_literal, 0, - last_call_info->start_symbol, (symbolS *) NULL, 0, - 0, R_EXIT, e_fsel, 0, 0, (char *) NULL); + 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 /* XXX: no EXIT relocation for PA ELF. All we do is create a */ @@ -5197,7 +5157,7 @@ process_exit () assert (symbolP); - symbolP->bsym->flags = last_call_info->start_symbol->bsym->flags; + symbolP->bsym->flags = BSF_LOCAL; symbol_table_insert (symbolP); } if (symbolP) @@ -5211,8 +5171,9 @@ process_exit () } #else fix_new_hppa (frag_now, where - frag_now->fr_literal, 0, - last_call_info->start_symbol, (symbolS *) NULL, 0, - 0, R_HPPA_EXIT, 0, 0, 0, (char *) NULL); + last_call_info->start_symbol, (offsetT) 0, + (expressionS *) NULL, 0, R_HPPA_EXIT, 0, 0, 0, + (char *) NULL); #endif last_call_info->end_frag = frag_now; @@ -5246,6 +5207,25 @@ pa_exit () return; } +#ifdef OBJ_ELF +void + pa_build_symextn_section() +{ + segT seg; + asection *save_seg = now_seg; + subsegT subseg = (subsegT)0; + subsegT save_subseg = now_subseg; + + seg = subseg_new(".hppa_symextn", subseg); + bfd_set_section_flags (stdoutput, + seg, + SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC | SEC_LOAD); + + subseg_new(save_seg->name, save_subseg); + +} +#endif + void pa_export () { @@ -5286,6 +5266,9 @@ pa_export () { input_line_pointer++; pa_export_args (symbolP); +#ifdef OBJ_ELF + pa_build_symextn_section(); +#endif } } @@ -5303,7 +5286,7 @@ pa_export_args (symbolP) register int temp; register unsigned int arg_reloc; #ifdef OBJ_ELF - elf_symbol_type *esymbolP = (elf_symbol_type *) (symbolP->bsym); + elf32_symbol_type *esymbolP = (elf32_symbol_type *) (symbolP->bsym); #endif if (strncasecmp (input_line_pointer, "absolute", 8) == 0) @@ -5551,12 +5534,60 @@ pa_leave () void pa_origin () { - s_org (); /* ORG actually allows another argument (the fill value) - but maybe this is OK? */ + s_org (); /* ORG actually allows another argument + (the fill value) but maybe this is OK? */ pa_undefine_label (); return; } + +void +pa_param () +{ + char *name; + char c; + char *p; + int temp; + int regno; + symbolS *symbolP; + + name = input_line_pointer; + c = get_symbol_end (); + /* just after name is now '\0' */ + + if ((symbolP = symbol_find_or_make (name)) == NULL) + { + as_bad ("Cannot define static symbol: %s\n", name); + p = input_line_pointer; + *p = c; + input_line_pointer++; + } + else + { +#ifdef OBJ_SOM + symbolP->pa_sy_dict.symbol_scope = SS_LOCAL; + /* determination of the symbol_type field will have to wait until + we know the subspace index (within the object file) of the subspace + containing this symbol */ +#else + /* S_SET_SEGMENT(symbolP,&bfd_und_section); */ + S_CLEAR_EXTERNAL (symbolP); + /* symbolP->sy_frag = frag_now; */ +#endif + + p = input_line_pointer; + *p = c; + if (!is_end_of_statement ()) + { + input_line_pointer++; + pa_export_args (symbolP); + } + } + + demand_empty_rest_of_line (); + return; +} + void pa_proc () { @@ -5897,11 +5928,15 @@ pa_space () current_subspace = pa_subsegment_to_subspace (SEG_GDB, sd_chain->sd_last_subseg); #else - if (now_seg != gdb_section) /* no need to align if we are already there */ - pa_align_subseg (now_seg, now_subseg); - subseg_new ((char *) gdb_section->name, sd_chain->sd_last_subseg); - current_subspace = pa_subsegment_to_subspace (gdb_section, - sd_chain->sd_last_subseg); + { + asection *gdb_section + = bfd_make_section_old_way (stdoutput, GDB_DEBUG_SPACE_NAME); + if (now_seg != gdb_section) /* no need to align if we are already there */ + pa_align_subseg (now_seg, now_subseg); + subseg_new ((char *) gdb_section->name, sd_chain->sd_last_subseg); + current_subspace = pa_subsegment_to_subspace (gdb_section, + sd_chain->sd_last_subseg); + } #endif demand_empty_rest_of_line (); return; @@ -6217,7 +6252,7 @@ pa_subspace () /* fr_fix != 0. */ void -elf_hppa_final_processing_hook () +elf_hppa_final_processing () { extern call_infoS *call_info_root; @@ -6225,10 +6260,9 @@ elf_hppa_final_processing_hook () for (ciP = call_info_root; ciP; ciP = ciP->ci_next) { - elf_symbol_type *esym = (elf_symbol_type *) ciP->start_symbol->bsym; + elf32_symbol_type *esym = (elf32_symbol_type *) ciP->start_symbol->bsym; esym->internal_elf_sym.st_size = - ciP->end_symbol->bsym->value - - ciP->start_symbol->bsym->value + 4; + S_GET_VALUE (ciP->end_symbol) - S_GET_VALUE (ciP->start_symbol) + 4; } } @@ -6242,9 +6276,6 @@ space_dict_chainS *space_dict_last; space_dict_chainS *current_space; subspace_dict_chainS *current_subspace; -extern symbolS *start_symbol_root; -extern symbolS *start_symbol_last; - void pa_spaces_begin () { @@ -6255,9 +6286,6 @@ pa_spaces_begin () space_dict_root = NULL; space_dict_last = NULL; - start_symbol_root = NULL; - start_symbol_last = NULL; - /* create default space and subspace dictionaries */ i = 0; @@ -6850,7 +6878,11 @@ pa_stringer (append_zero) /* Worker to do .ascii etc statements. */ for (i = 0; i <= num_digit; i++) s_start[i] = num_buf[i]; } + break; } + /* This might be a "\"", skip over the escaped char. */ + default: + s++; break; } } @@ -6939,3 +6971,132 @@ pa_text () s_text (); pa_undefine_label (); } + +static symext_chainS *symext_rootP = NULL; +static symext_chainS *symext_lastP = NULL; + +void +hppa_tc_symbol (abfd, symbolP, sym_idx) + bfd * abfd; + elf_symbol_type * symbolP; + int sym_idx; +{ + symext_chainS *symextP; + unsigned int arg_reloc; + + if (!(symbolP->symbol.flags & BSF_FUNCTION)) + return; + + arg_reloc = symbolP->tc_data.hppa_arg_reloc; + + symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2); + + symextP[0].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, sym_idx); + symextP[0].next = &symextP[1]; + + symextP[1].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC, arg_reloc); + symextP[1].next = NULL; + + if (symext_rootP == NULL) + { + symext_rootP = &symextP[0]; + symext_lastP = &symextP[1]; + } + else + { + symext_lastP->next = &symextP[0]; + symext_lastP = &symextP[1]; + } +} + +void +hppa_tc_make_sections (abfd) +bfd * abfd; +{ + symext_chainS *symextP; + symext_entryS *outbound_symexts; + int size; + int n; + extern void hppa_elf_stub_finish (); /* forward declaration */ + asection *symextn_sec; + segT save_seg = now_seg; + subsegT save_subseg = now_subseg; + + hppa_tc_make_symextn_section(); + + bfd_set_section_contents(stdoutput, stdoutput->sections, "", 0, 0); /* force some calculations */ + + hppa_elf_stub_finish (abfd); + + if (symext_rootP == NULL) + return; + + for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n) + ; + + size = sizeof (symext_entryS) * n; + + symextn_sec = subseg_new(SYMEXTN_SECTION_NAME, 0); + + frag_wane (frag_now); + frag_new (0); + + for (symextP = symext_rootP; symextP; symextP = symextP->next) + { + char *ptr; + extern int *elf_get_symtab_map(); + Elf_Sym_Extra *symextra = elf_sym_extra (abfd); + int idx; + + /* First, patch the symbol extension record to reflect the true */ + /* symbol table index */ + + if (ELF32_HPPA_SX_TYPE(symextP->entry) == HPPA_SXT_SYMNDX) + { + idx = ELF32_HPPA_SX_VAL(symextP->entry) - 1; + symextP->entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, + symextra[idx].elf_sym_num); + } + + ptr = frag_more(sizeof(symextP->entry)); + md_number_to_chars(ptr,symextP->entry,sizeof(symextP->entry)); + } + + frag_now->fr_fix = obstack_next_free (&frags) - frag_now->fr_literal; + frag_wane (frag_now); + + /* now, switch back to the original segment */ + + subseg_new(save_seg->name, save_subseg); + + return; +} + +static void +hppa_tc_make_symextn_section() +{ + extern symext_chainS *elf32_hppa_get_symextn_chain(); + + if (symext_rootP) + { + symext_chainS *symextP; + int n; + int size; + segT symextn_sec; + segT save_seg = now_seg; + subsegT save_subseg = now_subseg; + + for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n) + ; + + size = sizeof (symext_entryS) * n; + + symextn_sec = subseg_new(SYMEXTN_SECTION_NAME, 0); + + bfd_set_section_flags(stdoutput, symextn_sec, SEC_LOAD | SEC_HAS_CONTENTS | SEC_DATA); + bfd_set_section_size (stdoutput, symextn_sec, size); + + /* now, switch back to the original segment */ + subseg_new(save_seg->name, save_subseg); + } +} diff --git a/gas/config/tc-hppa.h b/gas/config/tc-hppa.h index 821ec3d00d1..b39d4d83672 100644 --- a/gas/config/tc-hppa.h +++ b/gas/config/tc-hppa.h @@ -1,6 +1,6 @@ /* tc-hppa.h -- Header file for the PA */ -/* Copyright (C) 1989 Free Software Foundation, Inc. +/* Copyright (C) 1989, 1993 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -31,9 +31,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define TC_HPPA 1 #endif +#ifdef OBJ_ELF +#include "../bfd/elf32-hppa.h" +#endif + #define TARGET_ARCH bfd_arch_hppa #define TARGET_FORMAT "elf32-hppa" +/* Local labels have an "L$" prefix. */ +#define LOCAL_LABEL(name) ((name)[0] == 'L' && (name)[1] == '$') #define ASEC_NULL (asection *)0 /* We can do sym1 - sym2 as long as sym2 is $global$ */ @@ -106,6 +112,7 @@ void pa_entry (), pa_equ (), pa_exit (), pa_export (); void pa_export_args (), pa_import (), pa_label (), pa_leave (); void pa_origin (), pa_proc (), pa_procend (), pa_space (); void pa_spnum (), pa_subspace (), pa_version (); +void pa_param(); extern const pseudo_typeS md_pseudo_table[]; @@ -150,28 +157,6 @@ int need_89_opcode (); int pa_89_parse_number (); -/* pa-ctrl-func.h -- Control Structures and Functions for the PA */ - -extern unsigned int assemble_3 ( /* unsigned int x; */ ); - -extern void dis_assemble_3 ( /* unsigned int x, *r; */ ); - -extern unsigned int assemble_12 ( /* unsigned int x,y; */ ); - -extern void dis_assemble_12 ( /* unsigned int as12, *x,*y */ ); - -extern unsigned long assemble_17 ( /* unsigned int x,y,z */ ); - -extern void dis_assemble_17 ( /* unsigned int as17, *x,*y,*z */ ); - -extern unsigned long assemble_21 ( /* unsigned int x; */ ); - -extern void dis_assemble_21 ( /* unsigned int as21,*x; */ ); - -extern void sign_unext ( /* unsigned int x,len; unsigned int *result */ ); - -extern void low_sign_unext ( /* unsigned int x,len; unsigned int *result */ ); - struct call_desc { unsigned int arg_reloc; @@ -237,7 +222,7 @@ struct subspace_dictionary_chain the object file is written */ int ssd_last_align; /* the size of the last alignment request for this subspace */ - symbolS *ssd_start_sym; /* a symbol whose value is the + struct symbol *ssd_start_sym; /* a symbol whose value is the start of this subspace */ struct subspace_dictionary_chain *ssd_next; /* next subspace dict. entry */ }; @@ -336,15 +321,15 @@ typedef struct space_dictionary_chain space_dict_chainS; #define STAB_FIXUP(frag,toptr,symP,stab_type) \ if ( (stab_type == 's' || stab_type == 'n') \ - && symP->sy_value.X_seg == undefined_section) \ + && symP->sy_value.X_op == O_symbol) \ { \ int i = S_GET_TYPE(symP) & N_TYPE; \ fix_new_hppa(frag, \ toptr-frag->fr_literal, /* where */ \ 4, /* size */ \ symP->sy_value.X_add_symbol, /* addr of sym for this stab */ \ - (asymbol *)NULL, \ - 0, \ + (offsetT) 0, \ + (expressionS *) NULL, \ i == N_UNDF || i == N_ABS, /* 1 if internal reloc */ \ R_HPPA, /* type */ \ e_fsel, /* fixup fld = F% */ \ @@ -359,8 +344,8 @@ typedef struct space_dictionary_chain space_dict_chainS; toptr-frag->fr_literal, /* where */ \ 4, /* size */ \ symP, /* addr of sym for this stab */ \ - (asymbol *)NULL, \ - 0, \ + (offsetT) 0, \ + (expressionS *) NULL, \ 0, \ R_HPPA, /* type */ \ e_fsel, /* fixup fld = F% */ \ @@ -422,9 +407,9 @@ extern int is_last_defined_subspace (); /* symbol support */ -extern symbolS *pa_get_start_symbol (); +extern struct symbol *pa_get_start_symbol (); -extern symbolS *pa_set_start_symbol (); +extern struct symbol *pa_set_start_symbol (); /* default space and subspace dictionaries */ @@ -432,7 +417,8 @@ struct default_subspace_dict { char *name; char defined; - char loadable, code_only, common, dup_common, zero, sort; + char loadable, code_only, common, dup_common, zero; + unsigned char sort; int access, space_index, alignment, quadrant; #ifdef OBJ_SOM segT segment; @@ -452,12 +438,13 @@ struct default_space_dict char loadable; char defined; char private; - char sort; + unsigned char sort; #ifdef OBJ_SOM segT segment; #else asection *segment; - char *alias; /* an alias for this section (or NULL if there isn't one) */ + /* an alias for this section (or NULL if there isn't one) */ + char *alias; #endif }; @@ -472,50 +459,58 @@ extern struct default_space_dict pa_def_spaces[]; typedef struct label_symbol_struct { - symbolS *lss_label; /* the label symbol */ - space_dict_chainS *lss_space; /* the space to which it applies*/ - struct label_symbol_struct *lss_next; /* the next label symbol */ + /* the label symbol */ + struct symbol *lss_label; + /* the space to which it applies */ + space_dict_chainS *lss_space; + /* the next label symbol */ + struct label_symbol_struct *lss_next; } label_symbolS; -extern label_symbolS *label_symbols_rootP; - -label_symbolS *pa_get_label (); -int pa_label_is_defined (); void pa_define_label (); -void pa_undefine_label (); -int pa_pseudo_op_moves_pc (); /* end of label symbol support. */ -#define is_DP_relative(exp) ( (exp).X_subtract_symbol \ - && strcmp((exp).X_subtract_symbol->bsym->name, \ - "$global$") == 0 ) +#define is_DP_relative(exp) \ + ((exp).X_op == O_subtract \ + && strcmp((exp).X_op_symbol->bsym->name, "$global$") == 0) -#define is_PC_relative(exp) ( (exp).X_subtract_symbol \ - && strcmp((exp).X_subtract_symbol->bsym->name, \ - "$PIC_pcrel$0") == 0 ) +#define is_PC_relative(exp) \ + ((exp).X_op == O_subtract \ + && strcmp((exp).X_op_symbol->bsym->name, "$PIC_pcrel$0") == 0) -#define is_complex(exp) ((exp).X_seg && (exp).X_seg == diff_section) +#define is_complex(exp) \ + ((exp).X_op != O_constant && (exp).X_op != O_symbol) #define tc_crawl_symbol_chain(headers) {;} /* Not used. */ #define tc_headers_hook(headers) {;} /* Not used. */ -#define elf_tc_symbol elf_hppa_tc_symbol -#define elf_tc_make_sections elf_hppa_tc_make_sections +#define elf_tc_symbol hppa_tc_symbol +#define elf_tc_make_sections hppa_tc_make_sections extern void elf_hppa_final_processing (); #define elf_tc_final_processing elf_hppa_final_processing /* We need to parse field selectors in .byte, etc. */ #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \ - parse_cons_expression_hppa (exp) + parse_cons_expression_hppa (EXP) #define TC_CONS_FIX_NEW cons_fix_new_hppa -extern void parse_cons_expression_hppa PARAMS ((expressionS *exp)); -extern void cons_fix_new_hppa PARAMS ((fragS *frag, - int where, - int size, - expressionS *exp)); +/* FIXME these used to be prototypes, but both want an expressionS which + is not defined when this file is included. */ +extern void parse_cons_expression_hppa (); +extern void cons_fix_new_hppa (); + +/* On the PA, an equal sign often appears as a condition or nullification + completer in an instruction. This can be detected by checking the + previous character, if the character is a comma, then the equal is + being used as part of an instruction. */ +#define TC_EQUAL_IN_INSN(C, PTR) ((C) == ',') + +/* Similarly for an exclamation point. It is used in FP comparison + instructions and as an end of line marker. When used in an instruction + it will always follow a comma. */ +#define TC_EOL_IN_INSN(PTR) (is_end_of_line[*(PTR)] && (PTR)[-1] == ',') #endif /* _TC_HPPA_H */ -- 2.30.2