* som.c (struct som_misc_symbol_info): Add is_comdat, is_common and
[deliverable/binutils-gdb.git] / gas / config / tc-hppa.c
index e9eb8e1b0f9572e5a766418d080975e224165c97..72abe1dedb54a4571e56cc26bbab72d17c1d3452 100644 (file)
@@ -1,6 +1,6 @@
 /* tc-hppa.c -- Assemble for the PA
    Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002 Free Software Foundation, Inc.
+   2002, 2003 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -43,7 +43,7 @@ error only one of OBJ_ELF and OBJ_SOM can be defined
 #ifdef OBJ_ELF
 #include "dwarf2dbg.h"
 
-/* A "convient" place to put object file dependencies which do
+/* A "convenient" place to put object file dependencies which do
    not need to be seen outside of tc-hppa.c.  */
 
 /* Object file formats specify relocation types.  */
@@ -363,6 +363,9 @@ struct default_subspace_dict
     /* Nonzero if this subspace contains only code.  */
     char code_only;
 
+    /* Nonzero if this is a comdat subspace.  */
+    char comdat;
+
     /* Nonzero if this is a common subspace.  */
     char common;
 
@@ -490,7 +493,7 @@ struct selector_entry
 static void pa_check_current_space_and_subspace PARAMS ((void));
 #endif
 
-#if !(defined (OBJ_ELF) && defined (TE_LINUX))
+#if !(defined (OBJ_ELF) && (defined (TE_LINUX) || defined (TE_NetBSD)))
 static void pa_text PARAMS ((int));
 static void pa_data PARAMS ((int));
 static void pa_comm PARAMS ((int));
@@ -555,13 +558,13 @@ static sd_chain_struct *create_new_space PARAMS ((char *, int, int,
                                                  asection *, int));
 static ssd_chain_struct *create_new_subspace PARAMS ((sd_chain_struct *,
                                                      char *, int, int,
-                                                     int, int, int,
+                                                     int, int, int, int,
                                                      int, int, int, int,
                                                      int, asection *));
 static ssd_chain_struct *update_subspace PARAMS ((sd_chain_struct *,
                                                  char *, int, int, int,
                                                  int, int, int, int,
-                                                 int, int, int,
+                                                 int, int, int, int,
                                                  asection *));
 static sd_chain_struct *is_defined_space PARAMS ((char *));
 static ssd_chain_struct *is_defined_subspace PARAMS ((char *));
@@ -596,7 +599,7 @@ static void pa_vtable_entry PARAMS ((int));
 static void pa_vtable_inherit  PARAMS ((int));
 #endif
 
-/* File and gloally scoped variable declarations.  */
+/* File and globally scoped variable declarations.  */
 
 #ifdef OBJ_SOM
 /* Root and final entry in the space chain.  */
@@ -622,6 +625,11 @@ static struct call_desc last_call_desc;
 /* handle of the OPCODE hash table */
 static struct hash_control *op_hash = NULL;
 
+/* These characters can be suffixes of opcode names and they may be
+   followed by meaningful whitespace.  We don't include `,' and `!'
+   as they never appear followed by meaningful whitespace.  */
+const char hppa_symbol_chars[] = "*?=<>";
+
 /* Table of pseudo ops for the PA.  FIXME -- how many of these
    are now redundant with the overall GAS and the object file
    dependent tables?  */
@@ -642,7 +650,7 @@ const pseudo_typeS md_pseudo_table[] =
   {"byte", pa_cons, 1},
   {"call", pa_call, 0},
   {"callinfo", pa_callinfo, 0},
-#if defined (OBJ_ELF) && defined (TE_LINUX)
+#if defined (OBJ_ELF) && (defined (TE_LINUX) || defined (TE_NetBSD))
   {"code", obj_elf_text, 0},
 #else
   {"code", pa_text, 0},
@@ -652,14 +660,14 @@ const pseudo_typeS md_pseudo_table[] =
   {"compiler", pa_compiler, 0},
 #endif
   {"copyright", pa_copyright, 0},
-#if !(defined (OBJ_ELF) && defined (TE_LINUX))
+#if !(defined (OBJ_ELF) && (defined (TE_LINUX) || defined (TE_NetBSD)))
   {"data", pa_data, 0},
 #endif
   {"double", pa_float_cons, 'd'},
   {"dword", pa_cons, 8},
   {"end", pa_end, 0},
   {"end_brtab", pa_brtab, 0},
-#if !(defined (OBJ_ELF) && defined (TE_LINUX))
+#if !(defined (OBJ_ELF) && (defined (TE_LINUX) || defined (TE_NetBSD)))
   {"end_try", pa_try, 0},
 #endif
   {"enter", pa_enter, 0},
