* syms.c (BSF_DYNAMIC): New symbol flag.
authorIan Lance Taylor <ian@airs.com>
Fri, 21 Jan 1994 06:29:21 +0000 (06:29 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 21 Jan 1994 06:29:21 +0000 (06:29 +0000)
(bfd_print_symbol_vandf): Print it.
* bfd-in2.h: Rebuilt.
* libaout.h (struct aout_backend_data): New read_dynamic_symbols
and read_dynamic_relocs fields.
(struct aoutdata): New dynamic_info field.
(obj_aout_dynamic_info): New accessor macro.
* sunos.c (struct sunos_dynamic_info): New structure.
(sunos_read_dynamic_info, MY(read_dynamic_symbols),
MY(read_dynamic_relocs)): New functions to read dynamic symbols
and relocs.
* aoutx.h (NAME(aout,some_aout_object_p)): If the object is
dynamically linked, set SEC_RELOC for both the .text and .data
sections.
(translate_from_native_sym_flags): Don't set BSF_LOCAL for an
undefined symbol.
(translate_symbol_table): New function, split out of
slurp_symbol_table; set the BSF_DYNAMIC flag appropriately.
(NAME(aout,slurp_symbol_table)): Read dynamic symbols, if any.
(NAME(aout,slurp_reloc_table)): Read dynamic relocs, if any.
(NAME(aout,get_reloc_upper_bound)): Include dynamic reloc count in
return value.
* aoutf1.h (NAME(aout,sunos4_write_object_contents)): Don't write
out dynamic symbols or relocs against reloc symbols, since they
are already in the .text section and we wouldn't know where to
write them anyhow.
(sunos4_aout_backend): Initialize read_dynamic_symbols and
read_dynamic_relocs fields.
* aout-target.h (MY(backend_data)): Initialize
read_dynamic_symbols and read_dynamic_relocs fields.

bfd/ChangeLog
bfd/aoutf1.h
bfd/aoutx.h
bfd/bfd-in2.h
bfd/sunos.c
bfd/syms.c

index 5b47c973703d27bdd655d558197111fd7b214941..f7eb6671ffa847d74424fb557d4261e60dd43f91 100644 (file)
@@ -1,3 +1,36 @@
+Fri Jan 21 01:11:55 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+       * syms.c (BSF_DYNAMIC): New symbol flag.
+       (bfd_print_symbol_vandf): Print it.
+       * bfd-in2.h: Rebuilt.
+       * libaout.h (struct aout_backend_data): New read_dynamic_symbols
+       and read_dynamic_relocs fields.
+       (struct aoutdata): New dynamic_info field.
+       (obj_aout_dynamic_info): New accessor macro.
+       * sunos.c (struct sunos_dynamic_info): New structure.
+       (sunos_read_dynamic_info, MY(read_dynamic_symbols),
+       MY(read_dynamic_relocs)): New functions to read dynamic symbols
+       and relocs.
+       * aoutx.h (NAME(aout,some_aout_object_p)): If the object is
+       dynamically linked, set SEC_RELOC for both the .text and .data
+       sections.
+       (translate_from_native_sym_flags): Don't set BSF_LOCAL for an
+       undefined symbol.
+       (translate_symbol_table): New function, split out of
+       slurp_symbol_table; set the BSF_DYNAMIC flag appropriately.
+       (NAME(aout,slurp_symbol_table)): Read dynamic symbols, if any.
+       (NAME(aout,slurp_reloc_table)): Read dynamic relocs, if any.
+       (NAME(aout,get_reloc_upper_bound)): Include dynamic reloc count in
+       return value.
+       * aoutf1.h (NAME(aout,sunos4_write_object_contents)): Don't write
+       out dynamic symbols or relocs against reloc symbols, since they
+       are already in the .text section and we wouldn't know where to
+       write them anyhow.
+       (sunos4_aout_backend): Initialize read_dynamic_symbols and
+       read_dynamic_relocs fields.
+       * aout-target.h (MY(backend_data)): Initialize
+       read_dynamic_symbols and read_dynamic_relocs fields.
+
 Thu Jan 20 20:57:27 1994  Ken Raeburn  (raeburn@cujo.cygnus.com)
 
        * hosts/alphaosf.h (uint64e_type, uint64_type, int64_type): Delete
index 2f4b7286ddb07699fbc99554766fc3dd8f79ac9b..b5dcecfddaf213494369de0922ca006fa162209f 100644 (file)
@@ -195,7 +195,70 @@ DEFUN(NAME(aout,sunos4_write_object_contents),
      */
   N_SET_FLAGS (*execp, 1);
 #endif
-    
+
+  N_SET_DYNAMIC(*execp, bfd_get_file_flags(abfd) & DYNAMIC);
+
+  /* At least for SunOS, the dynamic symbols and relocs are embedded
+     in the .text section, and we do not want to write them out with
+     the symbol table.  FIXME: This may be right if there is any other
+     form of a.out shared libraries.  */
+  if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0
+      && bfd_get_outsymbols (abfd) != (asymbol **) NULL)
+    {
+      bfd_size_type i;
+      asymbol **sym_ptr_ptr;
+      bfd_size_type count;
+      arelent **rel_ptr_ptr;
+
+      sym_ptr_ptr = bfd_get_outsymbols (abfd);
+      count = bfd_get_symcount (abfd);
+      for (i = 0; i < count; i++, sym_ptr_ptr++)
+       {
+         if (((*sym_ptr_ptr)->flags & BSF_DYNAMIC) != 0)
+           {
+             /* This assumes that all dynamic symbols follow all
+                non-dynamic symbols, which is what slurp_symbol_table
+                does.  */
+             *sym_ptr_ptr = NULL;
+             bfd_get_symcount (abfd) = i;
+             break;
+           }
+       }
+
+      if (obj_textsec (abfd)->reloc_count > 0)
+       {
+         rel_ptr_ptr = obj_textsec (abfd)->orelocation;
+         count = obj_textsec (abfd)->reloc_count;
+         for (i = 0; i < count; i++, rel_ptr_ptr++)
+           {
+             if (((*(*rel_ptr_ptr)->sym_ptr_ptr)->flags & BSF_DYNAMIC) != 0)
+               {
+                 /* This assumes that all relocs against dynamic
+                    symbols follow all relocs against other symbols,
+                    which is what slurp_reloc_table does.  */
+                 *rel_ptr_ptr = NULL;
+                 obj_textsec (abfd)->reloc_count = i;
+                 break;
+               }
+           }
+       }
+
+      if (obj_datasec (abfd)->reloc_count > 0)
+       {
+         rel_ptr_ptr = obj_datasec (abfd)->orelocation;
+         count = obj_datasec (abfd)->reloc_count;
+         for (i = 0; i < count; i++, rel_ptr_ptr++)
+           {
+             if (((*(*rel_ptr_ptr)->sym_ptr_ptr)->flags & BSF_DYNAMIC) != 0)
+               {
+                 *rel_ptr_ptr = NULL;
+                 obj_datasec (abfd)->reloc_count = i;
+                 break;
+               }
+           }
+       }
+    }
+
   WRITE_HEADERS(abfd, execp);
 
   return true;
@@ -586,8 +649,21 @@ DEFUN (sunos4_set_sizes, (abfd),
     }
 }
 
