2000-11-27 Kazu Hirata <kazu@hxi.com>
[binutils-gdb.git] / bfd / xcofflink.c
index 9ec75bd01d8f4edabd7300b9bad2dbeacfc51bab..4b265cc381ab106ea23423ced1d559ea7de41dea 100644 (file)
@@ -29,14 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #define STRING_SIZE_SIZE (4)
 
-/* In order to support linking different object file formats into an
-   XCOFF format, we need to be able to determine whether a particular
-   bfd_target is an XCOFF vector.  FIXME: We need to rethink this
-   whole approach.  */
-#define XCOFF_XVECP(xv) \
-  (strcmp ((xv)->name, "aixcoff-rs6000") == 0 \
-   || strcmp ((xv)->name, "xcoff-powermac") == 0)
-
 /* Get the XCOFF hash table entries for a BFD.  */
 #define obj_xcoff_sym_hashes(bfd) \
   ((struct xcoff_link_hash_entry **) obj_coff_sym_hashes (bfd))
@@ -2915,7 +2907,7 @@ bfd_xcoff_link_record_set (output_bfd, info, harg, size)
   struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
   struct xcoff_link_size_list *n;
 
-  if (! XCOFF_XVECP (output_bfd->xvec))
+  if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
     return true;
 
   /* This will hardly ever be called.  I don't want to burn four bytes
@@ -2951,7 +2943,7 @@ bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile,
 {
   struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
 
-  if (! XCOFF_XVECP (output_bfd->xvec))
+  if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
     return true;
 
   /* A symbol name which starts with a period is the code for a
@@ -3065,7 +3057,7 @@ bfd_xcoff_export_symbol (output_bfd, info, harg, syscall)
 {
   struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
 
-  if (! XCOFF_XVECP (output_bfd->xvec))
+  if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
     return true;
 
   h->flags |= XCOFF_EXPORT;
@@ -3130,7 +3122,7 @@ bfd_xcoff_link_count_reloc (output_bfd, info, name)
 {
   struct xcoff_link_hash_entry *h;
 
-  if (! XCOFF_XVECP (output_bfd->xvec))
+  if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
     return true;
 
   h = ((struct xcoff_link_hash_entry *)
@@ -3164,7 +3156,7 @@ bfd_xcoff_record_link_assignment (output_bfd, info, name)
 {
   struct xcoff_link_hash_entry *h;
 
-  if (! XCOFF_XVECP (output_bfd->xvec))
+  if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
     return true;
 
   h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, true, true,
@@ -3249,7 +3241,7 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
   struct bfd_strtab_hash *debug_strtab;
   bfd_byte *debug_contents = NULL;
 
-  if (! XCOFF_XVECP (output_bfd->xvec))
+  if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
     {
       for (i = 0; i < 6; i++)
        special_sections[i] = NULL;
@@ -4687,22 +4679,40 @@ xcoff_link_input_bfd (finfo, input_bfd)
          else
            {
              bfd_vma tocval, tocend;
+             bfd *inp;
 
              tocval = ((*csectpp)->output_section->vma
                        + (*csectpp)->output_offset
                        + isym.n_value
                        - (*csectpp)->vma);
+
              /* We want to find out if tocval is a good value to use
                  as the TOC anchor--that is, whether we can access all
                  of the TOC using a 16 bit offset from tocval.  This
                  test assumes that the TOC comes at the end of the
                  output section, as it does in the default linker
-                 script.  FIXME: This doesn't handle .tocbss sections
-                 created from XMC_TD common symbols correctly.  */
-
+                 script.  */
              tocend = ((*csectpp)->output_section->vma
                        + (*csectpp)->output_section->_raw_size);
-
+             for (inp = finfo->info->input_bfds; 
+                  inp != NULL; 
+                  inp = inp->link_next)
+               {
+                 asection *o;
+                 
+                 for (o = inp->sections; o != NULL; o = o->next)
+                   if (strcmp (o->name, ".tocbss") == 0)
+                     {
+                       bfd_vma new_toc_end;
+                       new_toc_end = (o->output_section->vma
+                                      + o->output_offset
+                                      + o->_cooked_size);
+                       if (new_toc_end > tocend)
+                         tocend = new_toc_end;
+                     }
+                 
+               }
+             
              if (tocval + 0x10000 < tocend)
                {
                  (*_bfd_error_handler)
@@ -6421,7 +6431,7 @@ _bfd_ppc_xcoff_relocate_section (output_bfd, info, input_bfd,
            {
              if (! ((*info->callbacks->undefined_symbol)
                     (info, h->root.root.string, input_bfd, input_section,
-                     rel->r_vaddr - input_section->vma)))
+                     rel->r_vaddr - input_section->vma, true)))
                return false;
 
              /* Don't try to process the reloc.  It can't help, and
@@ -6585,13 +6595,14 @@ _bfd_ppc_xcoff_relocate_section (output_bfd, info, input_bfd,
              || strcmp (h->root.root.string, "._ptrgl") == 0)
            {
              if (next == 0x4def7b82            /* cror 15,15,15 */
-                 || next == 0x4ffffb82)        /* cror 31,31,31 */
+                 || next == 0x4ffffb82         /* cror 31,31,31 */
+                 || next == 0x60000000)        /* ori r0,r0,0 */
                bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r1,20(r1) */
            }
          else
            {
              if (next == 0x80410014)           /* lwz r1,20(r1) */
-               bfd_put_32 (input_bfd, 0x4ffffb82, pnext); /* cror 31,31,31 */
+               bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
            }
        }