@@ -667,9 +675,6 @@ const pseudo_typeS md_pseudo_table[] =
   {"equ", pa_equ, 0},
   {"exit", pa_exit, 0},
   {"export", pa_export, 0},
-#ifdef OBJ_ELF
-  {"file", dwarf2_directive_file, 0 },
-#endif
   {"fill", pa_fill, 0},
   {"float", pa_float_cons, 'f'},
   {"half", pa_cons, 2},
@@ -679,9 +684,6 @@ const pseudo_typeS md_pseudo_table[] =
   {"lcomm", pa_lcomm, 0},
   {"leave", pa_leave, 0},
   {"level", pa_level, 0},
-#ifdef OBJ_ELF
-  {"loc", dwarf2_directive_loc, 0 },
-#endif
   {"long", pa_cons, 4},
   {"lsym", pa_lsym, 0},
 #ifdef OBJ_SOM
@@ -706,7 +708,7 @@ const pseudo_typeS md_pseudo_table[] =
 #ifdef OBJ_SOM
   {"subspa", pa_subspace, 0},
 #endif
-#if !(defined (OBJ_ELF) && defined (TE_LINUX))
+#if !(defined (OBJ_ELF) && (defined (TE_LINUX) || defined (TE_NetBSD)))
   {"text", pa_text, 0},
 #endif
   {"version", pa_version, 0},
@@ -749,7 +751,7 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
 
 static struct pa_it the_insn;
 
-/* Points to the end of an expression just parsed by get_expressoin
+/* Points to the end of an expression just parsed by get_expression
    and friends.  FIXME.  This shouldn't be handled with a file-global
    variable.  */
 static char *expr_end;
@@ -853,6 +855,10 @@ static const struct pd_reg pre_defined_registers[] =
   {"%dp",    27},
   {"%eiem",  15},
   {"%eirr",  23},
+  {"%farg0",  5},
+  {"%farg1",  6},
+  {"%farg2",  7},
+  {"%farg3",  8},
   {"%fr0",    0 + FP_REG_BASE},
   {"%fr0l",   0 + FP_REG_BASE},
   {"%fr0r",   0 + FP_REG_BASE + FP_REG_RSEL},
@@ -949,6 +955,7 @@ static const struct pd_reg pre_defined_registers[] =
   {"%fr9",    9 + FP_REG_BASE},
   {"%fr9l",   9 + FP_REG_BASE},
   {"%fr9r",   9 + FP_REG_BASE + FP_REG_RSEL},
+  {"%fret",   4},
   {"%hta",   25},
   {"%iir",   19},
   {"%ior",   21},
@@ -1014,6 +1021,14 @@ static const struct pd_reg pre_defined_registers[] =
   {"%sr5",    5},
   {"%sr6",    6},
   {"%sr7",    7},
+  {"%t1",    22},
+  {"%t2",    21},
+  {"%t3",    20},
+  {"%t4",    19},
+  {"%tf1",   11},
+  {"%tf2",   10},
+  {"%tf3",    9},
+  {"%tf4",    8},
   {"%tr0",   24},
   {"%tr1",   25},
   {"%tr2",   26},
@@ -1105,12 +1120,12 @@ static const struct selector_entry selector_table[] =
 
 static struct default_subspace_dict pa_def_subspaces[] =
 {
-  {"$CODE$", 1, 1, 1, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, SUBSEG_CODE},
-  {"$DATA$", 1, 1, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, SUBSEG_DATA},
-  {"$LIT$", 1, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, SUBSEG_LIT},
-  {"$MILLICODE$", 1, 1, 0, 0, 0, 0, 8, 0x2c, 0, 8, 0, 0, SUBSEG_MILLI},
-  {"$BSS$", 1, 1, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, SUBSEG_BSS},
-  {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0}
+  {"$CODE$", 1, 1, 1, 0, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, SUBSEG_CODE},
+  {"$DATA$", 1, 1, 0, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, SUBSEG_DATA},
+  {"$LIT$", 1, 1, 0, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, SUBSEG_LIT},
+  {"$MILLICODE$", 1, 1, 0, 0, 0, 0, 0, 8, 0x2c, 0, 8, 0, 0, SUBSEG_MILLI},
+  {"$BSS$", 1, 1, 0, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, SUBSEG_BSS},
+  {NULL, 0, 1, 0, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0}
 };
 
 static struct default_space_dict pa_def_spaces[] =
@@ -1146,7 +1161,7 @@ static struct default_space_dict pa_def_spaces[] =
     continue; \
   }
 
-/* Simple range checking for FIELD againt HIGH and LOW bounds.
+/* Simple range checking for FIELD against HIGH and LOW bounds.
    IGNORE is used to suppress the error message.  */
 
 #define CHECK_FIELD(FIELD, HIGH, LOW, IGNORE) \
@@ -1174,7 +1189,7 @@ static struct default_space_dict pa_def_spaces[] =
       } \
   }
 
