This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Better (MIPS) ELF64 archive support


Hi All,

this patch moves the existing code for (MIPS) ELF64 archive support
in it's own file (and make it's compilation dependent of BFD64
support). This allows tools like 'ar' which have no way to
pre-select an architecture to open ELF64 archives.


Thiemo


2001-12-04  Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>

	/bfd/ChangeLog
	* Makefile.am: split up BFD_LIBS like statements in BFD32_LIBS and
	BFD64_LIBS, make the latter depending on the availability of BFD64.
	Add archive64.c source file.
	* archive64.c: New file implementing bfd_elf64_archive_slurp_armap
	and bfd_elf64_archive_write_armap, code from elf64-mips.c
	* archive.c (bfd_slurp_armap): Add ELF64 archive support.
	* config.bfd (mips*-*-irix6*): Allow with BFD64 only.
	(mips64*el-*-linux*): Likewise.
	(mips*el-*-linux*): Likewise. Reorder entries.
	* configure.in (bfd_libs): Define in dependency of BFD64 and
	AC_SUBST it.
	* elf64-mips.c (mips_elf64_slurp_armap): Remove, use
	bfd_elf64_archive_slurp_armap instead.
	(mips_elf64_write_armap): Remove, use bfd_elf64_archive_write_armap
	instead.


diff -BurpN source-orig/bfd/Makefile.am source/bfd/Makefile.am
--- source-orig/bfd/Makefile.am	Thu Nov  8 20:52:33 2001
+++ source/bfd/Makefile.am	Mon Dec  3 13:01:29 2001
@@ -25,20 +25,24 @@ BFD_H = bfd.h
 # for the debugger, so if you are downloading things as S-records you
 # need two copies of the executable, one to download and one for the
 # debugger).
-BFD_LIBS = \
+BFD32_LIBS = \
 	archive.lo archures.lo bfd.lo cache.lo coffgen.lo corefile.lo \
 	format.lo init.lo libbfd.lo opncls.lo reloc.lo \
 	section.lo syms.lo targets.lo hash.lo linker.lo \
 	srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo \
 	merge.lo dwarf2.lo
 
-BFD_LIBS_CFILES = \
+BFD64_LIBS = archive64.lo
+
+BFD32_LIBS_CFILES = \
 	archive.c archures.c bfd.c cache.c coffgen.c corefile.c \
 	format.c init.c libbfd.c opncls.c reloc.c \
 	section.c syms.c targets.c hash.c linker.c \
 	srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c \
 	merge.c dwarf2.c
 
+BFD64_LIBS_CFILES = archive64.c
+
 # This list is alphabetized to make it easier to keep in sync
 # with the decls and initializer in archures.c.
 ALL_MACHINES = \
@@ -486,6 +490,7 @@ OPTIONAL_BACKENDS_CFILES = \
 WORDSIZE = @wordsize@
 ALL_BACKENDS = @all_backends@
 BFD_BACKENDS = @bfd_backends@
+BFD_LIBS = @bfd_libs@
 BFD_MACHINES = @bfd_machines@
 TDEFAULTS = @tdefaults@
 
@@ -493,7 +498,8 @@ INCLUDES = -D_GNU_SOURCE @HDEFINES@ @COR
 
 # C source files that correspond to .o's.
 SOURCE_CFILES = \
-	$(BFD_LIBS_CFILES) \
+	$(BFD32_LIBS_CFILES) \
+	$(BFD64_LIBS_CFILES) \
 	$(ALL_MACHINES_CFILES) \
 	$(BFD32_BACKENDS_CFILES) \
 	$(BFD64_BACKENDS_CFILES) \
@@ -564,7 +570,7 @@ stamp-ofiles: Makefile
 
 ofiles: stamp-ofiles ; @true
 
-libbfd_la_SOURCES = $(BFD_LIBS_CFILES)
+libbfd_la_SOURCES = $(BFD32_LIBS_CFILES) $(BFD64_LIBS_CFILES)
 libbfd_la_DEPENDENCIES = $(OFILES) ofiles
 libbfd_la_LIBADD = `cat ofiles` @WIN32LIBADD@
 libbfd_la_LDFLAGS = -release $(VERSION) @WIN32LDFLAGS@
