dummy commit before egcs merge
[deliverable/binutils-gdb.git] / bfd / nlm32-alpha.c
index 358bc40ccaf52db8814dcb28566975263a805e2d..c70f630af32beaf65272f2f5a02dfe5299612c22 100644 (file)
@@ -16,7 +16,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* This file describes the 32 bit Alpha NLM format.  You might think
    that an Alpha chip would use a 64 bit format, but, for some reason,
@@ -92,10 +92,8 @@ nlm_alpha_write_prefix (abfd)
   bfd_h_put_32 (abfd, (bfd_vma) 2, s.format);
   bfd_h_put_32 (abfd, (bfd_vma) sizeof s, s.size);
   if (bfd_write ((PTR) &s, sizeof s, 1, abfd) != sizeof s)
-    {
-      bfd_error = system_call_error;
-      return false;
-    }
+    return false;
+  return true;
 }
 \f
 /* How to process the various reloc types.  */
@@ -424,10 +422,7 @@ nlm_alpha_read_reloc (abfd, sym, secp, rel)
 
   /* Read the reloc from the file.  */
   if (bfd_read (&ext, sizeof ext, 1, abfd) != sizeof ext)
-    {
-      bfd_error = system_call_error;
-      return false;
-    }
+    return false;
 
   /* Swap in the reloc information.  */
   r_vaddr = bfd_h_get_64 (abfd, (bfd_byte *) ext.r_vaddr);
@@ -466,16 +461,16 @@ nlm_alpha_read_reloc (abfd, sym, secp, rel)
          || r_type == ALPHA_R_GPDISP
          || r_type == ALPHA_R_IGNORE)
        {
-         rel->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
+         rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
          rel->addend = 0;
        }
-      else if (r_symndx == RELOC_SECTION_TEXT)
+      else if (r_symndx == ALPHA_RELOC_SECTION_TEXT)
        {
          rel->sym_ptr_ptr = code_sec->symbol_ptr_ptr;
          BFD_ASSERT (bfd_get_section_vma (abfd, code_sec) == 0);
          rel->addend = 0;
        }
-      else if (r_symndx == RELOC_SECTION_DATA)
+      else if (r_symndx == ALPHA_RELOC_SECTION_DATA)
        {
          rel->sym_ptr_ptr = data_sec->symbol_ptr_ptr;
          rel->addend = - bfd_get_section_vma (abfd, data_sec);
@@ -483,7 +478,7 @@ nlm_alpha_read_reloc (abfd, sym, secp, rel)
       else
        {
          BFD_ASSERT (0);
-         rel->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
+         rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
          rel->addend = 0;
        }
     }
@@ -536,7 +531,7 @@ nlm_alpha_read_reloc (abfd, sym, secp, rel)
         addend, but they do use a special code.  Put this code in the
         addend field.  */
       rel->addend = r_symndx;
-      rel->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
+      rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
       break;
 
     case ALPHA_R_OP_STORE:
@@ -567,20 +562,29 @@ nlm_alpha_read_reloc (abfd, sym, secp, rel)
         some reason the address of this reloc type is not adjusted by
         the section vma.  We record the gp value for this object file
         here, for convenience when doing the GPDISP relocation.  */
-      rel->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
+      rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
       rel->address = r_vaddr;
       rel->addend = gp_value;
       break;
 
     case ALPHA_R_NW_RELOC:
+      /* If this is SETGP, we set the addend to 0.  Otherwise we set
+        the addend to the size of the .lita section (this is
+        r_symndx) plus 1.  We have already set the address of the
+        reloc to r_vaddr.  */
       if (r_size == ALPHA_R_NW_RELOC_SETGP)
-       gp_value = r_vaddr;
+       {
+         gp_value = r_vaddr;
+         rel->addend = 0;
+       }
       else if (r_size == ALPHA_R_NW_RELOC_LITA)