+#ifndef MY_read_dynamic_symbols
+#define MY_read_dynamic_symbols 0
+#endif
+#ifndef MY_read_dynamic_relocs
+#define MY_read_dynamic_relocs 0
+#endif
+
 static CONST struct aout_backend_data sunos4_aout_backend = {
-  0, 1, 0, sunos4_set_sizes, 0,
+  0,                           /* zmagic files are not contiguous */
+  1,                           /* text includes header */
+  0,                           /* default text vma */
+  sunos4_set_sizes,
+  0,                           /* header is counted in zmagic text */
+  MY_read_dynamic_symbols,
+  MY_read_dynamic_relocs
 };
 \f
 #define        MY_core_file_failing_command    sunos4_core_file_failing_command
index b8040cbc06db28703bf51824a9bc52470e0f512e..03665907a4239ae1c8ee292ef36decaf75e91ba9 100644 (file)
@@ -134,6 +134,12 @@ DESCRIPTION
 #include "aout/stab_gnu.h"
 #include "aout/ar.h"
 
+static boolean translate_symbol_table PARAMS ((bfd *, aout_symbol_type *,
+                                              struct external_nlist *,
+                                              bfd_size_type, char *,
+                                              bfd_size_type,
+                                              boolean dynamic));
+
 /*
 SUBSECTION
        Relocations
@@ -430,12 +436,17 @@ DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
   obj_datasec (abfd)->_raw_size = execp->a_data;
   obj_bsssec (abfd)->_raw_size = execp->a_bss;
 
-  obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
-       (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) :
-       (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
-  obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
-       (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) :
-       (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
+  /* If this object is dynamically linked, we assume that both
+     sections have relocs.  This does no real harm, even though it may
+     not be true.  */
+  obj_textsec (abfd)->flags =
+    (execp->a_trsize != 0 || (abfd->flags & DYNAMIC) != 0
+     ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
+     : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
+  obj_datasec (abfd)->flags =
+    (execp->a_drsize != 0 || (abfd->flags & DYNAMIC) != 0
+     ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
+     : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
   obj_bsssec (abfd)->flags = SEC_ALLOC;
 
 #ifdef THIS_IS_ONLY_DOCUMENTATION
@@ -1273,7 +1284,7 @@ DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
            {
              cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
            }
-         else
+         else if (! sym_is_undefined (cache_ptr))
            {
              cache_ptr->symbol.flags = BSF_LOCAL;
            }
@@ -1366,9 +1377,6 @@ DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
 \f
 /* Native-level interface to symbols. */
 
-/* We read the symbols into a buffer, which is discarded when this
-function exits.  We read the strings into a buffer large enough to
-hold them all plus all the cached symbol entries. */
 
 asymbol *
 DEFUN(NAME(aout,make_empty_symbol),(abfd),
@@ -1381,6 +1389,51 @@ DEFUN(NAME(aout,make_empty_symbol),(abfd),
   return &new->symbol;
 }
 
+/* Translate a set of internal symbols into external symbols.  */
+
+static boolean
+translate_symbol_table (abfd, in, ext, count, str, strsize, dynamic)
+     bfd *abfd;
+     aout_symbol_type *in;
+     struct external_nlist *ext;
+     bfd_size_type count;
+     char *str;
+     bfd_size_type strsize;
+     boolean dynamic;
+{
+  struct external_nlist *ext_end;
+
+  ext_end = ext + count;
+  for (; ext < ext_end; ext++, in++)
+    {
+      bfd_vma x;
+
+      x = GET_WORD (abfd, ext->e_strx);
+      in->symbol.the_bfd = abfd;
+      if (x < strsize)
+       in->symbol.name = str + x;
+      else
+       return false;
+
+      in->symbol.value = GET_SWORD (abfd,  ext->e_value);
+      in->desc = bfd_h_get_16 (abfd, ext->e_desc);
+      in->other = bfd_h_get_8 (abfd, ext->e_other);
+      in->type = bfd_h_get_8 (abfd,  ext->e_type);
+      in->symbol.udata = 0;
+
+      translate_from_native_sym_flags (ext, in, abfd);
+
+      if (dynamic)
+       in->symbol.flags |= BSF_DYNAMIC;
+    }
+
+  return true;
+}
+
+/* We read the symbols into a buffer, which is discarded when this
+   function exits.  We read the strings into a buffer large enough to
+   hold them all plus all the cached symbol entries. */
+
 boolean
 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
       bfd *abfd)
@@ -1391,6 +1444,10 @@ DEFUN(NAME(aout,slurp_symbol_table),(abfd),
   struct external_nlist *syms;
   char *strings;
   aout_symbol_type *cached;
+  bfd_size_type dynsym_count = 0;
+  struct external_nlist *dynsyms = NULL;
+  char *dynstrs = NULL;
+  bfd_size_type dynstr_size;
 
   /* If there's no work to be done, don't do any */
   if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
@@ -1406,12 +1463,24 @@ DEFUN(NAME(aout,slurp_symbol_table),(abfd),
     return false;
   string_size = GET_WORD (abfd, string_chars);
 
-  strings =(char *) bfd_alloc(abfd, string_size + 1);
-  cached = (aout_symbol_type *)
-    bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
+  /* If this is a dynamic object, see if we can get the dynamic symbol
+     table.  */
+  if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0
+      && aout_backend_info (abfd)->read_dynamic_symbols)
+    {
+      dynsym_count = ((*aout_backend_info (abfd)->read_dynamic_symbols)
+                     (abfd, &dynsyms, &dynstrs, &dynstr_size));
+      if (dynsym_count == (bfd_size_type) -1)
+       return false;
+    }
 
-  /* malloc this, so we can free it if simply. The symbol caching
-     might want to allocate onto the bfd's obstack  */
+  strings = (char *) bfd_alloc (abfd, string_size + 1);
+  cached = ((aout_symbol_type *)
+           bfd_zalloc (abfd,
+                       ((bfd_get_symcount (abfd) + dynsym_count)
+                        * sizeof (aout_symbol_type))));
+
+  /* Don't allocate on the obstack, so we can free it easily.  */
   syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
   bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
   if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size)
@@ -1434,32 +1503,18 @@ DEFUN(NAME(aout,slurp_symbol_table),(abfd),
   strings[string_size] = 0; /* Just in case. */
 
   /* OK, now walk the new symtable, cacheing symbol properties */
-  {
-    register struct external_nlist *sym_pointer;
-    register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
-    register aout_symbol_type *cache_ptr = cached;
+  if (! translate_symbol_table (abfd, cached, syms, bfd_get_symcount (abfd),
+                               strings, string_size, false))
+    goto bailout;
+  if (dynsym_count > 0)
+    {
+      if (! translate_symbol_table (abfd, cached + bfd_get_symcount (abfd),
+                                   dynsyms, dynsym_count, dynstrs,
+                                   dynstr_size, true))
+       goto bailout;
 
-    /* Run through table and copy values */
-    for (sym_pointer = syms, cache_ptr = cached;
-        sym_pointer < sym_end; sym_pointer ++, cache_ptr++)
-      {
-       long x = GET_WORD(abfd, sym_pointer->e_strx);
-       cache_ptr->symbol.the_bfd = abfd;
-       if (x == 0)
-         cache_ptr->symbol.name = "";
-       else if (x >= 0 && x < string_size)
-         cache_ptr->symbol.name = x + strings;
-       else
-         goto bailout;
-
-       cache_ptr->symbol.value = GET_SWORD(abfd,  sym_pointer->e_value);
-       cache_ptr->desc = bfd_h_get_16(abfd, sym_pointer->e_desc);
-       cache_ptr->other = bfd_h_get_8(abfd, sym_pointer->e_other);
-       cache_ptr->type = bfd_h_get_8(abfd,  sym_pointer->e_type);
-       cache_ptr->symbol.udata = 0;
-       translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
-      }
-  }
+      bfd_get_symcount (abfd) += dynsym_count;
+    }
 
   obj_aout_symbols (abfd) =  cached;
   free((PTR)syms);
@@ -2233,71 +2288,129 @@ DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
   unsigned int count;
   bfd_size_type reloc_size;
   PTR relocs;
+  bfd_size_type dynrel_count = 0;
+  PTR dynrels = NULL;
   arelent *reloc_cache;
   size_t each_size;
+  unsigned int counter = 0;
+  arelent *cache_ptr;
 
   if (asect->relocation) return true;
 
   if (asect->flags & SEC_CONSTRUCTOR) return true;
 
-  if (asect == obj_datasec (abfd)) {
+  if (asect == obj_datasec (abfd))
     reloc_size = exec_hdr(abfd)->a_drsize;
-  } else if (asect == obj_textsec (abfd)) {
+  else if (asect == obj_textsec (abfd))
     reloc_size = exec_hdr(abfd)->a_trsize;
-  } else {
-    bfd_error = invalid_operation;
-    return false;
-  }
+  else
+    {
+      bfd_error = invalid_operation;
+      return false;
+    }
+
+  if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0
+      && aout_backend_info (abfd)->read_dynamic_relocs)
+    {
+      dynrel_count = ((*aout_backend_info (abfd)->read_dynamic_relocs)
+                     (abfd, &dynrels));
+      if (dynrel_count == (bfd_size_type) -1)
+       return false;
+    }
 
   bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
   each_size = obj_reloc_entry_size (abfd);
 
   count = reloc_size / each_size;
 
-
-  reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
-                                                      (arelent)));
-  if (!reloc_cache) {
-nomem:
-    bfd_error = no_memory;
-    return false;
-  }
+  reloc_cache = ((arelent *)
+                bfd_zalloc (abfd,
+                            (size_t) ((count + dynrel_count)
+                                      * sizeof (arelent))));
+  if (!reloc_cache)
+    {
+    nomem:
+      bfd_error = no_memory;
+      return false;
+    }
 
   relocs = (PTR) bfd_alloc (abfd, reloc_size);