@@ -637,7 +643,8 @@ pepigen.c : peXXigen.c
 
 BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
 LOCAL_H_DEPS= libbfd.h sysdep.h config.h
-$(BFD_LIBS) \
+$(BFD32_LIBS) \
+ $(BFD64_LIBS) \
  $(ALL_MACHINES) \
  $(BFD32_BACKENDS) \
  $(BFD64_BACKENDS) \
@@ -713,6 +720,7 @@ stmp-bfd-h: bfd-in3.h
 
 BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c section.c archures.c \
 	reloc.c syms.c bfd.c archive.c corefile.c targets.c format.c version.h
+BFD64_H_FILES = archive64.c
 LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c cache.c reloc.c archures.c elf.c
 LIBCOFF_H_FILES = libcoff-in.h coffcode.h
 
@@ -730,7 +738,7 @@ headers:
 # configured with --enable-maintainer-mode.
 
 $(srcdir)/bfd-in2.h: @MAINT@ stmp-bin2-h ; @true
-stmp-bin2-h: $(BFD_H_FILES)
+stmp-bin2-h: $(BFD_H_FILES) $(BFD64_H_FILES)
 	(cd $(docdir); $(MAKE) $(FLAGS_TO_PASS) bfd.h)
 	cp $(docdir)/bfd.h bfd-in2.h-new
 	$(SHELL) $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h
diff -BurpNX /bigdisk/src/binutils-exclude src-orig/bfd/archive.c src/bfd/archive.c
--- src-orig/bfd/archive.c	Wed Mar 14 17:01:58 2001
+++ src/bfd/archive.c	Wed Aug  1 22:12:18 2001
@@ -170,6 +170,7 @@ static char *get_extended_arelt_filename
 						  const char *name));
 static boolean do_slurp_bsd_armap PARAMS ((bfd *abfd));
 static boolean do_slurp_coff_armap PARAMS ((bfd *abfd));