-       lita_address = r_vaddr;
+       {
+         lita_address = r_vaddr;
+         rel->addend = r_symndx + 1;
+       }
       else
        BFD_ASSERT (0);
-      rel->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
-      rel->addend = r_size;
+      rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
       break;
 
     default:
@@ -619,32 +623,29 @@ nlm_alpha_read_import (abfd, sym)
   bfd_size_type rcount;                        /* number of relocs */
   bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
   unsigned char symlength;             /* length of symbol name */
+  char *name;
 
   if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
       != sizeof (symlength))
-    {
-      bfd_error = system_call_error;
-      return (false);
-    }
+    return false;
   sym -> symbol.the_bfd = abfd;
-  sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
-  if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
-      != symlength)
-    {
-      bfd_error = system_call_error;
-      return (false);
-    }
+  name = bfd_alloc (abfd, symlength + 1);
+  if (name == NULL)
+    return false;
+  if (bfd_read (name, symlength, 1, abfd) != symlength)
+    return false;
+  name[symlength] = '\0';
+  sym -> symbol.name = name;
   sym -> symbol.flags = 0;
   sym -> symbol.value = 0;
-  sym -> symbol.section = &bfd_und_section;
+  sym -> symbol.section = bfd_und_section_ptr;
   if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
-    {
-      bfd_error = system_call_error;
-      return (false);
-    }
+    return false;
   rcount = bfd_h_get_32 (abfd, temp);
   nlm_relocs = ((struct nlm_relent *)
                bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
+  if (!nlm_relocs)
+    return false;
   sym -> relocs = nlm_relocs;
   sym -> rcnt = 0;
   while (sym -> rcnt < rcount)
@@ -680,52 +681,72 @@ nlm_alpha_write_import (abfd, sec, rel)
   sym = *rel->sym_ptr_ptr;
 
   /* Get values for the relocation fields.  */
-  r_vaddr = bfd_get_section_vma (abfd, sec) + rel->address;
-  if (bfd_get_section (sym) == &bfd_und_section)
-    {
-      r_extern = 1;
-      r_symndx = 0;
-    }
-  else
+  r_type = rel->howto->type;
+  if (r_type != ALPHA_R_NW_RELOC)
     {
-      r_extern = 0;
-      if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
-       r_symndx = RELOC_SECTION_TEXT;
+      r_vaddr = bfd_get_section_vma (abfd, sec) + rel->address;
+      if ((sec->flags & SEC_CODE) == 0)
+       r_vaddr += bfd_section_size (abfd,
+                                    bfd_get_section_by_name (abfd,
+                                                             NLM_CODE_NAME));
+      if (bfd_is_und_section (bfd_get_section (sym)))
+       {
+         r_extern = 1;
+         r_symndx = 0;
+       }
       else
-       r_symndx = RELOC_SECTION_DATA;
-    }
-  r_type = rel->howto->type;
-  r_offset = 0;
-  r_size = 0;
+       {
+         r_extern = 0;
+         if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
+           r_symndx = ALPHA_RELOC_SECTION_TEXT;
+         else
+           r_symndx = ALPHA_RELOC_SECTION_DATA;
+       }
+      r_offset = 0;
+      r_size = 0;
 
-  switch (r_type)
+      switch (r_type)
+       {
+       case ALPHA_R_LITUSE:
+       case ALPHA_R_GPDISP:
+         r_symndx = rel->addend;
+         break;
+
+       case ALPHA_R_OP_STORE:
+         r_size = rel->addend & 0xff;
+         r_offset = (rel->addend >> 8) & 0xff;
+         break;
+
+       case ALPHA_R_OP_PUSH:
+       case ALPHA_R_OP_PSUB:
+       case ALPHA_R_OP_PRSHIFT:
+         r_vaddr = rel->addend;
+         break;
+
+       case ALPHA_R_IGNORE:
+         r_vaddr = rel->address;
+         break;
+
+       default:
+         break;
+       }
+    }
+  else
     {
-    case ALPHA_R_LITUSE:
-    case ALPHA_R_GPDISP:
-      r_symndx = rel->addend;
-      break;
-
-    case ALPHA_R_OP_STORE:
-      r_size = rel->addend & 0xff;
-      r_offset = (rel->addend >> 8) & 0xff;
-      break;
-
-    case ALPHA_R_OP_PUSH:
-    case ALPHA_R_OP_PSUB:
-    case ALPHA_R_OP_PRSHIFT:
-      r_vaddr = rel->addend;
-      break;
-
-    case ALPHA_R_IGNORE:
+      /* r_type == ALPHA_R_NW_RELOC */
       r_vaddr = rel->address;
-      break;
-
-    case ALPHA_R_NW_RELOC:
-      r_size = rel->addend;
-      break;
-
-    default:
-      break;
+      if (rel->addend == 0)
+       {
+         r_symndx = 0;
+         r_size = ALPHA_R_NW_RELOC_SETGP;
+       }
+      else
+       {
+         r_symndx = rel->addend - 1;
+         r_size = ALPHA_R_NW_RELOC_LITA;
+       }
+      r_extern = 0;
+      r_offset = 0;
     }
 
   /* Swap out the relocation fields.  */