-  if (!relocs) {
-    bfd_release (abfd, reloc_cache);
-    goto nomem;
-  }
+  if (!relocs)
+    {
+      bfd_release (abfd, reloc_cache);
+      goto nomem;
+    }
 
-  if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
-    bfd_release (abfd, relocs);
-    bfd_release (abfd, reloc_cache);
-    bfd_error = system_call_error;
-    return false;
-  }
+  if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
+    {
+      bfd_release (abfd, relocs);
+      bfd_release (abfd, reloc_cache);
+      bfd_error = system_call_error;
+      return false;
+    }
 
-  if (each_size == RELOC_EXT_SIZE) {
-    register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
-    unsigned int counter = 0;
-    arelent *cache_ptr = reloc_cache;
+  cache_ptr = reloc_cache;
+  if (each_size == RELOC_EXT_SIZE)
+    {
+      register struct reloc_ext_external *rptr =
+       (struct reloc_ext_external *) relocs;
 
-    for (; counter < count; counter++, rptr++, cache_ptr++) {
-      NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
+      for (; counter < count; counter++, rptr++, cache_ptr++)
+       NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols);
     }
-  } else {
-    register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
-    unsigned int counter = 0;
-    arelent *cache_ptr = reloc_cache;
+  else
+    {
+      register struct reloc_std_external *rptr
+       = (struct reloc_std_external *) relocs;
 
-    for (; counter < count; counter++, rptr++, cache_ptr++) {
-      NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
+      for (; counter < count; counter++, rptr++, cache_ptr++)
+       NAME(aout,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols);
     }
 
-  }
+  if (dynrel_count > 0)
+    {
+      asymbol **dynsyms;
+
+      /* The dynamic symbols are at the end of the symbol table.  */
+      for (dynsyms = symbols;
+          *dynsyms != NULL && ((*dynsyms)->flags & BSF_DYNAMIC) == 0;
+          ++dynsyms)
+       ;
+
+      /* Swap in the dynamic relocs.  These relocs may be for either
+        section, so we must discard ones we don't want.  */
+      counter = 0;
+      if (each_size == RELOC_EXT_SIZE)
+       {
+         register struct reloc_ext_external *rptr
+           = (struct reloc_ext_external *) dynrels;
+
+         for (; counter < dynrel_count; counter++, rptr++, cache_ptr++)
+           {
+             NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, dynsyms);
+             cache_ptr->address -= bfd_get_section_vma (abfd, asect);
+             if (cache_ptr->address >= bfd_section_size (abfd, asect))
+               --cache_ptr;
+           }
+       }
+      else
+       {
+         register struct reloc_std_external *rptr
+           = (struct reloc_std_external *) dynrels;
+
+         for (; counter < dynrel_count; counter++, rptr++, cache_ptr++)
+           {
+             NAME(aout,swap_std_reloc_in) (abfd, rptr, cache_ptr, dynsyms);
+             cache_ptr->address -= bfd_get_section_vma (abfd, asect);
+             if (cache_ptr->address >= bfd_section_size (abfd, asect))
+               --cache_ptr;
+           }
+       }
+    }
 
   bfd_release (abfd,relocs);
   asect->relocation = reloc_cache;
-  asect->reloc_count = count;
+  asect->reloc_count = cache_ptr - reloc_cache;
   return true;
 }
 