+boolean bfd_elf64_archive_slurp_armap PARAMS ((bfd *abfd));
 static const char *normalize PARAMS ((bfd *, const char *file));
 static struct areltdata *bfd_ar_hdr_from_filesystem PARAMS ((bfd *abfd,
 							     const char *,
@@ -936,9 +937,13 @@ bfd_slurp_armap (abfd)
     return do_slurp_coff_armap (abfd);
   else if (!strncmp (nextname, "/SYM64/         ", 16))
     {
-      /* Irix 6 archive--must be recognized by code in elf64-mips.c.  */
+      /* 64bit ELF (Irix 6) archive.  */
+#ifdef BFD64
+      return bfd_elf64_archive_slurp_armap (abfd);
+#else
       bfd_set_error (bfd_error_wrong_format);
       return false;
+#endif
     }
 
   bfd_has_map (abfd) = false;
diff -BurpN source-orig/bfd/archive64.c source/bfd/archive64.c
--- source-orig/bfd/archive64.c	Thu Jan  1 01:00:00 1970
+++ source/bfd/archive64.c	Mon Dec  3 13:05:12 2001
@@ -0,0 +1,245 @@
+/* MIPS-specific support for 64-bit ELF
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
+   Ian Lance Taylor, Cygnus Support
+   Linker support added by Mark Mitchell, CodeSourcery, LLC.
+   <mark@codesourcery.com>
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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 2 of the License, or
+(at your option) any later version.
+
+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 this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* This file supports the 64-bit (MIPS) ELF archives.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "aout/ar.h"
+
+/* Irix 6 defines a 64bit archive map format, so that they can
+   have archives more than 4 GB in size.  */
+
+boolean bfd_elf64_archive_slurp_armap PARAMS ((bfd *));
+boolean bfd_elf64_archive_write_armap
+  PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
+
+/* Read an Irix 6 armap.  */
+
+boolean
+bfd_elf64_archive_slurp_armap (abfd)
+     bfd *abfd;
+{
+  struct artdata *ardata = bfd_ardata (abfd);
+  char nextname[17];
+  file_ptr arhdrpos;
+  bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize;
+  struct areltdata *mapdata;
+  bfd_byte int_buf[8];
+  char *stringbase;
+  bfd_byte *raw_armap = NULL;
+  carsym *carsyms;
+  bfd_size_type amt;
+
+  ardata->symdefs = NULL;
+
+  /* Get the name of the first element.  */
+  arhdrpos = bfd_tell (abfd);
+  i = bfd_bread ((PTR) nextname, (bfd_size_type) 16, abfd);
+  if (i == 0)
+    return true;
+  if (i != 16)
+    return false;
+
+  if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
+    return false;
+
+  /* Archives with traditional armaps are still permitted.  */
+  if (strncmp (nextname, "/               ", 16) == 0)
+    return bfd_slurp_armap (abfd);
+
+  if (strncmp (nextname, "/SYM64/         ", 16) != 0)
+    {
+      bfd_has_map (abfd) = false;
+      return true;
+    }
+
+  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+  if (mapdata == NULL)
+    return false;
+  parsed_size = mapdata->parsed_size;
+  bfd_release (abfd, (PTR) mapdata);
+
+  if (bfd_bread (int_buf, (bfd_size_type) 8, abfd) != 8)
+    {
+      if (bfd_get_error () != bfd_error_system_call)
+	bfd_set_error (bfd_error_malformed_archive);
+      return false;
+    }
+
+  nsymz = bfd_getb64 (int_buf);
+  stringsize = parsed_size - 8 * nsymz - 8;
+
+  carsym_size = nsymz * sizeof (carsym);
+  ptrsize = 8 * nsymz;
+
+  amt = carsym_size + stringsize + 1;
+  ardata->symdefs = (carsym *) bfd_zalloc (abfd, amt);
+  if (ardata->symdefs == NULL)
+    return false;
+  carsyms = ardata->symdefs;
+  stringbase = ((char *) ardata->symdefs) + carsym_size;
+
+  raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
+  if (raw_armap == NULL)
+    goto release_symdefs;
+
+  if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize
+      || bfd_bread (stringbase, stringsize, abfd) != stringsize)
+    {
+      if (bfd_get_error () != bfd_error_system_call)
+	bfd_set_error (bfd_error_malformed_archive);
+      goto release_raw_armap;
+    }
+
+  for (i = 0; i < nsymz; i++)
+    {
+      carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
+      carsyms->name = stringbase;
+      stringbase += strlen (stringbase) + 1;
+      ++carsyms;
+    }
+  *stringbase = '\0';
+
+  ardata->symdef_count = nsymz;
+  ardata->first_file_filepos = bfd_tell (abfd);
+  /* Pad to an even boundary if you have to.  */
+  ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
+
+  bfd_has_map (abfd) = true;
+  bfd_release (abfd, raw_armap);
+
+  return true;
+
+release_raw_armap:
+  bfd_release (abfd, raw_armap);
+release_symdefs:
+  bfd_release (abfd, ardata->symdefs);
+  return false;
+}
+
+/* Write out an Irix 6 armap.  The Irix 6 tools are supposed to be
+   able to handle ordinary ELF armaps, but at least on Irix 6.2 the
+   linker crashes.  */
+
+boolean
+bfd_elf64_archive_write_armap (arch, elength, map, symbol_count, stridx)
+     bfd *arch;
+     unsigned int elength;
+     struct orl *map;
+     unsigned int symbol_count;
+     int stridx;
+{
+  unsigned int ranlibsize = (symbol_count * 8) + 8;
+  unsigned int stringsize = stridx;
+  unsigned int mapsize = stringsize + ranlibsize;
+  file_ptr archive_member_file_ptr;
+  bfd *current = arch->archive_head;
+  unsigned int count;
+  struct ar_hdr hdr;
+  unsigned int i;
+  int padding;
+  bfd_byte buf[8];
+
+  padding = BFD_ALIGN (mapsize, 8) - mapsize;
+  mapsize += padding;
+
+  /* work out where the first object file will go in the archive */
+  archive_member_file_ptr = (mapsize
+			     + elength
+			     + sizeof (struct ar_hdr)
+			     + SARMAG);
+
+  memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
+  strcpy (hdr.ar_name, "/SYM64/");
+  sprintf (hdr.ar_size, "%-10d", (int) mapsize);
+  sprintf (hdr.ar_date, "%ld", (long) time (NULL));
+  /* This, at least, is what Intel coff sets the values to.: */
+  sprintf ((hdr.ar_uid), "%d", 0);
+  sprintf ((hdr.ar_gid), "%d", 0);
+  sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0);
+  strncpy (hdr.ar_fmag, ARFMAG, 2);
+
+  for (i = 0; i < sizeof (struct ar_hdr); i++)
+    if (((char *) (&hdr))[i] == '\0')
+      (((char *) (&hdr))[i]) = ' ';
+
+  /* Write the ar header for this item and the number of symbols */
+
+  if (bfd_bwrite ((PTR) &hdr, (bfd_size_type) sizeof (struct ar_hdr), arch)
+      != sizeof (struct ar_hdr))
+    return false;
+
+  bfd_putb64 ((bfd_vma) symbol_count, buf);
+  if (bfd_bwrite (buf, (bfd_size_type) 8, arch) != 8)
+    return false;
+
+  /* Two passes, first write the file offsets for each symbol -
+     remembering that each offset is on a two byte boundary.  */
+
+  /* Write out the file offset for the file associated with each
+     symbol, and remember to keep the offsets padded out.  */
+
+  current = arch->archive_head;
+  count = 0;
+  while (current != (bfd *) NULL && count < symbol_count)
+    {
+      /* For each symbol which is used defined in this object, write out
+	 the object file's address in the archive */
+
+      while (map[count].u.abfd == current)
+	{
+	  bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
+	  if (bfd_bwrite (buf, (bfd_size_type) 8, arch) != 8)
+	    return false;
+	  count++;
+	}
+      /* Add size of this archive entry */
+      archive_member_file_ptr += (arelt_size (current)
+				  + sizeof (struct ar_hdr));
+      /* remember about the even alignment */
+      archive_member_file_ptr += archive_member_file_ptr % 2;
+      current = current->next;
+    }
+
+  /* now write the strings themselves */
+  for (count = 0; count < symbol_count; count++)
+    {
+      size_t len = strlen (*map[count].name) + 1;
+
+      if (bfd_bwrite (*map[count].name, (bfd_size_type) len, arch) != len)
+	return false;
+    }
+
+  /* The spec says that this should be padded to an 8 byte boundary.
+     However, the Irix 6.2 tools do not appear to do this.  */
+  while (padding != 0)
+    {
+      if (bfd_bwrite ("", (bfd_size_type) 1, arch) != 1)
+	return false;
+      --padding;
+    }
+
+  return true;
+}
diff -BurpN source-orig/bfd/config.bfd source/bfd/config.bfd
--- source-orig/bfd/config.bfd	Sun Nov  4 22:40:17 2001
+++ source/bfd/config.bfd	Mon Dec  3 14:08:54 2001
@@ -642,10 +642,12 @@ case "${targ}" in
     targ_defvec=ecoff_big_vec
     targ_selvecs=ecoff_little_vec
     ;;