@@ -745,10 +766,7 @@ nlm_alpha_write_import (abfd, sec, rel)
 
   /* Write out the relocation.  */
   if (bfd_write (&ext, sizeof ext, 1, abfd) != sizeof ext)
-    {
-      bfd_error = system_call_error;
-      return false;
-    }
+    return false;
 
   return true;
 }
@@ -800,28 +818,38 @@ nlm_alpha_get_public_offset (abfd, sym)
 static boolean
 nlm_alpha_write_external (abfd, count, sym, relocs)
      bfd *abfd;
-     bfd_vma count;
+     bfd_size_type count;
      asymbol *sym;
      struct reloc_and_sec *relocs;
 {
   int i;
   bfd_byte len;
   unsigned char temp[NLM_TARGET_LONG_SIZE];
+  arelent r;
 
   len = strlen (sym->name);
   if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
       || bfd_write (sym->name, len, 1, abfd) != len)
-    {
-      bfd_error = system_call_error;
-      return false;
-    }
+    return false;
 
-  bfd_put_32 (abfd, count, temp);
+  bfd_put_32 (abfd, count + 2, temp);
   if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
-    {
-      bfd_error = system_call_error;
-      return false;
-    }
+    return false;
+
+  /* The first two relocs for each external symbol are the .lita
+     address and the GP value.  */
+  r.sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+  r.howto = &nlm32_alpha_nw_howto;
+
+  r.address = nlm_alpha_backend_data (abfd)->lita_address;
+  r.addend = nlm_alpha_backend_data (abfd)->lita_size + 1;
+  if (nlm_alpha_write_import (abfd, (asection *) NULL, &r) == false)
+    return false;
+
+  r.address = nlm_alpha_backend_data (abfd)->gp;
+  r.addend = 0;
+  if (nlm_alpha_write_import (abfd, (asection *) NULL, &r) == false)
+    return false;
 
   for (i = 0; i < count; i++)
     {
@@ -842,6 +870,7 @@ static const struct nlm_backend_data nlm32_alpha_backend =
   sizeof (struct nlm32_alpha_external_prefix_header),
   bfd_arch_alpha,
   0,
+  true, /* no uninitialized data permitted by Alpha NetWare.  */
   nlm_alpha_backend_object_p,
   nlm_alpha_write_prefix,
   nlm_alpha_read_reloc,
@@ -853,6 +882,7 @@ static const struct nlm_backend_data nlm32_alpha_backend =
   nlm_swap_fixed_header_in,
   nlm_swap_fixed_header_out,
   nlm_alpha_write_external,
+  0,   /* write_export */
 };
 
 #define TARGET_LITTLE_NAME             "nlm32-alpha"
This page took 0.029015 seconds and 4 git commands to generate.