* som.c (som_hppa_howto_table): Add missing R_END_TRY. Delete
authorJeff Law <law@redhat.com>
Mon, 6 Dec 1993 03:33:06 +0000 (03:33 +0000)
committerJeff Law <law@redhat.com>
Mon, 6 Dec 1993 03:33:06 +0000 (03:33 +0000)
        extra R_DATA_OVERRIDE.
        (hppa_som_gen_reloc_type): Generate a relocation for the rounding
        mode selector if needed.
        (som_write_fixups): Handle requests for a change in the default
        rounding mode.  Rounding modes do not consume input bytes, but
        are just markers much like R_ENTRY and R_EXIT.

bfd/ChangeLog
bfd/som.c

index f51e257871c1ec81835feaebf5d8e97bc032c55d..77f5c87fd0059a0a95d447397cd9749f517597f3 100644 (file)
@@ -1,7 +1,31 @@
+Sun Dec  5 19:32:08 1993  Jeffrey A. Law  (law@snake.cs.utah.edu)
+
+       * som.c (som_hppa_howto_table): Add missing R_END_TRY.  Delete 
+       extra R_DATA_OVERRIDE.
+       (hppa_som_gen_reloc_type): Generate a relocation for the rounding
+       mode selector if needed.
+       (som_write_fixups): Handle requests for a change in the default
+       rounding mode.  Rounding modes do not consume input bytes, but
+       are just markers much like R_ENTRY and R_EXIT.
+
 Sat Dec  4 19:40:32 1993  Jeffrey A. Law  (law@snake.cs.utah.edu)
 
        Fri Dec  3 09:55:17 1993  Pete Hoogenboom  (hoogen@cs.utah.edu)
 
+       * elf32-hppa.c: (hppa_elf_reloc):  Do not do code reordering when
+       the branch instruction as originally been nullified.
+       hppa_elf_reloc):  Avoid useless call to bfd_put_32 () in the
+       case of no code reordering due to an LDO instruction in the
+       delay slot of the branch.  Make sure to relocate the correct
+       instruction.  Do not perform instruction reordering for millicode
+       calls.
+       (hppa_elf_build_arg_reloc_stub):  Change the relocation type
+       to R_HPPA_STUB_CALL_17 when special processing might be needed.
+       (hppa_elf_build_long_branch_stub): Prevent code reordering on
+       a call from a linker stub to another linker stub and for millicode
+       calls.  Do not trash the return register for calls from one linker
+       stub to a second linker stub.
+
        * elf32-hppa.c: (elf_hppa_howto_table):  PLABEL and DLT
        relocations are not pc-relative.
 
index 4c36fe720d9d18193e04806247e609669a909636..e4b696058a8cff8650894df0a725fbd59250a022 100644 (file)
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -102,6 +102,12 @@ typedef enum
   SYMBOL_TYPE_SEC_PROG,
 } pa_symbol_type;
 
+struct section_to_type
+{
+  char *section;
+  char type;
+};
+
 /* Forward declarations */
 
 static boolean som_mkobject PARAMS ((bfd *));