@@ -2393,6 +2506,8 @@ DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
      bfd *abfd AND
      sec_ptr asect)
 {
+  bfd_size_type dynrel_count = 0;
+
   if (bfd_get_format (abfd) != bfd_object) {
     bfd_error = invalid_operation;
     return 0;
@@ -2401,16 +2516,26 @@ DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
     return (sizeof (arelent *) * (asect->reloc_count+1));
   }
 
+  if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0
+      && aout_backend_info (abfd)->read_dynamic_relocs)
+    {
+      PTR dynrels;
+
+      dynrel_count = ((*aout_backend_info (abfd)->read_dynamic_relocs)
+                     (abfd, &dynrels));
+      if (dynrel_count == (bfd_size_type) -1)
+       return 0;
+    }
 
   if (asect == obj_datasec (abfd))
     return (sizeof (arelent *) *
-            ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
-             +1));
+           ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
+            + dynrel_count + 1));
 
   if (asect == obj_textsec (abfd))
     return (sizeof (arelent *) *
-            ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
-             +1));
+           ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
+            + dynrel_count + 1));
 
   bfd_error = invalid_operation;
   return 0;
index 06de0c6dd588048b2dc718aa14e8161378f04507..2e91a1d8db15ae07b2499ba342cbae2bd4e29e93 100644 (file)
@@ -1637,6 +1637,9 @@ typedef struct symbol_cache_entry
           for ELF STT_FILE symbols.  */
 #define BSF_FILE          0x4000
 
+        /* Symbol is from dynamic linking information.  */
+#define BSF_DYNAMIC       0x8000
+
   flagword flags;
 
         /* A pointer to the section to which this symbol is 
index a451a48914ed5463fbb998058e9692a6e3756aa7..7f62a33ad860ae91f72901e4d89c3af79c3a3bc5 100644 (file)
-/* BFD backend for sunos binaries */
+/* BFD backend for SunOS binaries.
+   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Written by Cygnus Support.
 
-/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+This file is part of BFD, the Binary File Descriptor library.
 
-This file is part of BFD, the Binary File Diddler.
-
-BFD is free software; you can redistribute it and/or modify
+This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-BFD is distributed in the hope that it will be useful,
+This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with BFD; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/* $Id$ */
+#define ARCH 32
+#define TARGETNAME "a.out-sunos-big"
+#define MY(OP) CAT(sunos_big_,OP)
 
-#include <ansidecl.h>
-#include "sysdep.h"
 #include "bfd.h"
-#include "libbfd.h"
-
-#include "a.out.sun4.h"
-#include "a.out.gnu.h"
-#include "stab.gnu.h"
-#include "ar.h"
-#include "liba.out.h"           /* BFD a.out internal data structures */
-
-void (*bfd_error_trap)();
-
-static bfd_target *sunos4_callback ();
 
-/*SUPPRESS558*/
-/*SUPPRESS529*/
+/* Static routines defined in this file.  */
 
-bfd_target *
-sunos4_object_p (abfd)
-     bfd *abfd;
-{
-  unsigned char magicbuf[4];   /* Raw bytes of magic number from file */
-  unsigned long magic;         /* Swapped magic number */
+struct external_nlist;
 
-  bfd_error = system_call_error;
+static boolean sunos_read_dynamic_info PARAMS ((bfd *));
+static bfd_size_type MY(read_dynamic_symbols)
+     PARAMS ((bfd *, struct external_nlist **, char **, bfd_size_type *));
+static bfd_size_type MY(read_dynamic_relocs) PARAMS ((bfd *, PTR *));
 
-  if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
-      sizeof (magicbuf))
-    return 0;
-  magic = bfd_h_getlong (abfd, magicbuf);
+#define MY_read_dynamic_symbols MY(read_dynamic_symbols)
+#define MY_read_dynamic_relocs MY(read_dynamic_relocs)
 
-  if (N_BADMAG (*((struct exec *) &magic))) return 0;
+/* Include the usual a.out support.  */
+#include "aoutf1.h"
 
-  return some_aout_object_p (abfd, sunos4_callback);
-}
+/* SunOS shared library support.  We store a pointer to this structure
+   in obj_aout_dynamic_info (abfd).  */
 
-  /* Determine the size of a relocation entry, based on the architecture */
-static void
-DEFUN(choose_reloc_size,(abfd),
-bfd *abfd)
-  {
-    switch (abfd->obj_arch) {
-    case bfd_arch_sparc:
-    case bfd_arch_a29k:
-      obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
-      break;
-    default:
-      obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
-      break;
-    }
-  }
-
-/* Set parameters about this a.out file that are machine-dependent.
-   This routine is called from some_aout_object_p just before it returns.  */
-
-static bfd_target *
-sunos4_callback (abfd)
-     bfd *abfd;
+struct sunos_dynamic_info
 {
-  struct exec *execp = exec_hdr (abfd);
-
-  /* The virtual memory addresses of the sections */
-  obj_datasec (abfd)->vma = N_DATADDR(*execp);
-  obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
-  obj_textsec (abfd)->vma = N_TXTADDR(*execp);
-
-  /* The file offsets of the sections */
-  obj_textsec (abfd)->filepos = EXEC_BYTES_SIZE; /*N_TXTOFF(*execp);*/
-  obj_datasec (abfd)->filepos = N_DATOFF(*execp);
-
-  /* The file offsets of the relocation info */
-  obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
-  obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
-
-  /* The file offsets of the string table and symbol table.  */
-  obj_str_filepos (abfd) = N_STROFF (*execp);
-  obj_sym_filepos (abfd) = N_SYMOFF (*execp);
-
-
-
-  /* Determine the architecture and machine type of the object file.  */
-  switch (N_MACHTYPE (*exec_hdr (abfd))) {
-
-  case M_UNKNOWN:
-       abfd->obj_arch = bfd_arch_unknown;
-       abfd->obj_machine = 0;
-       break;
-
-  case M_68010:
-       abfd->obj_arch = bfd_arch_m68k;
-       abfd->obj_machine = 68010;
-       break;
-
-  case M_68020:
-       abfd->obj_arch = bfd_arch_m68k;
-       abfd->obj_machine = 68020;
-       break;
-
-  case M_SPARC:
-       abfd->obj_arch = bfd_arch_sparc;
-       abfd->obj_machine = 0;
-       break;
-
-  case M_386:
-       abfd->obj_arch = bfd_arch_i386;
-       abfd->obj_machine = 0;
-       break;
-
-  case M_29K:
-       abfd->obj_arch = bfd_arch_a29k;
-       abfd->obj_machine = 0;
-       break;
-
-  default:
-       abfd->obj_arch = bfd_arch_obscure;
-       abfd->obj_machine = 0;
-       break;
-  }
-
-  choose_reloc_size(abfd);
-  return abfd->xvec;
-}
+  /* Whether we found any dynamic information.  */
+  boolean valid;
+  /* Dynamic information.  */
+  struct internal_sun4_dynamic_link dyninfo;
+  /* Number of dynamic symbols.  */
+  bfd_size_type dynsym_count;
+  /* Read in nlists for dynamic symbols.  */
+  struct external_nlist *dynsym;
+  /* Read in dynamic string table.  */
+  char *dynstr;
+  /* Number of dynamic relocs.  */
+  bfd_size_type dynrel_count;
+  /* Read in dynamic relocs.  This may be reloc_std_external or
+     reloc_ext_external.  */
+  PTR dynrel;
+};
 
