* som.c (hppa_som_gen_reloc_type): New argument "sym_diff",
authorJeff Law <law@redhat.com>
Mon, 3 Jul 1995 23:27:25 +0000 (23:27 +0000)
committerJeff Law <law@redhat.com>
Mon, 3 Jul 1995 23:27:25 +0000 (23:27 +0000)
nonzero when we're generating relocations for an expression
using the difference of two symbols.  All callers changed.
Handle difference of symbols for both R_HPPA and R_COMPLEX
cases.
(som_write_fixups): Handle R_COMP1, R_COMP2 and R_CODE_EXPR
fixups.

bfd/ChangeLog
bfd/som.c
bfd/som.h

index cfb81a504375341a5eaa00368b3ee621814ea835..a340b74834d4ee0c88df55888fd8e936061c331a 100644 (file)
@@ -1,3 +1,13 @@
+Mon Jul  3 17:03:52 1995  Jeff Law  (law@snake.cs.utah.edu)
+
+       * som.c (hppa_som_gen_reloc_type): New argument "sym_diff",
+       nonzero when we're generating relocations for an expression
+       using the difference of two symbols.  All callers changed.
+       Handle difference of symbols for both R_HPPA and R_COMPLEX
+       cases.
+       (som_write_fixups): Handle R_COMP1, R_COMP2 and R_CODE_EXPR
+       fixups.
+
 Mon Jul  3 13:55:18 1995  Steve Chamberlain  <sac@slash.cygnus.com>
 
        * config.bfd (win32): New configuration.
index f97a7fefbb8b0029abad51e586fb49a017205b69..e43e3946afdbe0eb3fb667a26276b00bbf849751 100644 (file)
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -167,6 +167,8 @@ static asymbol * som_make_empty_symbol PARAMS ((bfd *));
 static void som_print_symbol PARAMS ((bfd *, PTR,
                                      asymbol *, bfd_print_symbol_type));
 static boolean som_new_section_hook PARAMS ((bfd *, asection *));
+static boolean som_bfd_copy_private_symbol_data PARAMS ((bfd *, asymbol *,
+                                                         bfd *, asymbol *));
 static boolean som_bfd_copy_private_section_data PARAMS ((bfd *, asection *,
                                                          bfd *, asection *));
 static boolean som_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
@@ -254,6 +256,7 @@ static boolean som_is_space PARAMS ((asection *));
 static boolean som_is_subspace PARAMS ((asection *));
 static boolean som_is_container PARAMS ((asection *, asection *));
 static boolean som_bfd_free_cached_info PARAMS ((bfd *));
+static boolean som_bfd_link_split_section PARAMS ((bfd *, asection *));
        
 /* Map SOM section names to POSIX/BSD single-character symbol types.
 
@@ -1394,15 +1397,16 @@ hppa_som_reloc (abfd, reloc_entry, symbol_in, data,
    and a field selector, return one or more appropriate SOM relocations.  */
 
 int **
-hppa_som_gen_reloc_type (abfd, base_type, format, field)
+hppa_som_gen_reloc_type (abfd, base_type, format, field, sym_diff)
      bfd *abfd;
      int base_type;
      int format;
      enum hppa_reloc_field_selector_type_alt field;
+     int sym_diff;
 {
   int *final_type, **final_types;
 
-  final_types = (int **) bfd_alloc_by_size_t (abfd, sizeof (int *) * 3);
+  final_types = (int **) bfd_alloc_by_size_t (abfd, sizeof (int *) * 6);
   final_type = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
   if (!final_types || !final_type)
     {
@@ -1507,8 +1511,29 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field)
   switch (base_type)
     {
     case R_HPPA:
+      /* The difference of two symbols needs *very* special handling.  */
+      if (sym_diff)
+       {
+         final_types[0] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
+         final_types[1] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
+         final_types[2] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
+         final_types[3] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
+         if (!final_types[0] || !final_types[1] || !final_types[2])
+          {
+            bfd_set_error (bfd_error_no_memory);
+            return NULL;
+          }
+         *final_types[0] = R_FSEL;
+         *final_types[1] = R_COMP2;
+         *final_types[2] = R_COMP2;
+         *final_types[3] = R_COMP1;
+         final_types[4] = final_type;
+         *final_types[4] = R_CODE_EXPR;
+         final_types[5] = NULL;
+         break;
+       }
       /* PLABELs get their own relocation type.  */
-      if (field == e_psel
+      else if (field == e_psel
          || field == e_lpsel
          || field == e_rpsel)
        {
@@ -1538,6 +1563,31 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field)
        *final_type = R_DATA_PLABEL;
       break;
 
+    case R_HPPA_COMPLEX:
+      /* The difference of two symbols needs *very* special handling.  */
+      if (sym_diff)
+       {
+         final_types[0] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
+         final_types[1] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
+         final_types[2] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
+         final_types[3] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int));
+         if (!final_types[0] || !final_types[1] || !final_types[2])
+          {
+            bfd_set_error (bfd_error_no_memory);
+            return NULL;
+          }
+         *final_types[1] = R_FSEL;
+         *final_types[1] = R_COMP2;
+         *final_types[2] = R_COMP2;
+         *final_types[3] = R_COMP1;
+         final_types[4] = final_type;
+         *final_types[4] = R_CODE_EXPR;
+         final_types[5] = NULL;
+         break;
+       }
+      else
+       break;
+
     case R_HPPA_NONE:
     case R_HPPA_ABS_CALL:
     case R_HPPA_PCREL_CALL:
@@ -2556,6 +2606,8 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
                case R_FSEL:
                case R_LSEL:
                case R_RSEL:
+               case R_COMP1:
+               case R_COMP2:
                  reloc_offset = bfd_reloc->address;
                  break;
 
@@ -2690,6 +2742,37 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
                  p += 1;
                  break;
 
+               case R_COMP1:
+                 /* The only time we generate R_COMP1, R_COMP2 and 
+                    R_CODE_EXPR relocs is for the difference of two
+                    symbols.  Hence we can cheat here.  */
+                 bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+                 bfd_put_8 (abfd, 0x44, p + 1);
+                 p = try_prev_fixup (abfd, &subspace_reloc_size,
+                                     p, 2, reloc_queue);
+                 break;
+
+               case R_COMP2:
+                 /* The only time we generate R_COMP1, R_COMP2 and 
+                    R_CODE_EXPR relocs is for the difference of two
+                    symbols.  Hence we can cheat here.  */
+                 bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+                 bfd_put_8 (abfd, 0x80, p + 1);
+                 bfd_put_8 (abfd, sym_num >> 16, p + 2);
+                 bfd_put_16 (abfd, sym_num, p + 3);
+                 p = try_prev_fixup (abfd, &subspace_reloc_size,
+                                     p, 5, reloc_queue);
+                 break;
+
+               case R_CODE_EXPR:
+                 /* The only time we generate R_COMP1, R_COMP2 and 
+                    R_CODE_EXPR relocs is for the difference of two
+                    symbols.  Hence we can cheat here.  */
+                 bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+                 subspace_reloc_size += 1;
+                 p += 1;
+                 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.  */
@@ -4185,8 +4268,11 @@ som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
                 the stack.  */
              else if (islower (c))
                {
+                 int bits = (c - 'a') * 8;
                  for (v = 0; c > 'a'; --c)
                    v = (v << 8) | *fixup++;
+                 if (varname == 'V')
+                   v = sign_extend (v, bits);
                  push (v);
                }
 
@@ -4574,6 +4660,31 @@ som_new_section_hook (abfd, newsect)
   return true;
 }
 