+#ifdef BFD64
   mips*-*-irix6*)
     targ_defvec=bfd_elf32_bigmips_vec
     targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
     ;;
+#endif
   mips*-*-irix5*)
     targ_defvec=bfd_elf32_bigmips_vec
     targ_selvecs="bfd_elf32_littlemips_vec ecoff_big_vec ecoff_little_vec"
@@ -695,17 +697,19 @@ case "${targ}" in
     targ_defvec=bfd_elf32_bigmips_vec
     targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec ecoff_big_vec ecoff_little_vec"
     ;;
+#ifdef BFD64
   mips64*el-*-linux*)
     targ_defvec=bfd_elf32_tradlittlemips_vec
     targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf64_tradbigmips_vec"
     ;;
-  mips*el-*-linux*)
-    targ_defvec=bfd_elf32_tradlittlemips_vec
-    targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf64_tradbigmips_vec ecoff_little_vec ecoff_big_vec"
-    ;;
   mips64*-*-linux*)
     targ_defvec=bfd_elf32_tradbigmips_vec
     targ_selvecs="bfd_elf32_tradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec"
+    ;;
+#endif
+  mips*el-*-linux*)
+    targ_defvec=bfd_elf32_tradlittlemips_vec
+    targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf64_tradbigmips_vec ecoff_little_vec ecoff_big_vec"
     ;;
   mips*-*-linux*)
     targ_defvec=bfd_elf32_tradbigmips_vec