-/* Simple alignment checking for FIELD againt ALIGN (a power of two).
+/* Simple alignment checking for FIELD against ALIGN (a power of two).
    IGNORE is used to suppress the error message.  */
 
 #define CHECK_ALIGN(FIELD, ALIGN, IGNORE) \
@@ -1289,10 +1304,10 @@ pa_undefine_label ()
     {
       if (1
 #ifdef OBJ_SOM
-         && current_space == label_chain->lss_space && label_chain->lss_label
+         && current_space == label_chain->lss_space && label_chain->lss_label
 #endif
 #ifdef OBJ_ELF
-         && now_seg == label_chain->lss_segment && label_chain->lss_label
+         && now_seg == label_chain->lss_segment && label_chain->lss_label
 #endif
          )
        {
@@ -1387,6 +1402,8 @@ cons_fix_new_hppa (frag, where, size, exp)
   /* Get a base relocation type.  */
   if (is_DP_relative (*exp))
     rel_type = R_HPPA_GOTOFF;
+  else if (is_PC_relative (*exp))
+    rel_type = R_HPPA_PCREL_CALL;
   else if (is_complex (*exp))
     rel_type = R_HPPA_COMPLEX;
   else
@@ -1531,7 +1548,7 @@ md_assemble (str)
   /* Assemble the instruction.  Results are saved into "the_insn".  */
   pa_ip (str);
 
-  /* Get somewhere to put the assembled instrution.  */
+  /* Get somewhere to put the assembled instruction.  */
   to = frag_more (4);
 
   /* Output the opcode.  */
@@ -1627,7 +1644,7 @@ pa_ip (str)
       /* If this instruction is specific to a particular architecture,
         then set a new architecture.  */
       /* But do not automatically promote to pa2.0.  The automatic promotion
-        crud is for compatability with HP's old assemblers only.  */
+        crud is for compatibility with HP's old assemblers only.  */
       if (insn->arch < 20
          && bfd_get_mach (stdoutput) < insn->arch)
        {
@@ -2334,16 +2351,16 @@ pa_ip (str)
                args++;
                switch (*args)
                  {
-                 /* Handle FP compare conditions.  */
-                 case 'f':
-                   cond = pa_parse_fp_cmp_cond (&s);
-                   INSERT_FIELD_AND_CONTINUE (opcode, cond, 0);
+                 /* Handle FP compare conditions.  */
+                 case 'f':
+                   cond = pa_parse_fp_cmp_cond (&s);
+                   INSERT_FIELD_AND_CONTINUE (opcode, cond, 0);
 
                  /* Handle an add condition.  */
                  case 'A':
                  case 'a':
-                   cmpltr = 0;
-                   flag = 0;
+                   cmpltr = 0;
+                   flag = 0;
                    if (*s == ',')
                      {
                        s++;
@@ -2358,7 +2375,6 @@ pa_ip (str)
                          }
                        else if (*s == '*')
                          break;
-                       name = s;
 
                        name = s;
                        while (*s != ',' && *s != ' ' && *s != '\t')
@@ -2420,7 +2436,7 @@ pa_ip (str)
                            flag = 1;
                          }
                        /* ",*" is a valid condition.  */
-                       else if (*args == 'a')
+                       else if (*args == 'a' || *name)
                          as_bad (_("Invalid Add Condition: %s"), name);
                        *s = c;
                      }
@@ -2526,7 +2542,6 @@ pa_ip (str)
                          }
                        else if (*s == '*')
                          break;
-                       name = s;
 
                        name = s;
                        while (*s != ',' && *s != ' ' && *s != '\t')
@@ -2588,7 +2603,7 @@ pa_ip (str)
                            flag = 1;
                          }
                        /* ",*" is a valid condition.  */
-                       else if (*args != 'S')
+                       else if (*args != 'S' || *name)
                          as_bad (_("Invalid Compare/Subtract Condition: %s"),
                                  name);
                        *s = c;
@@ -2711,7 +2726,7 @@ pa_ip (str)
                            flag = 1;
                          }
                        /* ",*" is a valid condition.  */
-                       else if (*args != 'L')
+                       else if (*args != 'L' || *name)
                          as_bad (_("Invalid Logical Instruction Condition."));
                        *s = c;
                      }
@@ -2766,7 +2781,7 @@ pa_ip (str)
                            continue;
                          }
                        /* ",*" is a valid condition.  */
-                       else if (*args != 'X')
+                       else if (*args != 'X' || *name)
                          as_bad (_("Invalid Shift/Extract/Deposit Condition."));
                        *s = c;
                      }
@@ -2878,7 +2893,7 @@ pa_ip (str)
                            s += 3;
                          }
                        /* ",*" is a valid condition.  */
