2009-12-15 Tristan Gingold <gingold@adacore.com>
[binutils-gdb.git] / bfd / som.c
index 006af8cae2a914eabaf00b2316d40fcbdb7a9bd2..7a034b11084ebd62b94b2f58936b18d52c4af3f4 100644 (file)
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -1,6 +1,6 @@
 /* bfd back-end for HP PA-RISC SOM objects.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    Contributed by the Center for Software Science at the
@@ -328,7 +328,7 @@ static const struct fixup_format som_fixup_formats[256] =
   /* R_DATA_ONE_SYMBOL.  */
   {  0, "L4=Sb=" },            /* 0x25 */
   {  1, "L4=Sd=" },            /* 0x26 */
-  /* R_DATA_PLEBEL.  */
+  /* R_DATA_PLABEL.  */
   {  0, "L4=Sb=" },            /* 0x27 */
   {  1, "L4=Sd=" },            /* 0x28 */
   /* R_SPACE_REF.  */
@@ -412,8 +412,9 @@ static const struct fixup_format som_fixup_formats[256] =
   { 31, "L4=SD=" },            /* 0x6f */
   { 32, "L4=Sb=" },            /* 0x70 */
   { 33, "L4=Sd=" },            /* 0x71 */
+  /* R_DATA_GPREL.  */
+  {  0, "L4=Sd=" },            /* 0x72 */
   /* R_RESERVED.  */
-  {  0, "" },                  /* 0x72 */
   {  0, "" },                  /* 0x73 */
   {  0, "" },                  /* 0x74 */
   {  0, "" },                  /* 0x75 */
@@ -800,7 +801,7 @@ static reloc_howto_type som_hppa_howto_table[] =
   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
   SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
-  SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+  SOM_HOWTO (R_DATA_GPREL, "R_DATA_GPREL"),
   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
   SOM_HOWTO (R_RESERVED, "R_RESERVED"),