diff -BurpN source-orig/bfd/configure.in source/bfd/configure.in
--- source-orig/bfd/configure.in	Thu Nov  8 20:52:33 2001
+++ source/bfd/configure.in	Mon Dec  3 12:50:44 2001
@@ -761,6 +761,7 @@ fi	# all_targets is true
 case ${host64}-${target64}-${want64} in
   *true*)
     wordsize=64
+    bfd_libs='$(BFD64_LIBS) $(BFD32_LIBS)'
     all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)'
     if test -z "$GCC" && test "$BFD_HOST_64BIT_LONG" = "0" && test "$BFD_HOST_64_BIT_DEFINED" = "0"; then
       AC_MSG_WARN([You have requested a 64 bit BFD configuration, but])
@@ -769,11 +770,13 @@ case ${host64}-${target64}-${want64} in
     ;;
   false-false-false)
     wordsize=32
+    bfd_libs='$(BFD32_LIBS)'
     all_backends='$(BFD32_BACKENDS)'
     ;;
 esac
 
 AC_SUBST(wordsize)
+AC_SUBST(bfd_libs)
 AC_SUBST(all_backends)
 AC_SUBST(bfd_backends)
 AC_SUBST(bfd_machines)
diff -BurpN source-orig/bfd/elf64-mips.c source/bfd/elf64-mips.c
--- source-orig/bfd/elf64-mips.c	Sun Dec  2 15:38:30 2001
+++ source/bfd/elf64-mips.c	Mon Dec  3 14:03:54 2001
@@ -25,9 +25,7 @@ Foundation, Inc., 59 Temple Place - Suit
 
    The MIPS 64-bit ELF ABI uses an unusual reloc format.  This file
    overrides the usual ELF reloc handling, and handles reading and
-   writing the relocations here.
-
-   The MIPS 64-bit ELF ABI also uses an unusual archive map format.  */
+   writing the relocations here.  */
 
 #include "bfd.h"
 #include "sysdep.h"
@@ -77,9 +75,6 @@ static boolean mips_elf64_slurp_one_relo
 static boolean mips_elf64_slurp_reloc_table
   PARAMS ((bfd *, asection *, asymbol **, boolean));
 static void mips_elf64_write_relocs PARAMS ((bfd *, asection *, PTR));
-static boolean mips_elf64_slurp_armap PARAMS ((bfd *));
-static boolean mips_elf64_write_armap
-  PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
 
 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
    from smaller values.  Start with zero, widen, *then* decrement.  */
@@ -1768,217 +1763,6 @@ mips_elf64_write_relocs (abfd, sec, data
 	      == (int) count);
 }
 