-                       else if (*args != 'U')
+                       else if (*args != 'U' || (*s != ' ' && *s != '\t'))
                          as_bad (_("Invalid Unit Instruction Condition."));
                      }
                    opcode |= cmpltr << 13;
@@ -3251,7 +3266,7 @@ pa_ip (str)
              the_insn.pcrel = 1;
              if (!the_insn.exp.X_add_symbol
                  || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
-                             "L$0\001"))
+                             FAKE_LABEL_NAME))
                {
                  num = evaluate_absolute (&the_insn);
                  if (num % 4)
@@ -3283,7 +3298,7 @@ pa_ip (str)
              the_insn.pcrel = 1;
              if (!the_insn.exp.X_add_symbol
                  || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
-                             "L$0\001"))
+                             FAKE_LABEL_NAME))
                {
                  num = evaluate_absolute (&the_insn);
                  if (num % 4)
@@ -3314,7 +3329,7 @@ pa_ip (str)
              the_insn.pcrel = 1;
              if (!the_insn.exp.X_add_symbol
                  || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
-                             "L$0\001"))
+                             FAKE_LABEL_NAME))
                {
                  num = evaluate_absolute (&the_insn);
                  if (num % 4)
@@ -3344,7 +3359,7 @@ pa_ip (str)
              the_insn.pcrel = 0;
              if (!the_insn.exp.X_add_symbol
                  || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
-                             "L$0\001"))
+                             FAKE_LABEL_NAME))
                {
                  num = evaluate_absolute (&the_insn);
                  if (num % 4)
@@ -3949,7 +3964,7 @@ pa_ip (str)
 
  failed:
       /* Check if the args matched.  */
-      if (match == FALSE)
+      if (!match)
        {
          if (&insn[1] - pa_opcodes < (int) NUMOPCODES
              && !strcmp (insn->name, insn[1].name))
@@ -4240,8 +4255,8 @@ tc_gen_reloc (section, fixp)
        case R_N0SEL:
        case R_N1SEL:
          /* There is no symbol or addend associated with these fixups.  */
-          relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
-          *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol);
+         relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+         *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol);
          relocs[i]->addend = 0;
          break;
 
@@ -4249,8 +4264,8 @@ tc_gen_reloc (section, fixp)
        case R_ENTRY:
        case R_EXIT:
          /* There is no symbol associated with these fixups.  */
-          relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
-          *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol);
+         relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+         *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol);
          relocs[i]->addend = fixp->fx_offset;
          break;
 
@@ -4419,9 +4434,6 @@ md_apply_fix3 (fixP, valP, seg)
   offsetT new_val;
   int insn, val, fmt;
 
-  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
-    fixP->fx_done = 1;
-
   /* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can
      never be "applied" (they are just markers).  Likewise for
      R_HPPA_BEGIN_BRTAB and R_HPPA_END_BRTAB.  */
@@ -4448,6 +4460,9 @@ md_apply_fix3 (fixP, valP, seg)
     return;
 #endif
 
+  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+    fixP->fx_done = 1;
+
   /* There should have been an HPPA specific fixup associated
      with the GAS fixup.  */
   hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data;
@@ -4459,7 +4474,7 @@ md_apply_fix3 (fixP, valP, seg)
       return;
     }
 
-  buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+  buf = (unsigned char *) (fixP->fx_frag->fr_literal + fixP->fx_where);
   insn = bfd_get_32 (stdoutput, buf);
   fmt = bfd_hppa_insn2fmt (stdoutput, insn);
 
@@ -4483,13 +4498,6 @@ md_apply_fix3 (fixP, valP, seg)
           || hppa_fixP->fx_r_field == e_rtsel
           || hppa_fixP->fx_r_field == e_ltsel)
     new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
-  /* This is truly disgusting.  The machine independent code blindly
-     adds in the value of the symbol being relocated against.  Damn!  */
-  else if (fmt == 32
-          && fixP->fx_addsy != NULL
-          && S_GET_SEGMENT (fixP->fx_addsy) != bfd_com_section_ptr)
-    new_val = hppa_field_adjust (* valP - S_GET_VALUE (fixP->fx_addsy),
-                                0, hppa_fixP->fx_r_field);
 #endif
   else
     new_val = hppa_field_adjust (* valP, 0, hppa_fixP->fx_r_field);
@@ -4687,7 +4695,7 @@ pa_parse_number (s, is_float)
   symbolS *sym;
   int status;
   char *p = *s;
-  boolean have_prefix;
+  bfd_boolean have_prefix;
 
   /* Skip whitespace before the number.  */
   while (*p == ' ' || *p == '\t')
@@ -4826,7 +4834,7 @@ pa_parse_number (s, is_float)
              num = S_GET_VALUE (sym);
              /* Well, we don't really have one, but we do have a
                 register, so...  */