@@ -981,12 +982,12 @@ som_reloc_queue_insert (unsigned char *p,
    to the front of the queue.  */
 
 static void
-som_reloc_queue_fix (struct reloc_queue *queue, unsigned int index)
+som_reloc_queue_fix (struct reloc_queue *queue, unsigned int idx)
 {
-  if (index == 0)
+  if (idx == 0)
     return;
 
-  if (index == 1)
+  if (idx == 1)
     {
       unsigned char *tmp1 = queue[0].reloc;
       unsigned int tmp2 = queue[0].size;
@@ -998,7 +999,7 @@ som_reloc_queue_fix (struct reloc_queue *queue, unsigned int index)
       return;
     }
 
-  if (index == 2)
+  if (idx == 2)
     {
       unsigned char *tmp1 = queue[0].reloc;
       unsigned int tmp2 = queue[0].size;
@@ -1012,7 +1013,7 @@ som_reloc_queue_fix (struct reloc_queue *queue, unsigned int index)
       return;
     }
 
-  if (index == 3)
+  if (idx == 3)
     {
       unsigned char *tmp1 = queue[0].reloc;
       unsigned int tmp2 = queue[0].size;
@@ -1546,6 +1547,8 @@ hppa_som_gen_reloc_type (bfd *abfd,
          || field == e_lpsel
          || field == e_rpsel)
        *final_type = R_DATA_PLABEL;
+      else if (field == e_fsel && format == 32)
+       *final_type = R_DATA_GPREL;
       break;
 
     case R_HPPA_COMPLEX:
@@ -2774,6 +2777,24 @@ som_write_fixups (bfd *abfd,
                    abort ();
                  break;
 
+               case R_DATA_GPREL:
+                 /* Account for any addend.  */
+                 if (bfd_reloc->addend)
+                   p = som_reloc_addend (abfd, bfd_reloc->addend, p,
+                                         &subspace_reloc_size, reloc_queue);
+
+                 if (sym_num < 0x10000000)
+                   {
+                     bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+                     bfd_put_8 (abfd, sym_num >> 16, p + 1);
+                     bfd_put_16 (abfd, (bfd_vma) sym_num, p + 2);
+                     p = try_prev_fixup (abfd, &subspace_reloc_size,
+                                         p, 4, reloc_queue);
+                   }
+                 else
+                   abort ();
+                 break;
+
                case R_DATA_ONE_SYMBOL:
                case R_DATA_PLABEL:
                case R_CODE_PLABEL:
@@ -3969,7 +3990,9 @@ som_bfd_derive_misc_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
         section (ST_DATA for DATA sections, ST_CODE for CODE sections).  */
       else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
        {
-         if (sym->section->flags & SEC_CODE)
+         if (bfd_is_abs_section (sym->section))
+           info->symbol_type = ST_ABSOLUTE;
+         else if (sym->section->flags & SEC_CODE)
            info->symbol_type = ST_CODE;
          else
            info->symbol_type = ST_DATA;
@@ -4216,10 +4239,10 @@ bfd_section_from_som_symbol (bfd *abfd, struct symbol_dictionary_record *symbol)
          && symbol->symbol_type != ST_SEC_PROG
          && symbol->symbol_type != ST_MILLICODE))
     {
-      int index = symbol->symbol_info;
+      int idx = symbol->symbol_info;
 
       for (section = abfd->sections; section != NULL; section = section->next)
-       if (section->target_index == index && som_is_subspace (section))
+       if (section->target_index == idx && som_is_subspace (section))
          return section;
     }
   else
@@ -4449,13 +4472,13 @@ static asymbol *
 som_make_empty_symbol (bfd *abfd)
 {
   bfd_size_type amt = sizeof (som_symbol_type);
-  som_symbol_type *new = bfd_zalloc (abfd, amt);
+  som_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt);
 
-  if (new == NULL)
+  if (new_symbol_type == NULL)
     return NULL;
-  new->symbol.the_bfd = abfd;
+  new_symbol_type->symbol.the_bfd = abfd;
 
-  return &new->symbol;
+  return &new_symbol_type->symbol;
 }
 
 /* Print symbol information.  */
@@ -5154,7 +5177,7 @@ bfd_som_set_section_attributes (asection *section,
 bfd_boolean
 bfd_som_set_subsection_attributes (asection *section,
                                   asection *container,
-                                  int access,
+                                  int access_ctr,
                                   unsigned int sort_key,
                                   int quadrant,
                                   int comdat,
@@ -5171,7 +5194,7 @@ bfd_som_set_subsection_attributes (asection *section,
        return FALSE;
     }
   som_section_data (section)->copy_data->sort_key = sort_key;
-  som_section_data (section)->copy_data->access_control_bits = access;
+  som_section_data (section)->copy_data->access_control_bits = access_ctr;
   som_section_data (section)->copy_data->quadrant = quadrant;
   som_section_data (section)->copy_data->container = container;
   som_section_data (section)->copy_data->is_comdat = comdat;
@@ -6320,12 +6343,15 @@ som_bfd_link_split_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
 #define som_bfd_link_hash_table_free            _bfd_generic_link_hash_table_free
 #define som_bfd_link_add_symbols                _bfd_generic_link_add_symbols
 #define som_bfd_link_just_syms                  _bfd_generic_link_just_syms
+#define som_bfd_copy_link_hash_symbol_type \
+  _bfd_generic_copy_link_hash_symbol_type
 #define som_bfd_final_link                      _bfd_generic_final_link
 #define som_bfd_gc_sections                    bfd_generic_gc_sections
 #define som_bfd_merge_sections                 bfd_generic_merge_sections
 #define som_bfd_is_group_section               bfd_generic_is_group_section
 #define som_bfd_discard_group                  bfd_generic_discard_group
 #define som_section_already_linked              _bfd_generic_section_already_linked
+#define som_bfd_define_common_symbol            bfd_generic_define_common_symbol
 #define som_bfd_merge_private_bfd_data         _bfd_generic_bfd_merge_private_bfd_data
 #define som_bfd_copy_private_header_data       _bfd_generic_bfd_copy_private_header_data
 #define som_bfd_set_private_flags              _bfd_generic_bfd_set_private_flags