-/* Irix 6 defines a brand new archive map format, so that they can
-   have archives more than 4 GB in size.  */
-
-/* Read an Irix 6 armap.  */
-
-static boolean
-mips_elf64_slurp_armap (abfd)
-     bfd *abfd;
-{
-  struct artdata *ardata = bfd_ardata (abfd);
-  char nextname[17];
-  file_ptr arhdrpos;
-  bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize;
-  struct areltdata *mapdata;
-  bfd_byte int_buf[8];
-  char *stringbase;
-  bfd_byte *raw_armap = NULL;
-  carsym *carsyms;
-  bfd_size_type amt;
-
-  ardata->symdefs = NULL;
-
-  /* Get the name of the first element.  */
-  arhdrpos = bfd_tell (abfd);
-  i = bfd_bread ((PTR) nextname, (bfd_size_type) 16, abfd);
-  if (i == 0)
-    return true;
-  if (i != 16)
-    return false;
-
-  if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
-    return false;
-
-  /* Archives with traditional armaps are still permitted.  */
-  if (strncmp (nextname, "/               ", 16) == 0)
-    return bfd_slurp_armap (abfd);
-
-  if (strncmp (nextname, "/SYM64/         ", 16) != 0)
-    {
-      bfd_has_map (abfd) = false;
-      return true;
-    }
-
-  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
-  if (mapdata == NULL)
-    return false;
-  parsed_size = mapdata->parsed_size;
-  bfd_release (abfd, (PTR) mapdata);
-
-  if (bfd_bread (int_buf, (bfd_size_type) 8, abfd) != 8)
-    {
-      if (bfd_get_error () != bfd_error_system_call)
-	bfd_set_error (bfd_error_malformed_archive);
-      return false;
-    }
-
-  nsymz = bfd_getb64 (int_buf);
-  stringsize = parsed_size - 8 * nsymz - 8;
-
-  carsym_size = nsymz * sizeof (carsym);
-  ptrsize = 8 * nsymz;
-
-  amt = carsym_size + stringsize + 1;
-  ardata->symdefs = (carsym *) bfd_zalloc (abfd, amt);
-  if (ardata->symdefs == NULL)
-    return false;
-  carsyms = ardata->symdefs;
-  stringbase = ((char *) ardata->symdefs) + carsym_size;
-
-  raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
-  if (raw_armap == NULL)
-    goto error_return;
-
-  if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize
-      || bfd_bread (stringbase, stringsize, abfd) != stringsize)
-    {
-      if (bfd_get_error () != bfd_error_system_call)
-	bfd_set_error (bfd_error_malformed_archive);
-      goto error_return;
-    }
-
-  for (i = 0; i < nsymz; i++)
-    {
-      carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
-      carsyms->name = stringbase;
-      stringbase += strlen (stringbase) + 1;
-      ++carsyms;
-    }
-  *stringbase = '\0';
-
-  ardata->symdef_count = nsymz;
-  ardata->first_file_filepos = arhdrpos + sizeof (struct ar_hdr) + parsed_size;
-
-  bfd_has_map (abfd) = true;
-  bfd_release (abfd, raw_armap);
-
-  return true;
-
- error_return:
-  if (raw_armap != NULL)
-    bfd_release (abfd, raw_armap);
-  if (ardata->symdefs != NULL)
-    bfd_release (abfd, ardata->symdefs);
-  return false;
-}
-
-/* Write out an Irix 6 armap.  The Irix 6 tools are supposed to be
-   able to handle ordinary ELF armaps, but at least on Irix 6.2 the
-   linker crashes.  */
-
-static boolean
-mips_elf64_write_armap (arch, elength, map, symbol_count, stridx)
-     bfd *arch;
-     unsigned int elength;
-     struct orl *map;
-     unsigned int symbol_count;
-     int stridx;
-{
-  unsigned int ranlibsize = (symbol_count * 8) + 8;
-  unsigned int stringsize = stridx;
-  unsigned int mapsize = stringsize + ranlibsize;
-  file_ptr archive_member_file_ptr;
-  bfd *current = arch->archive_head;
-  unsigned int count;
-  struct ar_hdr hdr;
-  unsigned int i;
-  int padding;
-  bfd_byte buf[8];
-
-  padding = BFD_ALIGN (mapsize, 8) - mapsize;
-  mapsize += padding;
-
-  /* work out where the first object file will go in the archive */
-  archive_member_file_ptr = (mapsize
-			     + elength
-			     + sizeof (struct ar_hdr)
-			     + SARMAG);
-
-  memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
-  strcpy (hdr.ar_name, "/SYM64/");
-  sprintf (hdr.ar_size, "%-10d", (int) mapsize);
-  sprintf (hdr.ar_date, "%ld", (long) time (NULL));
-  /* This, at least, is what Intel coff sets the values to.: */
-  sprintf ((hdr.ar_uid), "%d", 0);
-  sprintf ((hdr.ar_gid), "%d", 0);
-  sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0);
-  strncpy (hdr.ar_fmag, ARFMAG, 2);
-
-  for (i = 0; i < sizeof (struct ar_hdr); i++)
-    if (((char *) (&hdr))[i] == '\0')
-      (((char *) (&hdr))[i]) = ' ';
-
-  /* Write the ar header for this item and the number of symbols */
-
-  if (bfd_bwrite ((PTR) &hdr, (bfd_size_type) sizeof (struct ar_hdr), arch)
-      != sizeof (struct ar_hdr))
-    return false;
-
-  bfd_putb64 ((bfd_vma) symbol_count, buf);
-  if (bfd_bwrite (buf, (bfd_size_type) 8, arch) != 8)
-    return false;
-
-  /* Two passes, first write the file offsets for each symbol -
-     remembering that each offset is on a two byte boundary.  */
-
-  /* Write out the file offset for the file associated with each
-     symbol, and remember to keep the offsets padded out.  */
-
-  current = arch->archive_head;
-  count = 0;
-  while (current != (bfd *) NULL && count < symbol_count)
-    {
-      /* For each symbol which is used defined in this object, write out
-	 the object file's address in the archive */
-
-      while (map[count].u.abfd == current)
-	{
-	  bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
-	  if (bfd_bwrite (buf, (bfd_size_type) 8, arch) != 8)
-	    return false;
-	  count++;
-	}
-      /* Add size of this archive entry */
-      archive_member_file_ptr += (arelt_size (current)
-				  + sizeof (struct ar_hdr));
-      /* remember about the even alignment */
-      archive_member_file_ptr += archive_member_file_ptr % 2;
-      current = current->next;
-    }
-
-  /* now write the strings themselves */
-  for (count = 0; count < symbol_count; count++)
-    {
-      size_t len = strlen (*map[count].name) + 1;
-
-      if (bfd_bwrite (*map[count].name, (bfd_size_type) len, arch) != len)
-	return false;
-    }
-
-  /* The spec says that this should be padded to an 8 byte boundary.
-     However, the Irix 6.2 tools do not appear to do this.  */
-  while (padding != 0)
-    {
-      if (bfd_bwrite ("", (bfd_size_type) 1, arch) != 1)
-	return false;
-      --padding;
-    }
-
-  return true;
-}
-
 /* ECOFF swapping routines.  These are used when dealing with the
    .mdebug section, which is in the ECOFF debugging format.  */
 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
@@ -2129,14 +1913,16 @@ const struct elf_size_info mips_elf64_si
 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
 #define bfd_elf64_bfd_reloc_type_lookup	mips_elf64_reloc_type_lookup
 #define bfd_elf64_archive_functions
-#define bfd_elf64_archive_slurp_armap	mips_elf64_slurp_armap
+extern boolean bfd_elf64_archive_slurp_armap
+  PARAMS((bfd *));
+extern boolean bfd_elf64_archive_write_armap
+  PARAMS((bfd *, unsigned int, struct orl *, unsigned int, int));
 #define bfd_elf64_archive_slurp_extended_name_table \
 				_bfd_archive_coff_slurp_extended_name_table
 #define bfd_elf64_archive_construct_extended_name_table \
 				_bfd_archive_coff_construct_extended_name_table
 #define bfd_elf64_archive_truncate_arname \
 					_bfd_archive_coff_truncate_arname
-#define bfd_elf64_archive_write_armap	mips_elf64_write_armap
 #define bfd_elf64_archive_read_ar_hdr	_bfd_archive_coff_read_ar_hdr
 #define bfd_elf64_archive_openr_next_archived_file \
 				_bfd_archive_coff_openr_next_archived_file


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]