+/* Copy any private info we understand from the input symbol
+   to the output symbol.  */
+
+static boolean
+som_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)
+     bfd *ibfd;
+     asymbol *isymbol;
+     bfd *obfd;
+     asymbol *osymbol;
+{
+  struct som_symbol *input_symbol = isymbol;
+  struct som_symbol *output_symbol = osymbol;
+
+  /* One day we may try to grok other private data.  */
+  if (ibfd->xvec->flavour != bfd_target_som_flavour
+      || obfd->xvec->flavour != bfd_target_som_flavour)
+    return false;
+
+  /* The only private information we need to copy is the argument relocation
+     bits.  */
+  output_symbol->tc_data.hppa_arg_reloc = input_symbol->tc_data.hppa_arg_reloc;
+
+  return true;
+}
+
 /* Copy any private info we understand from the input section
    to the output section.  */
 static boolean
@@ -5813,6 +5924,15 @@ som_bfd_free_cached_info (abfd)
 
 /* End of miscellaneous support functions. */
 
+/* Linker support functions.  */
+static boolean
+som_bfd_link_split_section (abfd, sec)
+     bfd *abfd;
+     asection *sec;
+{
+  return (som_is_subspace (sec) && sec->_raw_size > 240000);
+}
+
 #define        som_close_and_cleanup           som_bfd_free_cached_info
 
 #define som_openr_next_archived_file   bfd_generic_openr_next_archived_file
index 99b777d3ca8da676cf0ec7b0f44068b423a12a46..32303446e5bd20c7ac5e65693da2d8c9f0a56a71 100644 (file)
--- a/bfd/som.h
+++ b/bfd/som.h
 #include <lst.h>
 #include <ar.h>
 
+/* The SOM BFD backend doesn't currently use anything from these
+   two include files, but it's likely to need them in the future.  */
+#ifdef R_DLT_REL
+#include <shl.h>
+#include <dl.h>
+#endif
 
 #if defined(HOST_HPPABSD) || defined (HOST_HPPAOSF)
 /* BSD uses a completely different scheme for object file identification.
@@ -107,6 +113,7 @@ struct somdata
        need not be copied for objcopy or strip to work.  */
     som_symbol_type *symtab;
     char *stringtab;
+    asymbol **sorted_syms;
 
     /* We remember these offsets so that after check_file_format, we have
        no dependencies on the particular format of the exec_hdr.
@@ -179,6 +186,7 @@ struct som_section_data_struct
 #define obj_som_str_filepos(bfd)       (somdata(bfd).str_filepos)
 #define obj_som_stringtab_size(bfd)    (somdata(bfd).stringtab_size)
 #define obj_som_reloc_filepos(bfd)     (somdata(bfd).reloc_filepos)
+#define obj_som_sorted_syms(bfd)       (somdata(bfd).sorted_syms)
 #define som_section_data(sec) \
   ((struct som_section_data_struct *)sec->used_by_bfd)
 #define som_symbol_data(symbol)                ((som_symbol_type *) symbol)
@@ -210,5 +218,5 @@ boolean bfd_som_set_subsection_attributes PARAMS ((asection *, asection *,
 void bfd_som_set_symbol_type PARAMS ((asymbol *, unsigned int));
 boolean bfd_som_attach_aux_hdr PARAMS ((bfd *, int, char *));
 int ** hppa_som_gen_reloc_type
-  PARAMS ((bfd *, int, int, enum hppa_reloc_field_selector_type_alt));
+  PARAMS ((bfd *, int, int, enum hppa_reloc_field_selector_type_alt, int));
 #endif /* _SOM_H */
This page took 0.035146 seconds and 4 git commands to generate.