aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@cygnus>1993-09-03 22:36:26 +0000
committerKen Raeburn <raeburn@cygnus>1993-09-03 22:36:26 +0000
commit5cf4cd1b8bbd68c2fb21a42d0a58b3ef595156f8 (patch)
tree916f2cfce3fd56b9464bc56bba0ce21b382db5ad /gas
parent6a54ad639f7c596cf16663c3d381ac55908dc2f6 (diff)
downloadgdb-5cf4cd1b8bbd68c2fb21a42d0a58b3ef595156f8.zip
gdb-5cf4cd1b8bbd68c2fb21a42d0a58b3ef595156f8.tar.gz
gdb-5cf4cd1b8bbd68c2fb21a42d0a58b3ef595156f8.tar.bz2
more Utah changes, some cleanup of mine
Diffstat (limited to 'gas')
-rw-r--r--gas/config/obj-elf.c17
-rw-r--r--gas/config/tc-hppa.c789
-rw-r--r--gas/config/tc-hppa.h111
3 files changed, 537 insertions, 380 deletions
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 629b92b..9914db5 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 581a0bf..7be90ec 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 (&notes, 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 821ec3d..b39d4d8 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 */