-             have_prefix = true;
+             have_prefix = TRUE;
            }
          else if (S_GET_SEGMENT (sym) == &bfd_abs_section)
            num = S_GET_VALUE (sym);
@@ -4842,7 +4850,7 @@ pa_parse_number (s, is_float)
          /* There is where we'd come for an undefined symbol
             or for an empty string.  For an empty string we
             will return zero.  That's a concession made for
-            compatability with the braindamaged HP assemblers.  */
+            compatibility with the braindamaged HP assemblers.  */
          if (*name == 0)
            num = 0;
          else
@@ -5213,11 +5221,11 @@ pa_get_absolute_expression (insn, strp)
   expression (&insn->exp);
   /* This is not perfect, but is a huge improvement over doing nothing.
 
-     The PA assembly syntax is ambigious in a variety of ways.  Consider
+     The PA assembly syntax is ambiguous in a variety of ways.  Consider
      this string "4 %r5"  Is that the number 4 followed by the register
      r5, or is that 4 MOD r5?
 
-     If we get a modulo expresion When looking for an absolute, we try
+     If we get a modulo expression when looking for an absolute, we try
      again cutting off the input string at the first whitespace character.  */
   if (insn->exp.X_op == O_modulus)
     {
@@ -5227,7 +5235,7 @@ pa_get_absolute_expression (insn, strp)
       input_line_pointer = *strp;
       s = *strp;
       while (*s != ',' && *s != ' ' && *s != '\t')
-        s++;
+       s++;
 
       c = *s;
       *s = 0;
@@ -5355,7 +5363,7 @@ pa_parse_nullif (s)
 }
 
 /* Parse a non-negated compare/subtract completer returning the
-   number (for encoding in instrutions) of the given completer.  */
+   number (for encoding in instructions) of the given completer.  */
 
 static int
 pa_parse_nonneg_cmpsub_cmpltr (s)
@@ -5426,7 +5434,7 @@ pa_parse_nonneg_cmpsub_cmpltr (s)
 }
 
 /* Parse a negated compare/subtract completer returning the
-   number (for encoding in instrutions) of the given completer.  */
+   number (for encoding in instructions) of the given completer.  */
 
 static int
 pa_parse_neg_cmpsub_cmpltr (s)
@@ -5501,7 +5509,7 @@ pa_parse_neg_cmpsub_cmpltr (s)
 }
 
 /* Parse a 64 bit compare and branch completer returning the number (for
-   encoding in instrutions) of the given completer.
+   encoding in instructions) of the given completer.
 
    Nonnegated comparisons are returned as 0-7, negated comparisons are
    returned as 8-15.  */
@@ -5598,7 +5606,7 @@ pa_parse_cmpb_64_cmpltr (s)
 }
 
 /* Parse a 64 bit compare immediate and branch completer returning the number
-   (for encoding in instrutions) of the given completer.  */
+   (for encoding in instructions) of the given completer.  */
 
 static int
 pa_parse_cmpib_64_cmpltr (s)
@@ -5660,7 +5668,7 @@ pa_parse_cmpib_64_cmpltr (s)
 }
 
 /* Parse a non-negated addition completer returning the number
-   (for encoding in instrutions) of the given completer.  */
+   (for encoding in instructions) of the given completer.  */
 
 static int
 pa_parse_nonneg_add_cmpltr (s)
@@ -5730,7 +5738,7 @@ pa_parse_nonneg_add_cmpltr (s)
 }
 
 /* Parse a negated addition completer returning the number
-   (for encoding in instrutions) of the given completer.  */
+   (for encoding in instructions) of the given completer.  */
 
 static int
 pa_parse_neg_add_cmpltr (s)
@@ -5804,7 +5812,7 @@ pa_parse_neg_add_cmpltr (s)
 }
 
 /* Parse a 64 bit wide mode add and branch completer returning the number (for
-   encoding in instrutions) of the given completer.  */
+   encoding in instructions) of the given completer.  */
 
 static int
 pa_parse_addb_64_cmpltr (s)
@@ -5971,7 +5979,7 @@ pa_brtab (begin)
 {
 
 #ifdef OBJ_SOM
-  /* The BRTAB relocations are only availble in SOM (to denote
+  /* The BRTAB relocations are only available in SOM (to denote
      the beginning and end of branch tables).  */
   char *where = frag_more (0);
 
@@ -5997,7 +6005,7 @@ pa_try (begin)
   if (! begin)
     expression (&exp);
 
-  /* The TRY relocations are only availble in SOM (to denote
+  /* The TRY relocations are only available in SOM (to denote
      the beginning and end of exception handling regions).  */
 
   fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
@@ -6314,7 +6322,7 @@ pa_callinfo (unused)
   demand_empty_rest_of_line ();
 }
 