+/* Read in the basic dynamic information.  This locates the __DYNAMIC
+   structure and uses it to find the dynamic_link structure.  It
+   creates and saves a sunos_dynamic_info structure.  If it can't find
+   __DYNAMIC, it sets the valid field of the sunos_dynamic_info
+   structure to false to avoid doing this work again.  */
 
-boolean
-sunos4_mkobject (abfd)
+static boolean
+sunos_read_dynamic_info (abfd)
      bfd *abfd;
 {
-  char *rawptr;
-
-  bfd_error = system_call_error;
-
-  /* Use an intermediate variable for clarity */
-  rawptr = bfd_zalloc (abfd, sizeof (struct aoutdata) + sizeof (struct exec));
-
-  if (rawptr == NULL) {
-    bfd_error = no_memory;
-    return false;
-  }
-
-  set_tdata (abfd, (struct aoutdata *) rawptr);
-  exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct aoutdata));
-
-  /* For simplicity's sake we just make all the sections right here. */
-
-  obj_textsec (abfd) = (asection *)NULL;
-  obj_datasec (abfd) = (asection *)NULL;
-  obj_bsssec (abfd) = (asection *)NULL;
-  bfd_make_section (abfd, ".text");
-  bfd_make_section (abfd, ".data");
-  bfd_make_section (abfd, ".bss");
+  struct sunos_dynamic_info *info;
+  struct external_nlist dynsym;
+  char buf[sizeof "__DYNAMIC"];
+  asection *dynsec;
+  file_ptr dynoff;
+  struct external_sun4_dynamic dyninfo;
+  unsigned long dynver;
+  struct external_sun4_dynamic_link linkinfo;
+
+  if (obj_aout_dynamic_info (abfd) != (PTR) NULL)
+    return true;
+
+  info = ((struct sunos_dynamic_info *)
+         bfd_zalloc (abfd, sizeof (struct sunos_dynamic_info)));
+  info->valid = false;
+  info->dynsym = NULL;
+  info->dynstr = NULL;
+  info->dynrel = NULL;
+  obj_aout_dynamic_info (abfd) = (PTR) info;
+
+  /* We look for the __DYNAMIC symbol to locate the dynamic linking
+     information.  It should be the first symbol if it is defined.  If
+     we can't find it, don't sweat it.  */
+  if ((abfd->flags & DYNAMIC) == 0
+      || bfd_get_symcount (abfd) <= 0
+      || bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+      || (bfd_read ((PTR) &dynsym, 1, EXTERNAL_NLIST_SIZE, abfd)
+         != EXTERNAL_NLIST_SIZE)
+      || ((dynsym.e_type[0] & N_TYPE) != N_DATA
+         && (dynsym.e_type[0] & N_TYPE) != N_TEXT)
+      || bfd_seek (abfd,
+                  obj_str_filepos (abfd) + GET_WORD (abfd, dynsym.e_strx),
+                  SEEK_SET) != 0
+      || bfd_read ((PTR) buf, 1, sizeof buf, abfd) != sizeof buf
+      || buf[sizeof buf - 1] != '\0'
+      || strcmp (buf, "__DYNAMIC") != 0)
+    return true;
+
+  if ((dynsym.e_type[0] & N_TYPE) == N_DATA)
+    dynsec = obj_datasec (abfd);
+  else
+    dynsec = obj_textsec (abfd);
+  if (! bfd_get_section_contents (abfd, dynsec, (PTR) &dyninfo,
+                                 (GET_WORD (abfd, dynsym.e_value)
+                                  - bfd_get_section_vma (abfd, dynsec)),
+                                 sizeof dyninfo))
+    return true;
+
+  dynver = GET_WORD (abfd, dyninfo.ld_version);
+  if (dynver != 2 && dynver != 3)
+    return true;
+
+  dynoff = GET_WORD (abfd, dyninfo.ld);
+
+  /* dynoff is a virtual address.  It is probably always in the .data
+     section, but this code should work even if it moves.  */
+  if (dynoff < bfd_get_section_vma (abfd, obj_datasec (abfd)))
+    dynsec = obj_textsec (abfd);
+  else
+    dynsec = obj_datasec (abfd);
+  dynoff -= bfd_get_section_vma (abfd, dynsec);
+  if (dynoff < 0 || dynoff > bfd_section_size (abfd, dynsec))
+    return true;
+
+  /* This executable appears to be dynamically linked in a way that we
+     can understand.  */
+  if (! bfd_get_section_contents (abfd, dynsec, (PTR) &linkinfo, dynoff,
+                                 (bfd_size_type) sizeof linkinfo))
+    return true;
+
+  /* Swap in the dynamic link information.  */
+  info->dyninfo.ld_loaded = GET_WORD (abfd, linkinfo.ld_loaded);
+  info->dyninfo.ld_need = GET_WORD (abfd, linkinfo.ld_need);
+  info->dyninfo.ld_rules = GET_WORD (abfd, linkinfo.ld_rules);
+  info->dyninfo.ld_got = GET_WORD (abfd, linkinfo.ld_got);
+  info->dyninfo.ld_plt = GET_WORD (abfd, linkinfo.ld_plt);
+  info->dyninfo.ld_rel = GET_WORD (abfd, linkinfo.ld_rel);
+  info->dyninfo.ld_hash = GET_WORD (abfd, linkinfo.ld_hash);
+  info->dyninfo.ld_stab = GET_WORD (abfd, linkinfo.ld_stab);
+  info->dyninfo.ld_stab_hash = GET_WORD (abfd, linkinfo.ld_stab_hash);
+  info->dyninfo.ld_buckets = GET_WORD (abfd, linkinfo.ld_buckets);
+  info->dyninfo.ld_symbols = GET_WORD (abfd, linkinfo.ld_symbols);
+  info->dyninfo.ld_symb_size = GET_WORD (abfd, linkinfo.ld_symb_size);
+  info->dyninfo.ld_text = GET_WORD (abfd, linkinfo.ld_text);
+  info->dyninfo.ld_plt_sz = GET_WORD (abfd, linkinfo.ld_plt_sz);
+
+  /* The only way to get the size of the symbol information appears to
+     be to determine the distance between it and the string table.  */
+  info->dynsym_count = ((info->dyninfo.ld_symbols - info->dyninfo.ld_stab)
+                       / EXTERNAL_NLIST_SIZE);
+  BFD_ASSERT (info->dynsym_count * EXTERNAL_NLIST_SIZE
+             == info->dyninfo.ld_symbols - info->dyninfo.ld_stab);
+
+  /* Similarly, the relocs end at the hash table.  */
+  info->dynrel_count = ((info->dyninfo.ld_hash - info->dyninfo.ld_rel)
+                       / obj_reloc_entry_size (abfd));
+  BFD_ASSERT (info->dynrel_count * obj_reloc_entry_size (abfd)
+             == info->dyninfo.ld_hash - info->dyninfo.ld_rel);
+
+  info->valid = true;
 
   return true;
 }
 