@@ -182,6 +188,37 @@ static boolean som_write_symbol_strings PARAMS ((bfd *, unsigned long,
 static boolean som_begin_writing PARAMS ((bfd *));
 static const reloc_howto_type * som_bfd_reloc_type_lookup
        PARAMS ((bfd_arch_info_type *, bfd_reloc_code_real_type));
+static char som_section_type PARAMS ((const char *));
+static int som_decode_symclass PARAMS ((asymbol *));
+
+
+/* Map SOM section names to POSIX/BSD single-character symbol types.
+
+   This table includes all the standard subspaces as defined in the 
+   current "PRO ABI for PA-RISC Systems", $UNWIND$ which for 
+   some reason was left out, and sections specific to embedded stabs.  */
+
+static const struct section_to_type stt[] = {
+  {"$TEXT$", 't'},
+  {"$SHLIB_INFO$", 't'},
+  {"$MILLICODE$", 't'},
+  {"$LIT$", 't'},
+  {"$CODE$", 't'},
+  {"$UNWIND_START$", 't'},
+  {"$UNWIND$", 't'},
+  {"$PRIVATE$", 'd'},
+  {"$PLT$", 'd'},
+  {"$SHLIB_DATA$", 'd'},
+  {"$DATA$", 'd'},
+  {"$SHORTDATA$", 'g'},
+  {"$DLT$", 'd'},
+  {"$GLOBAL$", 'g'},
+  {"$SHORTBSS$", 's'},
+  {"$BSS$", 'b'},
+  {"$GDB_STRINGS$", 'N'},
+  {"$GDB_SYMBOLS$", 'N'},
+  {0, 0}
+};
 
 /* About the relocation formatting table...
 
@@ -803,6 +840,7 @@ static reloc_howto_type som_hppa_howto_table[] =
   {R_BEGIN_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BEGIN_TRY"},
   {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
   {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
+  {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
   {R_BEGIN_BRTAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BEGIN_BRTAB"},
   {R_END_BRTAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_BRTAB"},
   {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
@@ -822,7 +860,6 @@ static reloc_howto_type som_hppa_howto_table[] =
   {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
   {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
   {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
-  {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
   {R_TRANSLATED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_TRANSLATED"},
   {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
   {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
@@ -1290,20 +1327,70 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field)
      bfd *abfd;
      int base_type;
      int format;
-     int field;
+     enum hppa_reloc_field_selector_type field;
 {
   int *final_type, **final_types;
 
-  final_types = (int **) bfd_alloc_by_size_t (abfd, sizeof (int *) * 2);
+  final_types = (int **) bfd_alloc_by_size_t (abfd, sizeof (int *) * 3);
   final_type = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
 
+  /* The field selector may require additional relocations to be 
+     generated.  It's impossible to know at this moment if additional
+     relocations will be needed, so we make them.  The code to actually
+     write the relocation/fixup stream is responsible for removing
+     any redundant relocations.  */
+  switch (field)
+    {
+      case e_fsel:
+      case e_psel:
+      case e_lpsel:
+      case e_rpsel:
+      case e_tsel:
+      case e_ltsel:
+      case e_rtsel:
+       final_types[0] = final_type;
+       final_types[1] = NULL;
+       final_types[2] = NULL;
+       *final_type = base_type;
+       break;
+
+      case e_lssel:
+      case e_rssel:
+       final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
+       *final_types[0] = R_S_MODE;
+       final_types[1] = final_type;
+       final_types[2] = NULL;
+       *final_type = base_type;
+       break;
 
-  final_types[0] = final_type;
-  final_types[1] = NULL;
+      case e_lsel:
+      case e_rsel:
+       final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
+       *final_types[0] = R_N_MODE;
+       final_types[1] = final_type;
+       final_types[2] = NULL;
+       *final_type = base_type;
+       break;
 
-  /* Default to the basic relocation passed in.  */
-  *final_type = base_type;
+      case e_ldsel:
+      case e_rdsel:
+       final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
+       *final_types[0] = R_D_MODE;
+       final_types[1] = final_type;
+       final_types[2] = NULL;
+       *final_type = base_type;
+       break;
 
+      case e_lrsel:
+      case e_rrsel:
+       final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
+       *final_types[0] = R_R_MODE;
+       final_types[1] = final_type;
+       final_types[2] = NULL;
+       *final_type = base_type;
+       break;
+    }
+  
   switch (base_type)
     {
     case R_HPPA:
@@ -1649,6 +1736,9 @@ som_object_p (abfd)
 #endif
 #ifdef EXECLIBMAGIC
     case EXECLIBMAGIC:
+#endif
+#ifdef SHARED_MAGIC_CNX
+    case SHARED_MAGIC_CNX:
 #endif
       break;
     default:
@@ -2002,7 +2092,7 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
           subsection != NULL;
           subsection = subsection->next)
        {
-         int reloc_offset;
+         int reloc_offset, current_rounding_mode;
 
          /* Find a subspace of this space.  */
          if (som_section_data (subsection)->is_subspace == 0
@@ -2039,6 +2129,7 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
          subspace_reloc_size = 0;
          reloc_offset = 0;
          som_initialize_reloc_queue (reloc_queue);
+         current_rounding_mode = R_N_MODE;
 
          /* Translate each BFD relocation into one or more SOM 
             relocations.  */
@@ -2082,14 +2173,26 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
 
              /* Update reloc_offset for the next iteration.
 
-                Note R_ENTRY and R_EXIT relocations are just markers,
-                they do not consume input bytes.  */ 
-             if (bfd_reloc->howto->type != R_ENTRY
-                 && bfd_reloc->howto->type != R_EXIT)
-               reloc_offset = bfd_reloc->address + 4;
-             else
-               reloc_offset = bfd_reloc->address;
+                Many relocations do not consume input bytes.  They
+                are markers, or set state necessary to perform some
+                later relocation.  */
+             switch (bfd_reloc->howto->type)
+               {
+               /* This only needs to handle relocations that may be
+                  made by hppa_som_gen_reloc.  */
+               case R_ENTRY:
+               case R_EXIT:
+               case R_N_MODE:
+               case R_S_MODE:
+               case R_D_MODE:
+               case R_R_MODE:
+                 reloc_offset = bfd_reloc->address;
+                 break;
 
+               default:
+                 reloc_offset = bfd_reloc->address + 4;
+                 break;
+               }
 
              /* Now the actual relocation we care about.  */
              switch (bfd_reloc->howto->type)
@@ -2177,6 +2280,21 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
                  p += 1;
                  break;
 
+               case R_N_MODE:
+               case R_S_MODE:
+               case R_D_MODE:
+               case R_R_MODE:
+                 /* If this relocation requests the current rounding
+                    mode, then it is redundant.  */
+                 if (bfd_reloc->howto->type != current_rounding_mode)
+                   {
+                     bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+                     subspace_reloc_size += 1;
+                     p += 1;
+                     current_rounding_mode = bfd_reloc->howto->type;
+                   }
+                 break;
+
                /* Put a "R_RESERVED" relocation in the stream if
                   we hit something we do not understand.  The linker
                   will complain loudly if this ever happens.  */
@@ -2184,6 +2302,7 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
                  bfd_put_8 (abfd, 0xff, p);
                  subspace_reloc_size += 1;
                  p += 1;
+                 break;
                }
            }
 
@@ -3168,6 +3287,10 @@ som_slurp_symbol_table (abfd)
           so the section associated with this symbol can't be known.  */
        case SS_EXTERNAL:
        case SS_UNSAT:
+         if (bufp->symbol_type != ST_STORAGE)
+           sym->symbol.section = &bfd_und_section;
+         else
+           sym->symbol.section = &bfd_com_section;
          sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
          break;
 
@@ -3816,15 +3939,61 @@ som_sizeof_headers (abfd, reloc)
   return (0);
 }
 
+/* Return the single-character symbol type corresponding to
+   SOM section S, or '?' for an unknown SOM section.  */
+
+static char
+som_section_type (s)
+     const char *s;
+{
+  const struct section_to_type *t;
+
+  for (t = &stt[0]; t->section; t++)
+    if (!strcmp (s, t->section))
+      return t->type;
+  return '?';
+}
+
+static int
+som_decode_symclass (symbol)
+     asymbol *symbol;
+{
+  char c;
+
+  if (bfd_is_com_section (symbol->section))
+    return 'C';
+  if (symbol->section == &bfd_und_section)
+    return 'U';
+  if (symbol->section == &bfd_ind_section)
+    return 'I';
+  if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
+    return '?';
+
+  if (symbol->section == &bfd_abs_section)
+    c = 'a';
+  else if (symbol->section)
+    c = som_section_type (symbol->section->name);
+  else
+    return '?';
+  if (symbol->flags & BSF_GLOBAL)
+    c = toupper (c);
+  return c;
+}
+
 /* Return information about SOM symbol SYMBOL in RET.  */
 
 static void
 som_get_symbol_info (ignore_abfd, symbol, ret)
-     bfd *ignore_abfd;         /* Ignored.  */
+     bfd *ignore_abfd;
      asymbol *symbol;
      symbol_info *ret;
 {
-  bfd_symbol_info (symbol, ret);
+  ret->type = som_decode_symclass (symbol);
+  if (ret->type != 'U')
+    ret->value = symbol->value+symbol->section->vma;
+  else
+    ret->value = 0;
+  ret->name = symbol->name;
 }
 
 /* End of miscellaneous support functions. */