From Robin Kirkham <Robin.Kirkham@mlb.dmt.csiro.au>:
[deliverable/binutils-gdb.git] / bfd / som.c
index a1cf4cd52ed2c8ed991f926afcccf721103320c7..0a80300dcb854b7647f7d8ec403c674cafd713c4 100644 (file)
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -2631,8 +2631,6 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
                 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_ALT_ENTRY:
                case R_EXIT:
@@ -2647,6 +2645,8 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
                case R_COMP2:
                case R_BEGIN_BRTAB:
                case R_END_BRTAB:
+               case R_BEGIN_TRY:
+               case R_END_TRY:
                case R_N0SEL:
                case R_N1SEL:
                  reloc_offset = bfd_reloc->address;
@@ -2780,6 +2780,7 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
                case R_RSEL:
                case R_BEGIN_BRTAB:
                case R_END_BRTAB:
+               case R_BEGIN_TRY:
                case R_N0SEL:
                case R_N1SEL:
                  bfd_put_8 (abfd, bfd_reloc->howto->type, p);
@@ -2787,6 +2788,29 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
                  p += 1;
                  break;
 
+               case R_END_TRY:
+                 /* The end of a exception handling region.  The reloc's
+                    addend contains the offset of the exception handling
+                    code.  */
+                 if (bfd_reloc->addend == 0)
+                   bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+                 else if (bfd_reloc->addend < 1024)
+                   {
+                     bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p);
+                     bfd_put_8 (abfd, bfd_reloc->addend / 4, p + 1);
+                     p = try_prev_fixup (abfd, &subspace_reloc_size,
+                                         p, 2, reloc_queue);
+                   }
+                 else
+                   {
+                     bfd_put_8 (abfd, bfd_reloc->howto->type + 2, p);
+                     bfd_put_8 (abfd, (bfd_reloc->addend / 4) >> 16, p + 1);
+                     bfd_put_16 (abfd, bfd_reloc->addend / 4, p + 2);
+                     p = try_prev_fixup (abfd, &subspace_reloc_size,
+                                         p, 4, reloc_queue);
+                   }
+                 break;
+                     
                case R_COMP1:
                  /* The only time we generate R_COMP1, R_COMP2 and 
                     R_CODE_EXPR relocs is for the difference of two
@@ -3705,16 +3729,22 @@ som_bfd_derive_misc_symbol_info (abfd, sym, info)
          info->arg_reloc = som_symbol_data (sym)->tc_data.hppa_arg_reloc;
        }
 
-      /* If the type is unknown at this point, it should be ST_DATA or
-        ST_CODE (function/ST_ENTRY symbols were handled  as special
-        cases above). */
+      /* For unknown symbols, set their type to ST_DATA.
+
+        We used to set the symbol type based on the section this symbol
+        was in (ST_DATA for DATA sections, ST_CODE for CODE sections).
+        Strictly speaking, this is the right approach.  However, the
+        linker chokes if we have an R_DATA_ONE_SYMBOL reloc involving
+        an ST_CODE symbol in a shared library, which happens for
+        exception handling tables.
+
+        I tried an alternate approach to generating exception handling
+        tables using PUSH_SYM and DATA_EXPR relocs, but that fails to
+        relocate exception handling tables in shared libraries.
+
+        What a pain.  */
       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
-       {
-         if (sym->section->flags & SEC_CODE)
-           info->symbol_type = ST_CODE;
-         else
-           info->symbol_type = ST_DATA;
-       }
+       info->symbol_type = ST_DATA;
 
       /* From now on it's a very simple mapping.  */
       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE)
@@ -4625,6 +4655,7 @@ som_slurp_reloc_table (abfd, section, symbols, just_count)
 
   /* We're done with the external relocations.  Free them.  */
   free (external_relocs);
+  som_section_data (section)->reloc_stream = NULL;
 
   /* Save our results and return success.  */
   section->relocation = internal_relocs;
This page took 0.025344 seconds and 4 git commands to generate.