-/* Keep track of machine architecture and machine type for a.out's.
-   Return the machine_type for a particular arch&machine, or M_UNKNOWN
-   if that exact arch&machine can't be represented in a.out format.
-
-   If the architecture is understood, machine type 0 (default) should
-   always be understood.  */
-
-static enum machine_type
-aout_machine_type (arch, machine)
-     enum bfd_architecture arch;
-     unsigned long machine;
-{
-  enum machine_type arch_flags;
-
-  arch_flags = M_UNKNOWN;
-
-  switch (arch) {
-  case bfd_arch_sparc:
-    if (machine == 0)  arch_flags = M_SPARC;
-    break;
-
-  case bfd_arch_m68k:
-    switch (machine) {
-    case 0:            arch_flags = M_68010; break;
-    case 68000:                arch_flags = M_UNKNOWN; break;
-    case 68010:                arch_flags = M_68010; break;
-    case 68020:                arch_flags = M_68020; break;
-    default:           arch_flags = M_UNKNOWN; break;
-    }
-    break;
-
-  case bfd_arch_i386:
-    if (machine == 0)  arch_flags = M_386;
-    break;
-
-  case bfd_arch_a29k:
-    if (machine == 0)  arch_flags = M_29K;
-    break;
-
-  default:
-    arch_flags = M_UNKNOWN;
-    break;
-  }
-  return arch_flags;
-}
-
-/* Write an object file in SunOS format.
-   Section contents have already been written.  We write the
-   file header, symbols, and relocation.  */
+/* Read in the dynamic symbols.  */
 
-boolean
-sunos4_write_object_contents (abfd)
+static bfd_size_type
+MY(read_dynamic_symbols) (abfd, syms, strs, strsize)
      bfd *abfd;