-#if !(defined (OBJ_ELF) && defined (TE_LINUX))
+#if !(defined (OBJ_ELF) && (defined (TE_LINUX) || defined (TE_NetBSD)))
 /* Switch to the text space.  Like s_text, but delete our
    label when finished.  */
 static void
@@ -6383,6 +6391,7 @@ pa_comm (unused)
 
   if (symbol)
     {
+      symbol_get_bfdsym (symbol)->flags |= BSF_OBJECT;
       S_SET_VALUE (symbol, size);
       S_SET_SEGMENT (symbol, bfd_und_section_ptr);
       S_SET_EXTERNAL (symbol);
@@ -6394,7 +6403,7 @@ pa_comm (unused)
     }
   demand_empty_rest_of_line ();
 }
-#endif /* !(defined (OBJ_ELF) && defined (TE_LINUX)) */
+#endif /* !(defined (OBJ_ELF) && (defined (TE_LINUX) || defined (TE_NetBSD))) */
 
 /* Process a .END pseudo-op.  */
 
@@ -6420,7 +6429,7 @@ pa_enter (unused)
 }
 
 /* Process a .ENTRY pseudo-op.  .ENTRY marks the beginning of the
-   procesure.  */
+   procedure.  */
 static void
 pa_entry (unused)
      int unused ATTRIBUTE_UNUSED;
@@ -6778,7 +6787,7 @@ pa_type_args (symbolP, is_export)
 #endif
          *input_line_pointer = c;
        }
-      /* Privelege level.  */
+      /* Privilege level.  */
       else if ((strncasecmp (name, "priv_lev", 8)) == 0)
        {
          p = input_line_pointer;
@@ -6833,7 +6842,7 @@ pa_import (unused)
        }
       else
        {
-         /* Sigh.  To be compatable with the HP assembler and to help
+         /* Sigh.  To be compatible with the HP assembler and to help
             poorly written assembly code, we assign a type based on
             the current segment.  Note only BSF_FUNCTION really
             matters, we do not need to set the full SYMBOL_TYPE_* info.  */
@@ -7062,7 +7071,7 @@ pa_proc (unused)
   demand_empty_rest_of_line ();
 }
 
-/* Process the syntatical end of a procedure.  Make sure all the
+/* Process the syntactical end of a procedure.  Make sure all the
    appropriate pseudo-ops were found within the procedure.  */
 
 static void
@@ -7271,7 +7280,7 @@ pa_parse_space_stmt (space_name, create_flag)
   /* If create_flag is nonzero, then create the new space with
      the attributes computed above.  Else set the values in
      an already existing space -- this can only happen for
-     the first occurence of a built-in space.  */
+     the first occurrence of a built-in space.  */
   if (create_flag)
     space = create_new_space (space_name, spnum, loadable, defined,
                              private, sort, seg, 1);