+     struct external_nlist **syms;
+     char **strs;
+     bfd_size_type *strsize;
 {
-  size_t data_pad = 0;
-  unsigned char exec_bytes[EXEC_BYTES_SIZE];
-  struct exec *execp = exec_hdr (abfd);
+  struct sunos_dynamic_info *info;
 
-
-
-  execp->a_text = obj_textsec (abfd)->size;
-
-  /* Magic number, maestro, please!  */
-  switch (bfd_get_architecture(abfd)) {
-  case bfd_arch_m68k:
-    switch (bfd_get_machine(abfd)) {
-    case 68010:
-      N_SET_MACHTYPE(*execp, M_68010);
-      break;
-    default:
-    case 68020:
-      N_SET_MACHTYPE(*execp, M_68020);
-      break;
+  if (obj_aout_dynamic_info (abfd) == (PTR) NULL)
+    {
+      if (! sunos_read_dynamic_info (abfd))
+         return (bfd_size_type) -1;
     }
-    break;
-  case bfd_arch_sparc:
-    N_SET_MACHTYPE(*execp, M_SPARC);
-    break;
-  case bfd_arch_i386:
-    N_SET_MACHTYPE(*execp, M_386);
-    break;
-  case bfd_arch_a29k:
-    N_SET_MACHTYPE(*execp, M_29K);
-    break;
-  default:
-    N_SET_MACHTYPE(*execp, M_UNKNOWN);
-  }
 
-  choose_reloc_size(abfd);
+  info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
+  if (! info->valid || info->dynsym_count == 0)
+    return 0;
 
-  N_SET_MAGIC (*execp, OMAGIC);
-  if (abfd->flags & D_PAGED) {
-    /* This is not strictly true, but will probably do for the default
-       case.  FIXME.  
-       */
+  if (info->dynsym == (struct external_nlist *) NULL)
+    {
+      info->dynsym = ((struct external_nlist *)
+                     bfd_alloc (abfd,
+                                (info->dynsym_count
+                                 * EXTERNAL_NLIST_SIZE)));
+      info->dynstr = (char *) bfd_alloc (abfd, info->dyninfo.ld_symb_size);
+      if (bfd_seek (abfd, info->dyninfo.ld_stab, SEEK_SET) != 0
+         || (bfd_read ((PTR) info->dynsym, info->dynsym_count,
+                       EXTERNAL_NLIST_SIZE, abfd)
+             != info->dynsym_count * EXTERNAL_NLIST_SIZE)
+         || bfd_seek (abfd, info->dyninfo.ld_symbols, SEEK_SET) != 0
+         || (bfd_read ((PTR) info->dynstr, 1, info->dyninfo.ld_symb_size,
+                       abfd)
+             != info->dyninfo.ld_symb_size))
+       return (bfd_size_type) -1;
+    }
 
-    execp->a_text = obj_textsec (abfd)->size + EXEC_BYTES_SIZE;
-    N_SET_MAGIC (*execp, ZMAGIC);
-  } else if (abfd->flags & WP_TEXT) {
-    N_SET_MAGIC (*execp, NMAGIC);
-  }
-  N_SET_FLAGS (*execp, 0x1);   /* copied from ld.c; who the hell knows? */
+  *syms = info->dynsym;
+  *strs = info->dynstr;
+  *strsize = info->dyninfo.ld_symb_size;
 
-  if (abfd->flags & D_PAGED) 
+#ifdef CHECK_DYNAMIC_HASH
+  /* Check my understanding of the dynamic hash table by making sure
+     that each symbol can be located in the hash table.  */
+  {
+    bfd_size_type table_size;
+    bfd_byte *table;
+    bfd_size_type i;
+
+    if (info->dyninfo.ld_buckets > info->dynsym_count)
+      abort ();
+    table_size = info->dyninfo.ld_stab - info->dyninfo.ld_hash;
+    table = (bfd_byte *) alloca (table_size);
+    if (bfd_seek (abfd, info->dyninfo.ld_hash, SEEK_SET) != 0
+       || bfd_read ((PTR) table, 1, table_size, abfd) != table_size)
+      abort ();
+    for (i = 0; i < info->dynsym_count; i++)
       {
-       data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
-                   & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
-
-       if (data_pad > obj_bsssec(abfd)->size)
-         execp->a_bss = 0;
-       else 
-         execp->a_bss = obj_bsssec(abfd)->size - data_pad;
-       execp->a_data = obj_datasec(abfd)->size + data_pad;
-
+       unsigned char *name;
+       unsigned long hash;
+
+       name = ((unsigned char *) info->dynstr
+               + GET_WORD (abfd, info->dynsym[i].e_strx));
+       hash = 0;
+       while (*name != '\0')
+         hash = (hash << 1) + *name++;
+       hash &= 0x7fffffff;
+       hash %= info->dyninfo.ld_buckets;
+       while (GET_WORD (abfd, table + 8 * hash) != i)
+         {
+           hash = GET_WORD (abfd, table + 8 * hash + 4);
+           if (hash == 0 || hash >= table_size / 8)
+             abort ();
+         }
       }
-  else {
-    execp->a_data = obj_datasec (abfd)->size;
-    execp->a_bss = obj_bsssec (abfd)->size;
   }
+#endif /* CHECK_DYNAMIC_HASH */
 
-  execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
-  execp->a_entry = bfd_get_start_address (abfd);
-
-
-
-
-  execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
-                    obj_reloc_entry_size (abfd));
-                      
-  execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
-                    obj_reloc_entry_size (abfd));
-
-  bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
-
-  bfd_seek (abfd, 0L, false);
-  bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
-
-  /* Now write out reloc info, followed by syms and strings */
-
-  if (bfd_get_symcount (abfd) != 0) 
-    {
-      bfd_seek (abfd,
-               (long)(N_SYMOFF(*execp)), false);
-
-      aout_write_syms (abfd);
-
-      bfd_seek (abfd,  (long)(N_TRELOFF(*execp)), false);
-
-      if (!aout_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
-      bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false);
-
-      if (!aout_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
-    }
-  return true;
+  return info->dynsym_count;
 }
-\f
-/* core files */
-
-#define CORE_MAGIC 0x080456
-#define CORE_NAMELEN 16
-
-/* The core structure is taken from the Sun documentation.
-   Unfortunately, they don't document the FPA structure, or at least I
-   can't find it easily.  Fortunately the core header contains its own
-   length.  So this shouldn't cause problems, except for c_ucode, which
-   so far we don't use but is easy to find with a little arithmetic. */
-
-/* But the reg structure can be gotten from the SPARC processor handbook.
-   This really should be in a GNU include file though so that gdb can use
-   the same info. */
-struct regs {
-  int r_psr;
-  int r_pc;
-  int r_npc;
-  int r_y;
-  int r_g1;
-  int r_g2;
-  int r_g3;
-  int r_g4;
-  int r_g5;
-  int r_g6;
-  int r_g7;
-  int r_o0;
-  int r_o1;
-  int r_o2;
-  int r_o3;
-  int r_o4;
-  int r_o5;
-  int r_o6;
-  int r_o7;
-};
-
-/* Taken from Sun documentation: */
-
-/* FIXME:  It's worse than we expect.  This struct contains TWO substructs
-   neither of whose size we know, WITH STUFF IN BETWEEN THEM!  We can't
-   even portably access the stuff in between!  */
-
-struct core {
-  int c_magic;                 /* Corefile magic number */
-  int c_len;                   /* Sizeof (struct core) */
-  struct regs c_regs;          /* General purpose registers -- MACHDEP SIZE */
-  struct exec c_aouthdr;       /* A.out header */
-  int c_signo;                 /* Killing signal, if any */
-  int c_tsize;                 /* Text size (bytes) */
-  int c_dsize;                 /* Data size (bytes) */
-  int c_ssize;                 /* Stack size (bytes) */
-  char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
-  double fp_stuff[1];          /* external FPU state (size unknown by us) */
-               /* The type "double" is critical here, for alignment.
-                  SunOS declares a struct here, but the struct's alignment
-                  is double since it contains doubles.  */
-  int c_ucode;                 /* Exception no. from u_code */
-               /* (this member is not accessible by name since we don't
-                   portably know the size of fp_stuff.) */
-};
 
-/* Supposedly the user stack grows downward from the bottom of kernel memory.
-   Presuming that this remains true, this definition will work. */
-#define USRSTACK (-(128*1024*1024))
-
-PROTO (static void, swapcore, (bfd *abfd, struct core *core));
-
-/* need this cast b/c ptr is really void * */
-#define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
-#define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
-#define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
-#define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
-#define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
-
-/* These are stored in the bfd's tdata */
-struct suncordata {
-  struct core *hdr;             /* core file header */
-  asection *data_section;
-  asection *stack_section;
-  asection *reg_section;
-  asection *reg2_section;
-};
+/* Read in the dynamic relocs for a section.  */
 
-bfd_target *
-sunos4_core_file_p (abfd)
+static bfd_size_type
+MY(read_dynamic_relocs) (abfd, relocs)
      bfd *abfd;
+     PTR *relocs;
 {
-  unsigned char longbuf[4];    /* Raw bytes of various header fields */
-  int core_size;
-  int core_mag;
-  struct core *core;
-  char *rawptr;
-
-  bfd_error = system_call_error;
-
-  if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
-        sizeof (longbuf))
-    return 0;
-  core_mag = bfd_h_getlong (abfd, longbuf);
+  struct sunos_dynamic_info *info;
 
-  if (core_mag != CORE_MAGIC) return 0;
-
-  /* SunOS core headers can vary in length; second word is size; */
-  if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
-        sizeof (longbuf))
-    return 0;
-  core_size = bfd_h_getlong (abfd, longbuf);
-  /* Sanity check */
-  if (core_size > 20000)
-    return 0;
-
-  if (bfd_seek (abfd, 0L, false) < 0) return 0;
-
-  rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
-  if (rawptr == NULL) {
-    bfd_error = no_memory;
-    return 0;
-  }
-
-  core = (struct core *) (rawptr + sizeof (struct suncordata));
+  if (obj_aout_dynamic_info (abfd) == (PTR) NULL)
+    {
+      if (! sunos_read_dynamic_info (abfd))
+         return (bfd_size_type) -1;
+    }
 
-  if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
-    bfd_error = system_call_error;
-    bfd_release (abfd, rawptr);
+  info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
+  if (! info->valid || info->dynrel_count == 0)
     return 0;
-  }
 
-  swapcore (abfd, core);
-  set_tdata (abfd, ((struct suncordata *) rawptr));
-  core_hdr (abfd) = core;
-
-  /* create the sections.  This is raunchy, but bfd_close wants to reclaim
-     them */
-  core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
-  if (core_stacksec (abfd) == NULL) {
-loser:
-    bfd_error = no_memory;
-    bfd_release (abfd, rawptr);
-    return 0;
-  }
-  core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
-  if (core_datasec (abfd) == NULL) {
-loser1:
-    bfd_release (abfd, core_stacksec (abfd));
-    goto loser;
-  }
-  core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
-  if (core_regsec (abfd) == NULL) {
-loser2:
-    bfd_release (abfd, core_datasec (abfd));
-    goto loser1;
-  }
-  core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
-  if (core_reg2sec (abfd) == NULL) {
-    bfd_release (abfd, core_regsec (abfd));
-    goto loser2;
-  }
-
-  core_stacksec (abfd)->name = ".stack";
-  core_datasec (abfd)->name = ".data";
-  core_regsec (abfd)->name = ".reg";
-  core_reg2sec (abfd)->name = ".reg2";
-
-  core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
-  core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
-  core_regsec (abfd)->flags = SEC_ALLOC;
-  core_reg2sec (abfd)->flags = SEC_ALLOC;
-
-  core_stacksec (abfd)->size = core->c_ssize;
-  core_datasec (abfd)->size = core->c_dsize;
-  core_regsec (abfd)->size = (sizeof core->c_regs);
-  /* Float regs take up end of struct, except c_ucode.  */
-  core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
-                             (file_ptr)(((struct core *)0)->fp_stuff);
-
-  core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
-  core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
-  core_regsec (abfd)->vma = -1;
-  core_reg2sec (abfd)->vma = -1;
-
-  core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
-  core_datasec (abfd)->filepos = core->c_len;
-                        /* In file header: */
-  core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
-  core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
-
-  /* Align to word at least */
-  core_stacksec (abfd)->alignment_power = 2;
-  core_datasec (abfd)->alignment_power = 2;
-  core_regsec (abfd)->alignment_power = 2;
-  core_reg2sec (abfd)->alignment_power = 2;
-
-  abfd->sections = core_stacksec (abfd);
-  core_stacksec (abfd)->next = core_datasec (abfd);
-  core_datasec (abfd)->next = core_regsec (abfd);
-  core_regsec (abfd)->next = core_reg2sec (abfd);
-
-  abfd->section_count = 4;
-
-  return abfd->xvec;
-}
-
-char *
-sunos4_core_file_failing_command (abfd)
-     bfd *abfd;
-{
-  return core_hdr (abfd)->c_cmdname;
-}
-
-int
-sunos4_core_file_failing_signal (abfd)
-     bfd *abfd;
-{
-  return core_hdr (abfd)->c_signo;
-}
-
-boolean
-sunos4_core_file_matches_executable_p  (core_bfd, exec_bfd)
-     bfd *core_bfd, *exec_bfd;
-{
-  if (core_bfd->xvec != exec_bfd->xvec) {
-    bfd_error = system_call_error;
-    return false;
-  }
+  if (info->dynrel == (struct external_nlist *) NULL)
+    {
+      info->dynrel = (PTR) bfd_alloc (abfd,
+                                     (info->dynrel_count
+                                      * obj_reloc_entry_size (abfd)));
+      if (bfd_seek (abfd, info->dyninfo.ld_rel, SEEK_SET) != 0
+         || (bfd_read ((PTR) info->dynrel, info->dynrel_count,
+                       obj_reloc_entry_size (abfd), abfd)
+             != info->dynrel_count * obj_reloc_entry_size (abfd)))
+       return (bfd_size_type) -1;
+    }
 
-  return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
-                sizeof (struct exec)) == 0) ? true : false;
-}
+  *relocs = info->dynrel;
 
-/* byte-swap core structure */
-/* FIXME, this needs more work to swap IN a core struct from raw bytes */
-static void
-swapcore (abfd, core)
-     bfd *abfd;
-     struct core *core;
-{
-  unsigned char exec_bytes[EXEC_BYTES_SIZE];
-
-  core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic);
-  core->c_len   = bfd_h_getlong (abfd, (unsigned char *)&core->c_len  );
-  /* Leave integer registers in target byte order.  */
-  bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE);
-  bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr);
-  core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo);
-  core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize);
-  core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize);
-  core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize);
-  /* Leave FP registers in target byte order.  */
-  /* Leave "c_ucode" unswapped for now, since we can't find it easily.  */
+  return info->dynrel_count;
 }
-\f
-/* We use BFD generic archive files.  */
-#define        aout_openr_next_archived_file   bfd_generic_openr_next_archived_file
-#define        aout_generic_stat_arch_elt      bfd_generic_stat_arch_elt
-#define        aout_slurp_armap                bfd_slurp_bsd_armap
-#define        aout_slurp_extended_name_table  bfd_true
-#define        aout_write_armap                bsd_write_armap
-#define        aout_truncate_arname            bfd_bsd_truncate_arname
-
-/* We use our own core file format.  */
-#define        aout_core_file_failing_command  sunos4_core_file_failing_command
-#define        aout_core_file_failing_signal   sunos4_core_file_failing_signal
-#define        aout_core_file_matches_executable_p     \
-                                       sunos4_core_file_matches_executable_p
-
-/* We implement these routines ourselves, rather than using the generic
-   a.out versions.  */
-#define        aout_write_object_contents      sunos4_write_object_contents
-
-bfd_target sunos_big_vec =
-{
-  "a.out-sunos-big",           /* name */
-  bfd_target_aout_flavour_enum,
-  true,                                /* target byte order */
-  true,                                /* target headers byte order */
-  (HAS_RELOC | EXEC_P |                /* object flags */
-   HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
-  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
-  ' ',                         /* ar_pad_char */
-  16,                          /* ar_max_namelen */
-  _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
-  _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
-
-    {_bfd_dummy_target, sunos4_object_p,
-       bfd_generic_archive_p, sunos4_core_file_p},
-    {bfd_false, sunos4_mkobject,
-       _bfd_generic_mkarchive, bfd_false},
-    {bfd_false, sunos4_write_object_contents,  /* bfd_write_contents */
-       _bfd_write_archive_contents, bfd_false},
-
-  JUMP_TABLE(aout)
-};
index 021332f5061826298d15603bfa7c8dd795862ddf..cb799c65014c68f24624181528d7a3780f436fac 100644 (file)
@@ -249,6 +249,9 @@ CODE_FRAGMENT
 .         for ELF STT_FILE symbols.  *}
 .#define BSF_FILE          0x4000
 .
+.      {* Symbol is from dynamic linking information.  *}
+.#define BSF_DYNAMIC      0x8000
+.
 .  flagword flags;
 .
 .      {* A pointer to the section to which this symbol is 
@@ -352,10 +355,11 @@ DESCRIPTION
        stream @var{file}.
 */
 void
-DEFUN(bfd_print_symbol_vandf,(file, symbol),
-FILE *file AND
+DEFUN(bfd_print_symbol_vandf,(arg, symbol),
+PTR arg AND
 asymbol *symbol)
 {
+  FILE *file = (FILE *) arg;
   flagword type = symbol->flags;
   if (symbol->section != (asection *)NULL)
       {
@@ -365,6 +369,9 @@ asymbol *symbol)
       {
        fprintf_vma(file, symbol->value);
       }
+
+  /* This presumes that a symbol can not be both BSF_DEBUGGING and
+     BSF_DYNAMIC.  */
   fprintf(file," %c%c%c%c%c%c%c",
          (type & BSF_LOCAL)  ? 'l':' ',
          (type & BSF_GLOBAL) ? 'g' : ' ',
@@ -372,8 +379,8 @@ asymbol *symbol)
          (type & BSF_CONSTRUCTOR) ? 'C' : ' ',
          (type & BSF_WARNING) ? 'W' : ' ',
          (type & BSF_INDIRECT) ? 'I' : ' ',
-         (type & BSF_DEBUGGING) ? 'd' :' ');
-
+         (type & BSF_DEBUGGING) ? 'd'
+         : (type & BSF_DYNAMIC) ? 'D' : ' ');
 }