@@ -7448,7 +7457,7 @@ pa_subspace (create_new)
      int create_new;
 {
   char *name, *ss_name, c;
-  char loadable, code_only, common, dup_common, zero, sort;
+  char loadable, code_only, comdat, common, dup_common, zero, sort;
   int i, access, space_index, alignment, quadrant, applicable, flags;
   sd_chain_struct *space;
   ssd_chain_struct *ssd;
@@ -7474,6 +7483,7 @@ pa_subspace (create_new)
       sort = 0;
       access = 0x7f;
       loadable = 1;
+      comdat = 0;
       common = 0;
       dup_common = 0;
       code_only = 0;
@@ -7508,6 +7518,7 @@ pa_subspace (create_new)
              if (strcasecmp (pa_def_subspaces[i].name, ss_name) == 0)
                {
                  loadable = pa_def_subspaces[i].loadable;
+                 comdat = pa_def_subspaces[i].comdat;
                  common = pa_def_subspaces[i].common;
                  dup_common = pa_def_subspaces[i].dup_common;
                  code_only = pa_def_subspaces[i].code_only;
@@ -7571,6 +7582,11 @@ pa_subspace (create_new)
                  *input_line_pointer = c;
                  loadable = 0;
                }
+             else if ((strncasecmp (name, "comdat", 6) == 0))
+               {
+                 *input_line_pointer = c;
+                 comdat = 1;
+               }
              else if ((strncasecmp (name, "common", 6) == 0))
                {
                  *input_line_pointer = c;
@@ -7603,8 +7619,17 @@ pa_subspace (create_new)
        flags |= (SEC_ALLOC | SEC_LOAD);
       if (code_only)
        flags |= SEC_CODE;
-      if (common || dup_common)
-       flags |= SEC_IS_COMMON;
+
+      /* These flags are used to implement various flavors of initialized
+        common.  The SOM linker discards duplicate subspaces when they
+        have the same "key" symbol name.  This support is more like
+        GNU linkonce than BFD common.  Further, pc-relative relocations
+        are converted to section relative relocations in BFD common
+        sections.  This complicates the handling of relocations in
+        common sections containing text and isn't currently supported
+        correctly in the SOM BFD backend.  */
+      if (comdat || common || dup_common)
+       flags |= SEC_LINK_ONCE;
 
       flags |= SEC_RELOC | SEC_HAS_CONTENTS;
 
@@ -7646,16 +7671,16 @@ pa_subspace (create_new)
       if (ssd)
 
        current_subspace = update_subspace (space, ss_name, loadable,
-                                           code_only, common, dup_common,
-                                           sort, zero, access, space_index,
-                                           alignment, quadrant,
+                                           code_only, comdat, common,
+                                           dup_common, sort, zero, access,
+                                           space_index, alignment, quadrant,
                                            section);
       else
        current_subspace = create_new_subspace (space, ss_name, loadable,
-                                               code_only, common,
+                                               code_only, comdat, common,
                                                dup_common, zero, sort,
                                                access, space_index,
-                                             alignment, quadrant, section);
+                                               alignment, quadrant, section);
 
       demand_empty_rest_of_line ();
       current_subspace->ssd_seg = section;
@@ -7776,6 +7801,7 @@ pa_spaces_begin ()
       create_new_subspace (space, name,
                           pa_def_subspaces[i].loadable,
                           pa_def_subspaces[i].code_only,
+                          pa_def_subspaces[i].comdat,
                           pa_def_subspaces[i].common,
                           pa_def_subspaces[i].dup_common,
                           pa_def_subspaces[i].zero,
@@ -7877,12 +7903,12 @@ create_new_space (name, spnum, loadable, defined, private,
    order as defined by the SORT entries.  */
 
 static ssd_chain_struct *
-create_new_subspace (space, name, loadable, code_only, common,
+create_new_subspace (space, name, loadable, code_only, comdat, common,
                     dup_common, is_zero, sort, access, space_index,
                     alignment, quadrant, seg)
      sd_chain_struct *space;
      char *name;
-     int loadable, code_only, common, dup_common, is_zero;
+     int loadable, code_only, comdat, common, dup_common, is_zero;
      int sort;
      int access;
      int space_index;
@@ -7939,8 +7965,8 @@ create_new_subspace (space, name, loadable, code_only, common,
     }
 
 #ifdef obj_set_subsection_attributes
-  obj_set_subsection_attributes (seg, space->sd_seg, access,
-                                sort, quadrant);
+  obj_set_subsection_attributes (seg, space->sd_seg, access, sort,
+                                quadrant, comdat, common, dup_common);
 #endif
 
   return chain_entry;
@@ -7950,12 +7976,13 @@ create_new_subspace (space, name, loadable, code_only, common,
    various arguments.   Return the modified subspace chain entry.  */
 
 static ssd_chain_struct *
-update_subspace (space, name, loadable, code_only, common, dup_common, sort,
-                zero, access, space_index, alignment, quadrant, section)
+update_subspace (space, name, loadable, code_only, comdat, common, dup_common,
+                sort, zero, access, space_index, alignment, quadrant, section)
      sd_chain_struct *space;
      char *name;
      int loadable;
      int code_only;
+     int comdat;
      int common;
      int dup_common;
      int zero;
@@ -7971,8 +7998,8 @@ update_subspace (space, name, loadable, code_only, common, dup_common, sort,
   chain_entry = is_defined_subspace (name);
 
 #ifdef obj_set_subsection_attributes
-  obj_set_subsection_attributes (section, space->sd_seg, access,
-                                sort, quadrant);
+  obj_set_subsection_attributes (section, space->sd_seg, access, sort,
+                                quadrant, comdat, common, dup_common);
 #endif
 
   return chain_entry;
@@ -8398,13 +8425,8 @@ hppa_fix_adjustable (fixp)
     {
     /* Relocation types which use e_lrsel.  */
     case R_PARISC_DIR21L:
-    case R_PARISC_DLTIND21L:
     case R_PARISC_DLTREL21L:
     case R_PARISC_DPREL21L:
-    case R_PARISC_LTOFF_FPTR21L:
-    case R_PARISC_LTOFF_TP21L:
-    case R_PARISC_PCREL21L:
-    case R_PARISC_PLABEL21L:
     case R_PARISC_PLTOFF21L:
 
     /* Relocation types which use e_rrsel.  */
@@ -8412,24 +8434,15 @@ hppa_fix_adjustable (fixp)
     case R_PARISC_DIR14DR:
     case R_PARISC_DIR14WR:
     case R_PARISC_DIR17R:
-    case R_PARISC_DLTIND14R:
-    case R_PARISC_DLTIND14DR:
-    case R_PARISC_DLTIND14WR:
     case R_PARISC_DLTREL14R:
     case R_PARISC_DLTREL14DR:
     case R_PARISC_DLTREL14WR:
     case R_PARISC_DPREL14R:
     case R_PARISC_DPREL14DR:
     case R_PARISC_DPREL14WR:
-    case R_PARISC_PCREL14R:
-    case R_PARISC_PCREL17R:
-    case R_PARISC_PLABEL14R:
-    case R_PARISC_LTOFF_FPTR14R:
-    case R_PARISC_LTOFF_FPTR14DR:
-    case R_PARISC_LTOFF_FPTR14WR:
-    case R_PARISC_LTOFF_TP14R:
-    case R_PARISC_LTOFF_TP14DR:
-    case R_PARISC_LTOFF_TP14WR:
+    case R_PARISC_PLTOFF14R:
+    case R_PARISC_PLTOFF14DR:
+    case R_PARISC_PLTOFF14WR:
 
     /* Other types that we reject for reduction.  */
     case R_PARISC_GNU_VTENTRY:
@@ -8440,10 +8453,6 @@ hppa_fix_adjustable (fixp)
     }
 #endif
 
-  if (fixp->fx_addsy && (S_IS_EXTERNAL (fixp->fx_addsy)
-                        || S_IS_WEAK (fixp->fx_addsy)))
-    return 0;
-
   /* Reject reductions of symbols in sym1-sym2 expressions when
      the fixup will occur in a CODE subspace.
 
@@ -8453,11 +8462,7 @@ hppa_fix_adjustable (fixp)
   if (fixp->fx_addsy
       && fixp->fx_subsy
       && (hppa_fix->segment->flags & SEC_CODE))
-    {
-      /* Apparently sy_used_in_reloc never gets set for sub symbols.  */
-      symbol_mark_used_in_reloc (fixp->fx_subsy);
-      return 0;
-    }
+    return 0;
 
   /* We can't adjust any relocs that use LR% and RR% field selectors.
 
@@ -8481,7 +8486,7 @@ hppa_fix_adjustable (fixp)
      .                 RR%sect+4092 == (R%sect)+4092
      .                 RR%sect+4096 == (R%sect)-4096
      and the last address loses because rounding the addend to 8k
-     mutiples takes us up to 8192 with an offset of -4096.
+     multiples takes us up to 8192 with an offset of -4096.
 
      In cases where the LR% expression is identical to the RR% one we
      will never have a problem, but is so happens that gcc rounds
@@ -8547,7 +8552,7 @@ hppa_force_relocation (fixp)
 
   /* Ensure we emit a relocation for global symbols so that dynamic
      linking works.  */
-  if (S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy))
+  if (S_FORCE_RELOC (fixp->fx_addsy, 1))
     return 1;
 
   /* It is necessary to force PC-relative calls/jumps to have a relocation
@@ -8561,15 +8566,27 @@ hppa_force_relocation (fixp)
   /* Now check to see if we're going to need a long-branch stub.  */
   if (fixp->fx_r_type == (int) R_HPPA_PCREL_CALL)
     {
-      valueT distance;
+      long pc = md_pcrel_from (fixp);
+      valueT distance, min_stub_distance;
 
-      distance = (fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy)
-                 - md_pcrel_from (fixp) - 8);
-      if (distance + 8388608 >= 16777216
-         || (hppa_fixp->fx_r_format == 17 && distance + 262144 >= 524288)
-#ifdef OBJ_ELF
-         || (hppa_fixp->fx_r_format == 12 && distance + 8192 >= 16384)
+      distance = fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy) - pc - 8;
+
+      /* Distance to the closest possible stub.  This will detect most
+        but not all circumstances where a stub will not work.  */
+      min_stub_distance = pc + 16;
+#ifdef OBJ_SOM
+      if (last_call_info != NULL)
+       min_stub_distance -= S_GET_VALUE (last_call_info->start_symbol);
 #endif
+
+      if ((distance + 8388608 >= 16777216
+          && min_stub_distance <= 8388608)
+         || (hppa_fixp->fx_r_format == 17
+             && distance + 262144 >= 524288
+             && min_stub_distance <= 262144)
+         || (hppa_fixp->fx_r_format == 12
+             && distance + 8192 >= 16384
+             && min_stub_distance <= 8192)
          )
        return 1;
     }
@@ -8584,7 +8601,7 @@ hppa_force_relocation (fixp)
 /* Now for some ELF specific code.  FIXME.  */
 #ifdef OBJ_ELF
 /* Mark the end of a function so that it's possible to compute
-   the size of the function in hppa_elf_final_processing.  */
+   the size of the function in elf_hppa_final_processing.  */
 
 static void
 hppa_elf_mark_end_of_function ()
This page took 0.056332 seconds and 4 git commands to generate.