This is the mail archive of the binutils@sourceware.org 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: PR binutils/12235: elfedit.c:716: error: array subscript is above array bounds


Hi,

This patch extracts common ELF codes from dwarf.c, elfedit.c and
readelf.c into a new file, elfcomm.c.  OK for trunk?

Thanks.

H.J.
---
2010-11-21  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/12235
	* elfcomm.c: New.
	* elfcomm.h: Likewise.

	* Makefile.am (HFILES): Add elfcomm.h.
	(CFILES): Add elfcomm.c.
	(ELFLIBS): New.
	(readelf_SOURCES): Add $(ELFLIBS).
	(elfedit_SOURCES): Likewise.
	(objdump_SOURCES): Likewise.
	* Makefile.in: Regenerated.

	* dwarf.c: Include "elfcomm.h".
	(byte_get): Removed.
	(byte_get_little_endian): Likewise.
	(byte_get_big_endian): Likewise.
	(byte_get_signed): Likewise.
	(error): Likewise.
	(warn): Likewise.

	* dwarf.h (dwarf_vma): Defined with HOST_WIDEST_INT.
	(dwarf_size_type): Likewise.
	(byte_get): Removed.
	(byte_get_signed): Likewise.
	(byte_get_little_endian): Likewise.
	(byte_get_big_endian): Likewise.
	(error): Likewise.
	(warn): Likewise.

	* elfedit.c: Include "elfcomm.h".  Don't include "aout/ar.h".
	Call error () instead of non_fatal ().
	(streq): Removed.
	(strneq): Likewise.
	(const_strneq): Likewise.
	(non_fatal): Likewise.
	(BYTE_GET): Likewise.
	(BYTE_PUT): Likewise.
	(byte_get): Likewise.
	(byte_put): Likewise.
	(byte_get_little_endian): Likewise.
	(byte_get_big_endian): Likewise.
	(byte_put_little_endian): Likewise.
	(byte_put_big_endian): Likewise.
	(adjust_relative_path): Likewise.
	(archive_info): Likewise.
	(setup_archive): Likewise.
	(release_archive): Likewise.
	(setup_nested_archive): Likewise.
	(get_archive_member_name): Likewise.
	(get_archive_member_name_at): Likewise.
	(make_qualified_name): Likewise.

	* objdump.c: Include "elfcomm.h".

	* readelf.c: Include "elfcomm.h".  Don't include "aout/ar.h".
	(BYTE_GET): Removed.
	(BYTE_GET_SIGNED): Removed.
	(streq): Likewise.
	(strneq): Likewise.
	(const_strneq): Likewise.
	(byte_put): Likewise.
	(byte_put_little_endian): Likewise.
	(byte_put_big_endian): Likewise.
	(adjust_relative_path): Likewise.
	(archive_info): Likewise.
	(setup_archive): Likewise.
	(release_archive): Likewise.
	(setup_nested_archive): Likewise.
	(get_archive_member_name): Likewise.
	(get_archive_member_name_at): Likewise.
	(make_qualified_name): Likewise.

diff --git a/binutils/Makefile.am b/binutils/Makefile.am
index 0978538..6546087 100644
--- a/binutils/Makefile.am
+++ b/binutils/Makefile.am
@@ -84,7 +84,7 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) \
 
 HFILES = \
 	arsup.h binemul.h bucomm.h budbg.h \
-	coffgrok.h debug.h dlltool.h dwarf.h nlmconv.h \
+	coffgrok.h debug.h dlltool.h dwarf.h elfcomm.h nlmconv.h \
 	sysdep.h unwind-ia64.h windres.h winduni.h windint.h \
 	windmc.h
 
@@ -95,7 +95,7 @@ CFILES = \
 	addr2line.c ar.c arsup.c bin2c.c binemul.c bucomm.c \
 	coffdump.c coffgrok.c cxxfilt.c \
 	dwarf.c debug.c dlltool.c dllwrap.c \
-	emul_aix.c emul_vanilla.c filemode.c \
+	elfcomm.c emul_aix.c emul_vanilla.c filemode.c \
 	ieee.c is-ranlib.c is-strip.c maybe-ranlib.c maybe-strip.c \
 	nlmconv.c nm.c not-ranlib.c not-strip.c \
 	objcopy.c objdump.c prdbg.c \
@@ -116,6 +116,9 @@ WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
 # Code shared by all the binutils.
 BULIBS = bucomm.c version.c filemode.c
 
+# Code shared by the ELF related programs.
+ELFLIBS = elfcomm.c
+
 BFDLIB = ../bfd/libbfd.la
 
 OPCODES = ../opcodes/libopcodes.la
@@ -192,17 +195,17 @@ objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
 
 strings_SOURCES = strings.c $(BULIBS)
 
-readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c
+readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c $(ELFLIBS)
 readelf_LDADD   = $(LIBINTL) $(LIBIBERTY)
 
-elfedit_SOURCES = elfedit.c version.c
+elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
 elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
 
 strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
 
 nm_new_SOURCES = nm.c $(BULIBS)
 
-objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS)
+objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
 objdump_LDADD = $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL)
 
 objdump.@OBJEXT@:objdump.c
diff --git a/binutils/Makefile.in b/binutils/Makefile.in
index fddc931..8e3d7f2 100644
--- a/binutils/Makefile.in
+++ b/binutils/Makefile.in
@@ -121,7 +121,9 @@ am_dlltool_OBJECTS = dlltool.$(OBJEXT) defparse.$(OBJEXT) \
 dlltool_OBJECTS = $(am_dlltool_OBJECTS)
 am_dllwrap_OBJECTS = dllwrap.$(OBJEXT) version.$(OBJEXT)
 dllwrap_OBJECTS = $(am_dllwrap_OBJECTS)
-am_elfedit_OBJECTS = elfedit.$(OBJEXT) version.$(OBJEXT)
+am__objects_2 = elfcomm.$(OBJEXT)
+am_elfedit_OBJECTS = elfedit.$(OBJEXT) version.$(OBJEXT) \
+	$(am__objects_2)
 elfedit_OBJECTS = $(am_elfedit_OBJECTS)
 am_nlmconv_OBJECTS = nlmconv.$(OBJEXT) nlmheader.$(OBJEXT) \
 	$(am__objects_1)
@@ -130,22 +132,22 @@ nlmconv_LDADD = $(LDADD)
 am_nm_new_OBJECTS = nm.$(OBJEXT) $(am__objects_1)
 nm_new_OBJECTS = $(am_nm_new_OBJECTS)
 nm_new_LDADD = $(LDADD)
-am__objects_2 = rddbg.$(OBJEXT) debug.$(OBJEXT) stabs.$(OBJEXT) \
+am__objects_3 = rddbg.$(OBJEXT) debug.$(OBJEXT) stabs.$(OBJEXT) \
 	ieee.$(OBJEXT) rdcoff.$(OBJEXT)
-am__objects_3 = $(am__objects_2) wrstabs.$(OBJEXT)
+am__objects_4 = $(am__objects_3) wrstabs.$(OBJEXT)
 am_objcopy_OBJECTS = objcopy.$(OBJEXT) not-strip.$(OBJEXT) \
-	rename.$(OBJEXT) $(am__objects_3) $(am__objects_1)
+	rename.$(OBJEXT) $(am__objects_4) $(am__objects_1)
 objcopy_OBJECTS = $(am_objcopy_OBJECTS)
 objcopy_LDADD = $(LDADD)
 am_objdump_OBJECTS = objdump.$(OBJEXT) dwarf.$(OBJEXT) prdbg.$(OBJEXT) \
-	$(am__objects_2) $(am__objects_1)
+	$(am__objects_3) $(am__objects_1) $(am__objects_2)
 objdump_OBJECTS = $(am_objdump_OBJECTS)
 am_ranlib_OBJECTS = ar.$(OBJEXT) is-ranlib.$(OBJEXT) arparse.$(OBJEXT) \
 	arlex.$(OBJEXT) arsup.$(OBJEXT) rename.$(OBJEXT) \
 	binemul.$(OBJEXT) emul_$(EMULATION).$(OBJEXT) $(am__objects_1)
 ranlib_OBJECTS = $(am_ranlib_OBJECTS)
 am_readelf_OBJECTS = readelf.$(OBJEXT) version.$(OBJEXT) \
-	unwind-ia64.$(OBJEXT) dwarf.$(OBJEXT)
+	unwind-ia64.$(OBJEXT) dwarf.$(OBJEXT) $(am__objects_2)
 readelf_OBJECTS = $(am_readelf_OBJECTS)
 am_size_OBJECTS = size.$(OBJEXT) $(am__objects_1)
 size_OBJECTS = $(am_size_OBJECTS)
@@ -158,7 +160,7 @@ am_strings_OBJECTS = strings.$(OBJEXT) $(am__objects_1)
 strings_OBJECTS = $(am_strings_OBJECTS)
 strings_LDADD = $(LDADD)
 am_strip_new_OBJECTS = objcopy.$(OBJEXT) is-strip.$(OBJEXT) \
-	rename.$(OBJEXT) $(am__objects_3) $(am__objects_1)
+	rename.$(OBJEXT) $(am__objects_4) $(am__objects_1)
 strip_new_OBJECTS = $(am_strip_new_OBJECTS)
 strip_new_LDADD = $(LDADD)
 am_sysdump_OBJECTS = sysdump.$(OBJEXT) $(am__objects_1)
@@ -426,7 +428,7 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) \
 
 HFILES = \
 	arsup.h binemul.h bucomm.h budbg.h \
-	coffgrok.h debug.h dlltool.h dwarf.h nlmconv.h \
+	coffgrok.h debug.h dlltool.h dwarf.h elfcomm.h nlmconv.h \
 	sysdep.h unwind-ia64.h windres.h winduni.h windint.h \
 	windmc.h
 
@@ -436,7 +438,7 @@ CFILES = \
 	addr2line.c ar.c arsup.c bin2c.c binemul.c bucomm.c \
 	coffdump.c coffgrok.c cxxfilt.c \
 	dwarf.c debug.c dlltool.c dllwrap.c \
-	emul_aix.c emul_vanilla.c filemode.c \
+	elfcomm.c emul_aix.c emul_vanilla.c filemode.c \
 	ieee.c is-ranlib.c is-strip.c maybe-ranlib.c maybe-strip.c \
 	nlmconv.c nm.c not-ranlib.c not-strip.c \
 	objcopy.c objdump.c prdbg.c \
@@ -456,6 +458,9 @@ WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
 
 # Code shared by all the binutils.
 BULIBS = bucomm.c version.c filemode.c
+
+# Code shared by the ELF related programs.
+ELFLIBS = elfcomm.c
 BFDLIB = ../bfd/libbfd.la
 OPCODES = ../opcodes/libopcodes.la
 LIBIBERTY = ../libiberty/libiberty.a
@@ -505,13 +510,13 @@ LDADD = $(BFDLIB) $(LIBIBERTY) $(LIBINTL)
 size_SOURCES = size.c $(BULIBS)
 objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
 strings_SOURCES = strings.c $(BULIBS)
-readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c
+readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c $(ELFLIBS)
 readelf_LDADD = $(LIBINTL) $(LIBIBERTY)
-elfedit_SOURCES = elfedit.c version.c
+elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
 elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
 strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
 nm_new_SOURCES = nm.c $(BULIBS)
-objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS)
+objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
 objdump_LDADD = $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL)
 cxxfilt_SOURCES = cxxfilt.c $(BULIBS)
 ar_SOURCES = arparse.y arlex.l ar.c not-ranlib.c arsup.c rename.c binemul.c \
@@ -771,6 +776,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlltool.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dllwrap.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfcomm.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfedit.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emul_$(EMULATION).Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emul_aix.Po@am__quote@
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 369304b..c986ca7 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -23,6 +23,7 @@
 #include "libiberty.h"
 #include "bfd.h"
 #include "bucomm.h"
+#include "elfcomm.h"
 #include "elf/common.h"
 #include "dwarf2.h"
 #include "dwarf.h"
@@ -64,125 +65,6 @@ int do_wide;
 #define FLAG_DEBUG_LINES_RAW	 1
 #define FLAG_DEBUG_LINES_DECODED 2
 
-dwarf_vma (*byte_get) (unsigned char *, int);
-
-dwarf_vma
-byte_get_little_endian (unsigned char *field, int size)
-{
-  switch (size)
-    {
-    case 1:
-      return *field;
-
-    case 2:
-      return  ((unsigned int) (field[0]))
-	|    (((unsigned int) (field[1])) << 8);
-
-    case 3:
-      return  ((unsigned long) (field[0]))
-	|    (((unsigned long) (field[1])) << 8)
-	|    (((unsigned long) (field[2])) << 16);
-
-    case 4:
-      return  ((unsigned long) (field[0]))
-	|    (((unsigned long) (field[1])) << 8)
-	|    (((unsigned long) (field[2])) << 16)
-	|    (((unsigned long) (field[3])) << 24);
-
-    case 8:
-      if (sizeof (dwarf_vma) == 8)
-	return  ((dwarf_vma) (field[0]))
-	  |    (((dwarf_vma) (field[1])) << 8)
-	  |    (((dwarf_vma) (field[2])) << 16)
-	  |    (((dwarf_vma) (field[3])) << 24)
-	  |    (((dwarf_vma) (field[4])) << 32)
-	  |    (((dwarf_vma) (field[5])) << 40)
-	  |    (((dwarf_vma) (field[6])) << 48)
-	  |    (((dwarf_vma) (field[7])) << 56);
-      else if (sizeof (dwarf_vma) == 4)
-	/* We want to extract data from an 8 byte wide field and
-	   place it into a 4 byte wide field.  Since this is a little
-	   endian source we can just use the 4 byte extraction code.  */
-	return  ((unsigned long) (field[0]))
-	  |    (((unsigned long) (field[1])) << 8)
-	  |    (((unsigned long) (field[2])) << 16)
-	  |    (((unsigned long) (field[3])) << 24);
-
-    default:
-      error (_("Unhandled data length: %d\n"), size);
-      abort ();
-    }
-}
-
-dwarf_vma
-byte_get_big_endian (unsigned char *field, int size)
-{
-  switch (size)
-    {
-    case 1:
-      return *field;
-
-    case 2:
-      return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
-
-    case 3:
-      return ((unsigned long) (field[2]))
-	|   (((unsigned long) (field[1])) << 8)
-	|   (((unsigned long) (field[0])) << 16);
-
-    case 4:
-      return ((unsigned long) (field[3]))
-	|   (((unsigned long) (field[2])) << 8)
-	|   (((unsigned long) (field[1])) << 16)
-	|   (((unsigned long) (field[0])) << 24);
-
-    case 8:
-      if (sizeof (dwarf_vma) == 8)
-	return ((dwarf_vma) (field[7]))
-	  |   (((dwarf_vma) (field[6])) << 8)
-	  |   (((dwarf_vma) (field[5])) << 16)
-	  |   (((dwarf_vma) (field[4])) << 24)
-	  |   (((dwarf_vma) (field[3])) << 32)
-	  |   (((dwarf_vma) (field[2])) << 40)
-	  |   (((dwarf_vma) (field[1])) << 48)
-	  |   (((dwarf_vma) (field[0])) << 56);
-      else if (sizeof (dwarf_vma) == 4)
-	{
-	  /* Although we are extracing data from an 8 byte wide field,
-	     we are returning only 4 bytes of data.  */
-	  field += 4;
-	  return ((unsigned long) (field[3]))
-	    |   (((unsigned long) (field[2])) << 8)
-	    |   (((unsigned long) (field[1])) << 16)
-	    |   (((unsigned long) (field[0])) << 24);
-	}
-
-    default:
-      error (_("Unhandled data length: %d\n"), size);
-      abort ();
-    }
-}
-
-dwarf_vma
-byte_get_signed (unsigned char *field, int size)
-{
-  dwarf_vma x = byte_get (field, size);
-
-  switch (size)
-    {
-    case 1:
-      return (x ^ 0x80) - 0x80;
-    case 2:
-      return (x ^ 0x8000) - 0x8000;
-    case 4:
-      return (x ^ 0x80000000) - 0x80000000;
-    case 8:
-      return x;
-    default:
-      abort ();
-    }
-}
-
 static int
 size_of_encoded_value (int encoding)
 {
@@ -5020,28 +4902,6 @@ xcrealloc (void *ptr, size_t nmemb, size_t size)
 }
 
 void
-error (const char *message, ...)
-{
-  va_list args;
-
-  va_start (args, message);
-  fprintf (stderr, _("%s: Error: "), program_name);
-  vfprintf (stderr, message, args);
-  va_end (args);
-}
-
-void
-warn (const char *message, ...)
-{
-  va_list args;
-
-  va_start (args, message);
-  fprintf (stderr, _("%s: Warning: "), program_name);
-  vfprintf (stderr, message, args);
-  va_end (args);
-}
-
-void
 free_debug_memory (void)
 {
   unsigned int i;
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 1c47c5e..e9de463 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -19,15 +19,8 @@
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
-#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
-/* We can't use any bfd types here since readelf may define BFD64 and
-   objdump may not.  */
-typedef unsigned long long dwarf_vma;
-typedef unsigned long long dwarf_size_type;
-#else
-typedef unsigned long dwarf_vma;
-typedef unsigned long dwarf_size_type;
-#endif
+typedef unsigned HOST_WIDEST_INT dwarf_vma;
+typedef unsigned HOST_WIDEST_INT dwarf_size_type;
 
 struct dwarf_section
 {
@@ -100,11 +93,6 @@ typedef struct
 }
 debug_info;
 
-extern dwarf_vma (*byte_get) (unsigned char *, int);
-extern dwarf_vma byte_get_signed (unsigned char *, int);
-extern dwarf_vma byte_get_little_endian (unsigned char *, int);
-extern dwarf_vma byte_get_big_endian (unsigned char *, int);
-
 extern int eh_addr_size;
 
 extern int do_debug_info;
@@ -142,8 +130,5 @@ void *cmalloc (size_t, size_t);
 void *xcmalloc (size_t, size_t);
 void *xcrealloc (void *, size_t, size_t);
 
-void error (const char *, ...) ATTRIBUTE_PRINTF_1;
-void warn (const char *, ...) ATTRIBUTE_PRINTF_1;
-
 unsigned long int read_leb128 (unsigned char *data,
 			       unsigned int *length_return, int sign);
diff --git a/binutils/elfcomm.c b/binutils/elfcomm.c
new file mode 100644
index 0000000..e44dee8
--- /dev/null
+++ b/binutils/elfcomm.c
@@ -0,0 +1,658 @@
+/* elfcomm.c -- common code for ELF format file.
+   Copyright 2010
+   Free Software Foundation, Inc.
+
+   Originally developed by Eric Youngdale <eric@andante.jic.com>
+   Modifications by Nick Clifton <nickc@redhat.com>
+
+   This file is part of GNU Binutils.
+
+   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 3 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., 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "libiberty.h"
+#include "filenames.h"
+#include "bfd.h"
+#include "aout/ar.h"
+#include "bucomm.h"
+#include "elfcomm.h"
+
+void
+error (const char *message, ...)
+{
+  va_list args;
+
+  va_start (args, message);
+  fprintf (stderr, _("%s: Error: "), program_name);
+  vfprintf (stderr, message, args);
+  va_end (args);
+}
+
+void
+warn (const char *message, ...)
+{
+  va_list args;
+
+  va_start (args, message);
+  fprintf (stderr, _("%s: Warning: "), program_name);
+  vfprintf (stderr, message, args);
+  va_end (args);
+}
+
+void (*byte_put) (unsigned char *, elf_vma, int);
+
+void
+byte_put_little_endian (unsigned char * field, elf_vma value, int size)
+{
+  switch (size)
+    {
+    case 8:
+      field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
+      field[6] = ((value >> 24) >> 24) & 0xff;
+      field[5] = ((value >> 24) >> 16) & 0xff;
+      field[4] = ((value >> 24) >> 8) & 0xff;
+      /* Fall through.  */
+    case 4:
+      field[3] = (value >> 24) & 0xff;
+      /* Fall through.  */
+    case 3:
+      field[2] = (value >> 16) & 0xff;
+      /* Fall through.  */
+    case 2:
+      field[1] = (value >> 8) & 0xff;
+      /* Fall through.  */
+    case 1:
+      field[0] = value & 0xff;
+      break;
+
+    default:
+      error (_("Unhandled data length: %d\n"), size);
+      abort ();
+    }
+}
+
+void
+byte_put_big_endian (unsigned char * field, elf_vma value, int size)
+{
+  switch (size)
+    {
+    case 8:
+      field[7] = value & 0xff;
+      field[6] = (value >> 8) & 0xff;
+      field[5] = (value >> 16) & 0xff;
+      field[4] = (value >> 24) & 0xff;
+      value >>= 16;
+      value >>= 16;
+      /* Fall through.  */
+    case 4:
+      field[3] = value & 0xff;
+      value >>= 8;
+      /* Fall through.  */
+    case 3:
+      field[2] = value & 0xff;
+      value >>= 8;
+      /* Fall through.  */
+    case 2:
+      field[1] = value & 0xff;
+      value >>= 8;
+      /* Fall through.  */
+    case 1:
+      field[0] = value & 0xff;
+      break;
+
+    default:
+      error (_("Unhandled data length: %d\n"), size);
+      abort ();
+    }
+}
+
+elf_vma (*byte_get) (unsigned char *, int);
+
+elf_vma
+byte_get_little_endian (unsigned char *field, int size)
+{
+  switch (size)
+    {
+    case 1:
+      return *field;
+
+    case 2:
+      return  ((unsigned int) (field[0]))
+	|    (((unsigned int) (field[1])) << 8);
+
+    case 3:
+      return  ((unsigned long) (field[0]))
+	|    (((unsigned long) (field[1])) << 8)
+	|    (((unsigned long) (field[2])) << 16);
+
+    case 4:
+      return  ((unsigned long) (field[0]))
+	|    (((unsigned long) (field[1])) << 8)
+	|    (((unsigned long) (field[2])) << 16)
+	|    (((unsigned long) (field[3])) << 24);
+
+    case 8:
+      if (sizeof (elf_vma) == 8)
+	return  ((elf_vma) (field[0]))
+	  |    (((elf_vma) (field[1])) << 8)
+	  |    (((elf_vma) (field[2])) << 16)
+	  |    (((elf_vma) (field[3])) << 24)
+	  |    (((elf_vma) (field[4])) << 32)
+	  |    (((elf_vma) (field[5])) << 40)
+	  |    (((elf_vma) (field[6])) << 48)
+	  |    (((elf_vma) (field[7])) << 56);
+      else if (sizeof (elf_vma) == 4)
+	/* We want to extract data from an 8 byte wide field and
+	   place it into a 4 byte wide field.  Since this is a little
+	   endian source we can just use the 4 byte extraction code.  */
+	return  ((unsigned long) (field[0]))
+	  |    (((unsigned long) (field[1])) << 8)
+	  |    (((unsigned long) (field[2])) << 16)
+	  |    (((unsigned long) (field[3])) << 24);
+
+    default:
+      error (_("Unhandled data length: %d\n"), size);
+      abort ();
+    }
+}
+
+elf_vma
+byte_get_big_endian (unsigned char *field, int size)
+{
+  switch (size)
+    {
+    case 1:
+      return *field;
+
+    case 2:
+      return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
+
+    case 3:
+      return ((unsigned long) (field[2]))
+	|   (((unsigned long) (field[1])) << 8)
+	|   (((unsigned long) (field[0])) << 16);
+
+    case 4:
+      return ((unsigned long) (field[3]))
+	|   (((unsigned long) (field[2])) << 8)
+	|   (((unsigned long) (field[1])) << 16)
+	|   (((unsigned long) (field[0])) << 24);
+
+    case 8:
+      if (sizeof (elf_vma) == 8)
+	return ((elf_vma) (field[7]))
+	  |   (((elf_vma) (field[6])) << 8)
+	  |   (((elf_vma) (field[5])) << 16)
+	  |   (((elf_vma) (field[4])) << 24)
+	  |   (((elf_vma) (field[3])) << 32)
+	  |   (((elf_vma) (field[2])) << 40)
+	  |   (((elf_vma) (field[1])) << 48)
+	  |   (((elf_vma) (field[0])) << 56);
+      else if (sizeof (elf_vma) == 4)
+	{
+	  /* Although we are extracing data from an 8 byte wide field,
+	     we are returning only 4 bytes of data.  */
+	  field += 4;
+	  return ((unsigned long) (field[3]))
+	    |   (((unsigned long) (field[2])) << 8)
+	    |   (((unsigned long) (field[1])) << 16)
+	    |   (((unsigned long) (field[0])) << 24);
+	}
+
+    default:
+      error (_("Unhandled data length: %d\n"), size);
+      abort ();
+    }
+}
+
+elf_vma
+byte_get_signed (unsigned char *field, int size)
+{
+  elf_vma x = byte_get (field, size);
+
+  switch (size)
+    {
+    case 1:
+      return (x ^ 0x80) - 0x80;
+    case 2:
+      return (x ^ 0x8000) - 0x8000;
+    case 4:
+      return (x ^ 0x80000000) - 0x80000000;
+    case 8:
+      return x;
+    default:
+      abort ();
+    }
+}
+
+/* Return the path name for a proxy entry in a thin archive, adjusted
+   relative to the path name of the thin archive itself if necessary.
+   Always returns a pointer to malloc'ed memory.  */
+
+char *
+adjust_relative_path (const char *file_name, const char *name,
+		      int name_len)
+{
+  char * member_file_name;
+  const char * base_name = lbasename (file_name);
+
+  /* This is a proxy entry for a thin archive member.
+     If the extended name table contains an absolute path
+     name, or if the archive is in the current directory,
+     use the path name as given.  Otherwise, we need to
+     find the member relative to the directory where the
+     archive is located.  */
+  if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
+    {
+      member_file_name = (char *) malloc (name_len + 1);
+      if (member_file_name == NULL)
+        {
+          error (_("Out of memory\n"));
+          return NULL;
+        }
+      memcpy (member_file_name, name, name_len);
+      member_file_name[name_len] = '\0';
+    }
+  else
+    {
+      /* Concatenate the path components of the archive file name
+         to the relative path name from the extended name table.  */
+      size_t prefix_len = base_name - file_name;
+      member_file_name = (char *) malloc (prefix_len + name_len + 1);
+      if (member_file_name == NULL)
+        {
+          error (_("Out of memory\n"));
+          return NULL;
+        }
+      memcpy (member_file_name, file_name, prefix_len);
+      memcpy (member_file_name + prefix_len, name, name_len);
+      member_file_name[prefix_len + name_len] = '\0';
+    }
+  return member_file_name;
+}
+
+/* Read the symbol table and long-name table from an archive.  */
+
+int
+setup_archive (struct archive_info *arch, const char *file_name,
+	       FILE *file, bfd_boolean is_thin_archive,
+	       bfd_boolean read_symbols)
+{
+  size_t got;
+  unsigned long size;
+
+  arch->file_name = strdup (file_name);
+  arch->file = file;
+  arch->index_num = 0;
+  arch->index_array = NULL;
+  arch->sym_table = NULL;
+  arch->sym_size = 0;
+  arch->longnames = NULL;
+  arch->longnames_size = 0;
+  arch->nested_member_origin = 0;
+  arch->is_thin_archive = is_thin_archive;
+  arch->next_arhdr_offset = SARMAG;
+
+  /* Read the first archive member header.  */
+  if (fseek (file, SARMAG, SEEK_SET) != 0)
+    {
+      error (_("%s: failed to seek to first archive header\n"), file_name);
+      return 1;
+    }
+  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
+  if (got != sizeof arch->arhdr)
+    {
+      if (got == 0)
+	return 0;
+
+      error (_("%s: failed to read archive header\n"), file_name);
+      return 1;
+    }
+
+  /* See if this is the archive symbol table.  */
+  if (const_strneq (arch->arhdr.ar_name, "/               ")
+      || const_strneq (arch->arhdr.ar_name, "/SYM64/         "))
+    {
+      size = strtoul (arch->arhdr.ar_size, NULL, 10);
+      size = size + (size & 1);
+
+      arch->next_arhdr_offset += sizeof arch->arhdr + size;
+
+      if (read_symbols)
+	{
+	  unsigned long i;
+	  /* A buffer used to hold numbers read in from an archive index.
+	     These are always 4 bytes long and stored in big-endian
+	     format.  */
+#define SIZEOF_AR_INDEX_NUMBERS 4
+	  unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
+	  unsigned char * index_buffer;
+
+	  /* Check the size of the archive index.  */
+	  if (size < SIZEOF_AR_INDEX_NUMBERS)
+	    {
+	      error (_("%s: the archive index is empty\n"), file_name);
+	      return 1;
+	    }
+
+	  /* Read the numer of entries in the archive index.  */
+	  got = fread (integer_buffer, 1, sizeof integer_buffer, file);
+	  if (got != sizeof (integer_buffer))
+	    {
+	      error (_("%s: failed to read archive index\n"), file_name);
+	      return 1;
+	    }
+	  arch->index_num = byte_get_big_endian (integer_buffer,
+						 sizeof integer_buffer);
+	  size -= SIZEOF_AR_INDEX_NUMBERS;
+
+	  /* Read in the archive index.  */
+	  if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS)
+	    {
+	      error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
+		     file_name, arch->index_num);
+	      return 1;
+	    }
+	  index_buffer = (unsigned char *)
+              malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
+	  if (index_buffer == NULL)
+	    {
+	      error (_("Out of memory whilst trying to read archive symbol index\n"));
+	      return 1;
+	    }
+	  got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS,
+		       arch->index_num, file);
+	  if (got != arch->index_num)
+	    {
+	      free (index_buffer);
+	      error (_("%s: failed to read archive index\n"), file_name);
+	      return 1;
+	    }
+	  size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS;
+
+	  /* Convert the index numbers into the host's numeric format.  */
+	  arch->index_array = (long unsigned int *)
+              malloc (arch->index_num * sizeof (* arch->index_array));
+	  if (arch->index_array == NULL)
+	    {
+	      free (index_buffer);
+	      error (_("Out of memory whilst trying to convert the archive symbol index\n"));
+	      return 1;
+	    }
+
+	  for (i = 0; i < arch->index_num; i++)
+	    arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
+						        SIZEOF_AR_INDEX_NUMBERS);
+	  free (index_buffer);
+
+	  /* The remaining space in the header is taken up by the symbol
+	     table.  */
+	  if (size < 1)
+	    {
+	      error (_("%s: the archive has an index but no symbols\n"),
+		     file_name);
+	      return 1;
+	    }
+	  arch->sym_table = (char *) malloc (size);
+	  arch->sym_size = size;
+	  if (arch->sym_table == NULL)
+	    {
+	      error (_("Out of memory whilst trying to read archive index symbol table\n"));
+	      return 1;
+	    }
+	  got = fread (arch->sym_table, 1, size, file);
+	  if (got != size)
+	    {
+	      error (_("%s: failed to read archive index symbol table\n"),
+		     file_name);
+	      return 1;
+	    }
+  	}
+      else
+	{
+	  if (fseek (file, size, SEEK_CUR) != 0)
+	    {
+	      error (_("%s: failed to skip archive symbol table\n"),
+		     file_name);
+	      return 1;
+	    }
+	}
+
+      /* Read the next archive header.  */
+      got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
+      if (got != sizeof arch->arhdr)
+	{
+	  if (got == 0)
+            return 0;
+	  error (_("%s: failed to read archive header following archive index\n"),
+		 file_name);
+	  return 1;
+	}
+    }
+  else if (read_symbols)
+    printf (_("%s has no archive index\n"), file_name);
+
+  if (const_strneq (arch->arhdr.ar_name, "//              "))
+    {
+      /* This is the archive string table holding long member names.  */
+      arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
+      arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
+
+      arch->longnames = (char *) malloc (arch->longnames_size);
+      if (arch->longnames == NULL)
+	{
+	  error (_("Out of memory reading long symbol names in archive\n"));
+	  return 1;
+	}
+
+      if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
+	{
+	  free (arch->longnames);
+	  arch->longnames = NULL;
+	  error (_("%s: failed to read long symbol name string table\n"),
+		 file_name);
+	  return 1;
+	}
+
+      if ((arch->longnames_size & 1) != 0)
+	getc (file);
+    }
+
+  return 0;
+}
+
+/* Open and setup a nested archive, if not already open.  */
+
+int
+setup_nested_archive (struct archive_info *nested_arch,
+		      const char *member_file_name)
+{
+  FILE * member_file;
+
+  /* Have we already setup this archive?  */
+  if (nested_arch->file_name != NULL
+      && streq (nested_arch->file_name, member_file_name))
+    return 0;
+
+  /* Close previous file and discard cached information.  */
+  if (nested_arch->file != NULL)
+    fclose (nested_arch->file);
+  release_archive (nested_arch);
+
+  member_file = fopen (member_file_name, "rb");
+  if (member_file == NULL)
+    return 1;
+  return setup_archive (nested_arch, member_file_name, member_file,
+			FALSE, FALSE);
+}
+
+/* Release the memory used for the archive information.  */
+
+void
+release_archive (struct archive_info * arch)
+{
+  if (arch->file_name != NULL)
+    free (arch->file_name);
+  if (arch->index_array != NULL)
+    free (arch->index_array);
+  if (arch->sym_table != NULL)
+    free (arch->sym_table);
+  if (arch->longnames != NULL)
+    free (arch->longnames);
+}
+
+/* Get the name of an archive member from the current archive header.
+   For simple names, this will modify the ar_name field of the current
+   archive header.  For long names, it will return a pointer to the
+   longnames table.  For nested archives, it will open the nested archive
+   and get the name recursively.  NESTED_ARCH is a single-entry cache so
+   we don't keep rereading the same information from a nested archive.  */
+
+char *
+get_archive_member_name (struct archive_info *arch,
+                         struct archive_info *nested_arch)
+{
+  unsigned long j, k;
+
+  if (arch->arhdr.ar_name[0] == '/')
+    {
+      /* We have a long name.  */
+      char *endp;
+      char *member_file_name;
+      char *member_name;
+
+      arch->nested_member_origin = 0;
+      k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
+      if (arch->is_thin_archive && endp != NULL && * endp == ':')
+        arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
+
+      while ((j < arch->longnames_size)
+             && (arch->longnames[j] != '\n')
+             && (arch->longnames[j] != '\0'))
+        j++;
+      if (arch->longnames[j-1] == '/')
+        j--;
+      arch->longnames[j] = '\0';
+
+      if (!arch->is_thin_archive || arch->nested_member_origin == 0)
+        return arch->longnames + k;
+
+      /* This is a proxy for a member of a nested archive.
+         Find the name of the member in that archive.  */
+      member_file_name = adjust_relative_path (arch->file_name,
+					       arch->longnames + k, j - k);
+      if (member_file_name != NULL
+          && setup_nested_archive (nested_arch, member_file_name) == 0)
+	{
+          member_name = get_archive_member_name_at (nested_arch,
+						    arch->nested_member_origin,
+						    NULL);
+	  if (member_name != NULL)
+	    {
+	      free (member_file_name);
+	      return member_name;
+	    }
+	}
+      free (member_file_name);
+
+      /* Last resort: just return the name of the nested archive.  */
+      return arch->longnames + k;
+    }
+
+  /* We have a normal (short) name.  */
+  for (j = 0; j < sizeof (arch->arhdr.ar_name); j++)
+    if (arch->arhdr.ar_name[j] == '/')
+      {
+	arch->arhdr.ar_name[j] = '\0';
+	return arch->arhdr.ar_name;
+      }
+
+  /* The full ar_name field is used.  Don't rely on ar_date starting
+     with a zero byte.  */
+  {
+    char *name = xmalloc (sizeof (arch->arhdr.ar_name) + 1);
+    memcpy (name, arch->arhdr.ar_name, sizeof (arch->arhdr.ar_name));
+    name[sizeof (arch->arhdr.ar_name)] = '\0';
+    return name;
+  }
+}
+
+/* Get the name of an archive member at a given OFFSET within an archive
+   ARCH.  */
+
+char *
+get_archive_member_name_at (struct archive_info *arch,
+                            unsigned long offset,
+			    struct archive_info *nested_arch)
+{
+  size_t got;
+
+  if (fseek (arch->file, offset, SEEK_SET) != 0)
+    {
+      error (_("%s: failed to seek to next file name\n"), arch->file_name);
+      return NULL;
+    }
+  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
+  if (got != sizeof arch->arhdr)
+    {
+      error (_("%s: failed to read archive header\n"), arch->file_name);
+      return NULL;
+    }
+  if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
+    {
+      error (_("%s: did not find a valid archive header\n"),
+	     arch->file_name);
+      return NULL;
+    }
+
+  return get_archive_member_name (arch, nested_arch);
+}
+
+/* Construct a string showing the name of the archive member, qualified
+   with the name of the containing archive file.  For thin archives, we
+   use square brackets to denote the indirection.  For nested archives,
+   we show the qualified name of the external member inside the square
+   brackets (e.g., "thin.a[normal.a(foo.o)]").  */
+
+char *
+make_qualified_name (struct archive_info * arch,
+		     struct archive_info * nested_arch,
+		     const char *member_name)
+{
+  size_t len;
+  char * name;
+
+  len = strlen (arch->file_name) + strlen (member_name) + 3;
+  if (arch->is_thin_archive && arch->nested_member_origin != 0)
+    len += strlen (nested_arch->file_name) + 2;
+
+  name = (char *) malloc (len);
+  if (name == NULL)
+    {
+      error (_("Out of memory\n"));
+      return NULL;
+    }
+
+  if (arch->is_thin_archive && arch->nested_member_origin != 0)
+    snprintf (name, len, "%s[%s(%s)]", arch->file_name,
+	      nested_arch->file_name, member_name);
+  else if (arch->is_thin_archive)
+    snprintf (name, len, "%s[%s]", arch->file_name, member_name);
+  else
+    snprintf (name, len, "%s(%s)", arch->file_name, member_name);
+
+  return name;
+}
diff --git a/binutils/elfcomm.h b/binutils/elfcomm.h
new file mode 100644
index 0000000..3f9727e
--- /dev/null
+++ b/binutils/elfcomm.h
@@ -0,0 +1,110 @@
+/* elfcomm.h -- include file of common code for ELF format file.
+   Copyright 2010
+   Free Software Foundation, Inc.
+
+   Originally developed by Eric Youngdale <eric@andante.jic.com>
+   Modifications by Nick Clifton <nickc@redhat.com>
+
+   This file is part of GNU Binutils.
+
+   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 3 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., 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#ifndef _ELFCOMM_H
+#define _ELFCOMM_H
+
+#include "aout/ar.h"
+
+void error (const char *, ...) ATTRIBUTE_PRINTF_1;
+void warn (const char *, ...) ATTRIBUTE_PRINTF_1;
+
+#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
+/* We can't use any bfd types here since readelf may define BFD64 and
+   objdump may not.  */
+#define HOST_WIDEST_INT	long long
+#else
+#define HOST_WIDEST_INT long
+#endif
+typedef unsigned HOST_WIDEST_INT elf_vma;
+
+extern void (*byte_put) (unsigned char *, elf_vma, int);
+extern void byte_put_little_endian (unsigned char *, elf_vma, int);
+extern void byte_put_big_endian (unsigned char *, elf_vma, int);
+
+extern elf_vma (*byte_get) (unsigned char *, int);
+extern elf_vma byte_get_signed (unsigned char *, int);
+extern elf_vma byte_get_little_endian (unsigned char *, int);
+extern elf_vma byte_get_big_endian (unsigned char *, int);
+
+#define BYTE_PUT(field, val)	byte_put (field, val, sizeof (field))
+#define BYTE_GET(field)		byte_get (field, sizeof (field))
+#define BYTE_GET_SIGNED(field)	byte_get_signed (field, sizeof (field))
+
+/* This is just a bit of syntatic sugar.  */
+#define streq(a,b)	  (strcmp ((a), (b)) == 0)
+#define strneq(a,b,n)	  (strncmp ((a), (b), (n)) == 0)
+#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
+
+/* Structure to hold information about an archive file.  */
+
+struct archive_info
+{
+  char * file_name;                     /* Archive file name.  */
+  FILE * file;                          /* Open file descriptor.  */
+  unsigned long index_num;              /* Number of symbols in table.  */
+  unsigned long * index_array;          /* The array of member offsets.  */
+  char * sym_table;                     /* The symbol table.  */
+  unsigned long sym_size;               /* Size of the symbol table.  */
+  char * longnames;                     /* The long file names table.  */
+  unsigned long longnames_size;         /* Size of the long file names table.  */
+  unsigned long nested_member_origin;   /* Origin in the nested archive of the current member.  */
+  unsigned long next_arhdr_offset;      /* Offset of the next archive header.  */
+  bfd_boolean is_thin_archive;          /* TRUE if this is a thin archive.  */
+  struct ar_hdr arhdr;                  /* Current archive header.  */
+};
+
+/* Return the path name for a proxy entry in a thin archive.  */
+extern char *adjust_relative_path (const char *, const char *, int);
+
+/* Read the symbol table and long-name table from an archive.  */
+extern int setup_archive (struct archive_info *, const char *, FILE *,
+			  bfd_boolean, bfd_boolean);
+
+/* Open and setup a nested archive, if not already open.  */
+extern int setup_nested_archive (struct archive_info *, const char *);
+
+/* Release the memory used for the archive information.  */
+extern void release_archive (struct archive_info *);
+
+/* Get the name of an archive member from the current archive header.  */
+
+extern char *get_archive_member_name (struct archive_info *,
+				      struct archive_info *);
+
+/* Get the name of an archive member at a given offset within an
+   archive.  */
+
+extern char *get_archive_member_name_at (struct archive_info *,
+					 unsigned long,
+					 struct archive_info *);
+
+/* Construct a string showing the name of the archive member, qualified
+   with the name of the containing archive file.  */
+
+extern char *make_qualified_name (struct archive_info *,
+				  struct archive_info *,
+				  const char *);
+
+#endif /* _ELFCOMM_H */
diff --git a/binutils/elfedit.c b/binutils/elfedit.c
index c9a4b5a..1805ec1 100644
--- a/binutils/elfedit.c
+++ b/binutils/elfedit.c
@@ -33,15 +33,13 @@
 #endif
 
 #include "bfd.h"
+#include "elfcomm.h"
 #include "bucomm.h"
 
 #include "elf/common.h"
 #include "elf/external.h"
 #include "elf/internal.h"
 
-
-#include "aout/ar.h"
-
 #include "getopt.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
@@ -61,174 +59,6 @@ static int input_elf_osabi = -1;
 static int output_elf_osabi = -1;
 static int input_elf_class = -1;
 
-#define streq(a,b)	  (strcmp ((a), (b)) == 0)
-#define strneq(a,b,n)	  (strncmp ((a), (b), (n)) == 0)
-#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
-
-void
-non_fatal (const char *message, ...)
-{
-  va_list args;
-
-  va_start (args, message);
-  fprintf (stderr, _("%s: Error: "), program_name);
-  vfprintf (stderr, message, args);
-  va_end (args);
-}
-
-#define BYTE_GET(field)		byte_get (field, sizeof (field))
-#define BYTE_PUT(field, val)	byte_put (field, val, sizeof (field))
-
-static bfd_vma (*byte_get) (unsigned char *, int);
-static void (*byte_put) (unsigned char *, bfd_vma, int);
-
-static bfd_vma
-byte_get_little_endian (unsigned char *field, int size)
-{
-  switch (size)
-    {
-    case 1:
-      return *field;
-
-    case 2:
-      return  ((unsigned int) (field[0]))
-	|    (((unsigned int) (field[1])) << 8);
-
-    case 4:
-      return  ((unsigned long) (field[0]))
-	|    (((unsigned long) (field[1])) << 8)
-	|    (((unsigned long) (field[2])) << 16)
-	|    (((unsigned long) (field[3])) << 24);
-
-    case 8:
-      if (sizeof (bfd_vma) == 8)
-	return  ((bfd_vma) (field[0]))
-	  |    (((bfd_vma) (field[1])) << 8)
-	  |    (((bfd_vma) (field[2])) << 16)
-	  |    (((bfd_vma) (field[3])) << 24)
-	  |    (((bfd_vma) (field[4])) << 32)
-	  |    (((bfd_vma) (field[5])) << 40)
-	  |    (((bfd_vma) (field[6])) << 48)
-	  |    (((bfd_vma) (field[7])) << 56);
-      else if (sizeof (bfd_vma) == 4)
-	/* We want to extract data from an 8 byte wide field and
-	   place it into a 4 byte wide field.  Since this is a little
-	   endian source we can just use the 4 byte extraction code.  */
-	return  ((unsigned long) (field[0]))
-	  |    (((unsigned long) (field[1])) << 8)
-	  |    (((unsigned long) (field[2])) << 16)
-	  |    (((unsigned long) (field[3])) << 24);
-
-    default:
-      non_fatal (_("Unhandled data length: %d\n"), size);
-      abort ();
-    }
-}
-
-static bfd_vma
-byte_get_big_endian (unsigned char *field, int size)
-{
-  switch (size)
-    {
-    case 1:
-      return *field;
-
-    case 2:
-      return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
-
-    case 4:
-      return ((unsigned long) (field[3]))
-	|   (((unsigned long) (field[2])) << 8)
-	|   (((unsigned long) (field[1])) << 16)
-	|   (((unsigned long) (field[0])) << 24);
-
-    case 8:
-      if (sizeof (bfd_vma) == 8)
-	return ((bfd_vma) (field[7]))
-	  |   (((bfd_vma) (field[6])) << 8)
-	  |   (((bfd_vma) (field[5])) << 16)
-	  |   (((bfd_vma) (field[4])) << 24)
-	  |   (((bfd_vma) (field[3])) << 32)
-	  |   (((bfd_vma) (field[2])) << 40)
-	  |   (((bfd_vma) (field[1])) << 48)
-	  |   (((bfd_vma) (field[0])) << 56);
-      else if (sizeof (bfd_vma) == 4)
-	{
-	  /* Although we are extracing data from an 8 byte wide field,
-	     we are returning only 4 bytes of data.  */
-	  field += 4;
-	  return ((unsigned long) (field[3]))
-	    |   (((unsigned long) (field[2])) << 8)
-	    |   (((unsigned long) (field[1])) << 16)
-	    |   (((unsigned long) (field[0])) << 24);
-	}
-
-    default:
-      non_fatal (_("Unhandled data length: %d\n"), size);
-      abort ();
-    }
-}
-
-static void
-byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
-{
-  switch (size)
-    {
-    case 8:
-      field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
-      field[6] = ((value >> 24) >> 24) & 0xff;
-      field[5] = ((value >> 24) >> 16) & 0xff;
-      field[4] = ((value >> 24) >> 8) & 0xff;
-      /* Fall through.  */
-    case 4:
-      field[3] = (value >> 24) & 0xff;
-      field[2] = (value >> 16) & 0xff;
-      /* Fall through.  */
-    case 2:
-      field[1] = (value >> 8) & 0xff;
-      /* Fall through.  */
-    case 1:
-      field[0] = value & 0xff;
-      break;
-
-    default:
-      non_fatal (_("Unhandled data length: %d\n"), size);
-      abort ();
-    }
-}
-
-static void
-byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
-{
-  switch (size)
-    {
-    case 8:
-      field[7] = value & 0xff;
-      field[6] = (value >> 8) & 0xff;
-      field[5] = (value >> 16) & 0xff;
-      field[4] = (value >> 24) & 0xff;
-      value >>= 16;
-      value >>= 16;
-      /* Fall through.  */
-    case 4:
-      field[3] = value & 0xff;
-      field[2] = (value >> 8) & 0xff;
-      value >>= 16;
-      /* Fall through.  */
-    case 2:
-      field[1] = value & 0xff;
-      value >>= 8;
-      /* Fall through.  */
-    case 1:
-      field[0] = value & 0xff;
-      break;
-
-    default:
-      non_fatal (_("Unhandled data length: %d\n"), size);
-      abort ();
-    }
-}
-
 static int
 update_elf_header (const char *file_name, FILE *file)
 {
@@ -239,7 +69,7 @@ update_elf_header (const char *file_name, FILE *file)
       || elf_header.e_ident[EI_MAG2] != ELFMAG2
       || elf_header.e_ident[EI_MAG3] != ELFMAG3)
     {
-      non_fatal
+      error
 	(_("%s: Not an ELF file - wrong magic bytes at the start\n"),
 	 file_name);
       return 0;
@@ -247,7 +77,7 @@ update_elf_header (const char *file_name, FILE *file)
 
   if (elf_header.e_ident[EI_VERSION] != EV_CURRENT)
     {
-      non_fatal
+      error
 	(_("%s: Unsupported EI_VERSION: %d is not %d\n"),
 	 file_name, elf_header.e_ident[EI_VERSION],
 	 EV_CURRENT);
@@ -263,7 +93,7 @@ update_elf_header (const char *file_name, FILE *file)
   /* Skip if class doesn't match. */
   if (input_elf_class != -1 && class != input_elf_class)
     {
-      non_fatal
+      error
 	(_("%s: Unmatched EI_CLASS: %d is not %d\n"),
 	 file_name, class, input_elf_class);
       return 0;
@@ -274,7 +104,7 @@ update_elf_header (const char *file_name, FILE *file)
   /* Skip if e_machine doesn't match. */
   if (input_elf_machine != -1 && machine != input_elf_machine)
     {
-      non_fatal
+      error
 	(_("%s: Unmatched e_machine: %d is not %d\n"),
 	 file_name, machine, input_elf_machine);
       return 0;
@@ -285,7 +115,7 @@ update_elf_header (const char *file_name, FILE *file)
   /* Skip if e_type doesn't match. */
   if (input_elf_type != -1 && type != input_elf_type)
     {
-      non_fatal
+      error
 	(_("%s: Unmatched e_type: %d is not %d\n"),
 	 file_name, type, input_elf_type);
       return 0;
@@ -296,7 +126,7 @@ update_elf_header (const char *file_name, FILE *file)
   /* Skip if OSABI doesn't match. */
   if (input_elf_osabi != -1 && osabi != input_elf_osabi)
     {
-      non_fatal
+      error
 	(_("%s: Unmatched EI_OSABI: %d is not %d\n"),
 	 file_name, osabi, input_elf_osabi);
       return 0;
@@ -330,7 +160,7 @@ update_elf_header (const char *file_name, FILE *file)
     }
 
   if (status != 1)
-    non_fatal (_("%s: Failed to update ELF header: %s\n"),
+    error (_("%s: Failed to update ELF header: %s\n"),
 	       file_name, strerror (errno));
 
   return status;
@@ -363,7 +193,7 @@ get_file_header (FILE * file)
   switch (elf_header.e_ident[EI_CLASS])
     {
     default:
-      non_fatal (_("Unsupported EI_CLASS: %d\n"),
+      error (_("Unsupported EI_CLASS: %d\n"),
 		 elf_header.e_ident[EI_CLASS]);
       return 0;
 
@@ -396,7 +226,7 @@ get_file_header (FILE * file)
 	 overwriting things.  */
       if (sizeof (bfd_vma) < 8)
 	{
-	  non_fatal (_("This executable has been built without support for a\n\
+	  error (_("This executable has been built without support for a\n\
 64 bit data type and so it cannot process 64 bit ELF files.\n"));
 	  return 0;
 	}
@@ -437,14 +267,14 @@ process_object (const char *file_name, FILE *file)
 
   if (! get_file_header (file))
     {
-      non_fatal (_("%s: Failed to read ELF header\n"), file_name);
+      error (_("%s: Failed to read ELF header\n"), file_name);
       return 1;
     }
 
   /* Go to the position of the ELF header.  */
   if (fseek (file, offset, SEEK_SET) != 0)
     {
-      non_fatal (_("%s: Failed to seek to ELF header\n"), file_name);
+      error (_("%s: Failed to seek to ELF header\n"), file_name);
     }
 
   if (! update_elf_header (file_name, file))
@@ -453,341 +283,6 @@ process_object (const char *file_name, FILE *file)
   return 0;
 }
 
-/* Return the path name for a proxy entry in a thin archive, adjusted relative
-   to the path name of the thin archive itself if necessary.  Always returns
-   a pointer to malloc'ed memory.  */
-
-static char *
-adjust_relative_path (const char *file_name, char * name, int name_len)
-{
-  char * member_file_name;
-  const char * base_name = lbasename (file_name);
-
-  /* This is a proxy entry for a thin archive member.
-     If the extended name table contains an absolute path
-     name, or if the archive is in the current directory,
-     use the path name as given.  Otherwise, we need to
-     find the member relative to the directory where the
-     archive is located.  */
-  if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
-    {
-      member_file_name = malloc (name_len + 1);
-      if (member_file_name == NULL)
-        {
-          non_fatal (_("Out of memory\n"));
-          return NULL;
-        }
-      memcpy (member_file_name, name, name_len);
-      member_file_name[name_len] = '\0';
-    }
-  else
-    {
-      /* Concatenate the path components of the archive file name
-         to the relative path name from the extended name table.  */
-      size_t prefix_len = base_name - file_name;
-      member_file_name = malloc (prefix_len + name_len + 1);
-      if (member_file_name == NULL)
-        {
-          non_fatal (_("Out of memory\n"));
-          return NULL;
-        }
-      memcpy (member_file_name, file_name, prefix_len);
-      memcpy (member_file_name + prefix_len, name, name_len);
-      member_file_name[prefix_len + name_len] = '\0';
-    }
-  return member_file_name;
-}
-
-/* Structure to hold information about an archive file.  */
-
-struct archive_info
-{
-  char * file_name;                     /* Archive file name.  */
-  FILE * file;                          /* Open file descriptor.  */
-  unsigned long index_num;              /* Number of symbols in table.  */
-  unsigned long * index_array;          /* The array of member offsets.  */
-  char * sym_table;                     /* The symbol table.  */
-  unsigned long sym_size;               /* Size of the symbol table.  */
-  char * longnames;                     /* The long file names table.  */
-  unsigned long longnames_size;         /* Size of the long file names table.  */
-  unsigned long nested_member_origin;   /* Origin in the nested archive of the current member.  */
-  unsigned long next_arhdr_offset;      /* Offset of the next archive header.  */
-  bfd_boolean is_thin_archive;          /* TRUE if this is a thin archive.  */
-  struct ar_hdr arhdr;                  /* Current archive header.  */
-};
-
-/* Read the symbol table and long-name table from an archive.  */
-
-static int
-setup_archive (struct archive_info * arch, const char * file_name,
-	       FILE * file, bfd_boolean is_thin_archive)
-{
-  size_t got;
-  unsigned long size;
-
-  arch->file_name = strdup (file_name);
-  arch->file = file;
-  arch->index_num = 0;
-  arch->index_array = NULL;
-  arch->sym_table = NULL;
-  arch->sym_size = 0;
-  arch->longnames = NULL;
-  arch->longnames_size = 0;
-  arch->nested_member_origin = 0;
-  arch->is_thin_archive = is_thin_archive;
-  arch->next_arhdr_offset = SARMAG;
-
-  /* Read the first archive member header.  */
-  if (fseek (file, SARMAG, SEEK_SET) != 0)
-    {
-      non_fatal (_("%s: failed to seek to first archive header\n"),
-		 file_name);
-      return 1;
-    }
-  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
-  if (got != sizeof arch->arhdr)
-    {
-      if (got == 0)
-	return 0;
-
-      non_fatal (_("%s: failed to read archive header\n"), file_name);
-      return 1;
-    }
-
-  /* See if this is the archive symbol table.  */
-  if (const_strneq (arch->arhdr.ar_name, "/               ")
-      || const_strneq (arch->arhdr.ar_name, "/SYM64/         "))
-    {
-      size = strtoul (arch->arhdr.ar_size, NULL, 10);
-      size = size + (size & 1);
-
-      arch->next_arhdr_offset += sizeof arch->arhdr + size;
-
-      if (fseek (file, size, SEEK_CUR) != 0)
-	{
-	  non_fatal (_("%s: failed to skip archive symbol table\n"),
-		     file_name);
-	  return 1;
-	}
-
-      /* Read the next archive header.  */
-      got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
-      if (got != sizeof arch->arhdr)
-	{
-	  if (got == 0)
-            return 0;
-	  non_fatal (_("%s: failed to read archive header following archive index\n"),
-		     file_name);
-	  return 1;
-	}
-    }
-
-  if (const_strneq (arch->arhdr.ar_name, "//              "))
-    {
-      /* This is the archive string table holding long member names.  */
-      arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
-      arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
-
-      arch->longnames = malloc (arch->longnames_size);
-      if (arch->longnames == NULL)
-	{
-	  non_fatal (_("Out of memory reading long symbol names in archive\n"));
-	  return 1;
-	}
-
-      if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
-	{
-	  free (arch->longnames);
-	  arch->longnames = NULL;
-	  non_fatal (_("%s: failed to read long symbol name string table\n")
-		     , file_name);
-	  return 1;
-	}
-
-      if ((arch->longnames_size & 1) != 0)
-	getc (file);
-    }
-
-  return 0;
-}
-
-/* Release the memory used for the archive information.  */
-
-static void
-release_archive (struct archive_info * arch)
-{
-  if (arch->file_name != NULL)
-    free (arch->file_name);
-  if (arch->index_array != NULL)
-    free (arch->index_array);
-  if (arch->sym_table != NULL)
-    free (arch->sym_table);
-  if (arch->longnames != NULL)
-    free (arch->longnames);
-}
-
-/* Open and setup a nested archive, if not already open.  */
-
-static int
-setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
-{
-  FILE * member_file;
-
-  /* Have we already setup this archive?  */
-  if (nested_arch->file_name != NULL
-      && streq (nested_arch->file_name, member_file_name))
-    return 0;
-
-  /* Close previous file and discard cached information.  */
-  if (nested_arch->file != NULL)
-    fclose (nested_arch->file);
-  release_archive (nested_arch);
-
-  member_file = fopen (member_file_name, "r+b");
-  if (member_file == NULL)
-    return 1;
-  return setup_archive (nested_arch, member_file_name, member_file,
-			FALSE);
-}
-
-static char *
-get_archive_member_name_at (struct archive_info *  arch,
-			    unsigned long          offset,
-			    struct archive_info *  nested_arch);
-
-/* Get the name of an archive member from the current archive header.
-   For simple names, this will modify the ar_name field of the current
-   archive header.  For long names, it will return a pointer to the
-   longnames table.  For nested archives, it will open the nested archive
-   and get the name recursively.  NESTED_ARCH is a single-entry cache so
-   we don't keep rereading the same information from a nested archive.  */
-
-static char *
-get_archive_member_name (struct archive_info *  arch,
-                         struct archive_info *  nested_arch)
-{
-  unsigned long j, k;
-
-  if (arch->arhdr.ar_name[0] == '/')
-    {
-      /* We have a long name.  */
-      char * endp;
-      char * member_file_name;
-      char * member_name;
-
-      arch->nested_member_origin = 0;
-      k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
-      if (arch->is_thin_archive && endp != NULL && * endp == ':')
-        arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
-
-      while ((j < arch->longnames_size)
-             && (arch->longnames[j] != '\n')
-             && (arch->longnames[j] != '\0'))
-        j++;
-      if (arch->longnames[j-1] == '/')
-        j--;
-      arch->longnames[j] = '\0';
-
-      if (!arch->is_thin_archive || arch->nested_member_origin == 0)
-        return arch->longnames + k;
-
-      /* This is a proxy for a member of a nested archive.
-         Find the name of the member in that archive.  */
-      member_file_name = adjust_relative_path (arch->file_name,
-					       arch->longnames + k,
-					       j - k);
-      if (member_file_name != NULL
-          && setup_nested_archive (nested_arch, member_file_name) == 0
-          && (member_name = get_archive_member_name_at (nested_arch,
-							arch->nested_member_origin,
-							NULL)) != NULL)
-        {
-          free (member_file_name);
-          return member_name;
-        }
-      free (member_file_name);
-
-      /* Last resort: just return the name of the nested archive.  */
-      return arch->longnames + k;
-    }
-
-  /* We have a normal (short) name.  */
-  j = 0;
-  while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
-    j++;
-  arch->arhdr.ar_name[j] = '\0';
-  return arch->arhdr.ar_name;
-}
-
-/* Get the name of an archive member at a given OFFSET within an
-   archive ARCH.  */
-
-static char *
-get_archive_member_name_at (struct archive_info * arch,
-                            unsigned long         offset,
-			    struct archive_info * nested_arch)
-{
-  size_t got;
-
-  if (fseek (arch->file, offset, SEEK_SET) != 0)
-    {
-      non_fatal (_("%s: failed to seek to next file name\n"),
-		 arch->file_name);
-      return NULL;
-    }
-  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
-  if (got != sizeof arch->arhdr)
-    {
-      non_fatal (_("%s: failed to read archive header\n"),
-		 arch->file_name);
-      return NULL;
-    }
-  if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
-    {
-      non_fatal (_("%s: did not find a valid archive header\n"),
-		 arch->file_name);
-      return NULL;
-    }
-
-  return get_archive_member_name (arch, nested_arch);
-}
-
-/* Construct a string showing the name of the archive member, qualified
-   with the name of the containing archive file.  For thin archives, we
-   use square brackets to denote the indirection.  For nested archives,
-   we show the qualified name of the external member inside the square
-   brackets (e.g., "thin.a[normal.a(foo.o)]").  */
-
-static char *
-make_qualified_name (struct archive_info * arch,
-                     struct archive_info * nested_arch,
-                     char * member_name)
-{
-  size_t len;
-  char * name;
-
-  len = strlen (arch->file_name) + strlen (member_name) + 3;
-  if (arch->is_thin_archive && arch->nested_member_origin != 0)
-    len += strlen (nested_arch->file_name) + 2;
-
-  name = malloc (len);
-  if (name == NULL)
-    {
-      non_fatal (_("Out of memory\n"));
-      return NULL;
-    }
-
-  if (arch->is_thin_archive && arch->nested_member_origin != 0)
-    snprintf (name, len, "%s[%s(%s)]", arch->file_name,
-	      nested_arch->file_name, member_name);
-  else if (arch->is_thin_archive)
-    snprintf (name, len, "%s[%s]", arch->file_name, member_name);
-  else
-    snprintf (name, len, "%s(%s)", arch->file_name, member_name);
-
-  return name;
-}
-
 /* Process an ELF archive.
    On entry the file is positioned just after the ARMAG string.  */
 
@@ -816,7 +311,7 @@ process_archive (const char * file_name, FILE * file,
   nested_arch.sym_table = NULL;
   nested_arch.longnames = NULL;
 
-  if (setup_archive (&arch, file_name, file, is_thin_archive) != 0)
+  if (setup_archive (&arch, file_name, file, is_thin_archive, FALSE) != 0)
     {
       ret = 1;
       goto out;
@@ -833,7 +328,7 @@ process_archive (const char * file_name, FILE * file,
       /* Read the next archive header.  */
       if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
         {
-          non_fatal (_("%s: failed to seek to next archive header\n"),
+          error (_("%s: failed to seek to next archive header\n"),
 		     file_name);
           return 1;
         }
@@ -842,14 +337,14 @@ process_archive (const char * file_name, FILE * file,
         {
           if (got == 0)
 	    break;
-          non_fatal (_("%s: failed to read archive header\n"),
+          error (_("%s: failed to read archive header\n"),
 		     file_name);
           ret = 1;
           break;
         }
       if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
         {
-          non_fatal (_("%s: did not find a valid archive header\n"),
+          error (_("%s: did not find a valid archive header\n"),
 		     arch.file_name);
           ret = 1;
           break;
@@ -864,7 +359,7 @@ process_archive (const char * file_name, FILE * file,
       name = get_archive_member_name (&arch, &nested_arch);
       if (name == NULL)
 	{
-	  non_fatal (_("%s: bad archive file name\n"), file_name);
+	  error (_("%s: bad archive file name\n"), file_name);
 	  ret = 1;
 	  break;
 	}
@@ -873,7 +368,7 @@ process_archive (const char * file_name, FILE * file,
       qualified_name = make_qualified_name (&arch, &nested_arch, name);
       if (qualified_name == NULL)
 	{
-	  non_fatal (_("%s: bad archive file name\n"), file_name);
+	  error (_("%s: bad archive file name\n"), file_name);
 	  ret = 1;
 	  break;
 	}
@@ -893,7 +388,7 @@ process_archive (const char * file_name, FILE * file,
           member_file = fopen (member_file_name, "r+b");
           if (member_file == NULL)
             {
-              non_fatal (_("Input file '%s' is not readable\n"),
+              error (_("Input file '%s' is not readable\n"),
 			 member_file_name);
               free (member_file_name);
               ret = 1;
@@ -917,7 +412,7 @@ process_archive (const char * file_name, FILE * file,
           if (fseek (nested_arch.file, archive_file_offset,
 		     SEEK_SET) != 0)
             {
-              non_fatal (_("%s: failed to seek to archive member\n"),
+              error (_("%s: failed to seek to archive member\n"),
 			 nested_arch.file_name);
               ret = 1;
               break;
@@ -956,16 +451,16 @@ check_file (const char *file_name, struct stat *statbuf_p)
   if (stat (file_name, statbuf_p) < 0)
     {
       if (errno == ENOENT)
-	non_fatal (_("'%s': No such file\n"), file_name);
+	error (_("'%s': No such file\n"), file_name);
       else
-	non_fatal (_("Could not locate '%s'.  System error message: %s\n"),
+	error (_("Could not locate '%s'.  System error message: %s\n"),
 		   file_name, strerror (errno));
       return 1;
     }
 
   if (! S_ISREG (statbuf_p->st_mode))
     {
-      non_fatal (_("'%s' is not an ordinary file\n"), file_name);
+      error (_("'%s' is not an ordinary file\n"), file_name);
       return 1;
     }
 
@@ -985,13 +480,13 @@ process_file (const char *file_name)
   file = fopen (file_name, "r+b");
   if (file == NULL)
     {
-      non_fatal (_("Input file '%s' is not readable\n"), file_name);
+      error (_("Input file '%s' is not readable\n"), file_name);
       return 1;
     }
 
   if (fread (armag, SARMAG, 1, file) != 1)
     {
-      non_fatal (_("%s: Failed to read file's magic number\n"),
+      error (_("%s: Failed to read file's magic number\n"),
 		 file_name);
       fclose (file);
       return 1;
@@ -1049,7 +544,7 @@ elf_osabi (const char *osabi)
     if (strcasecmp (osabi, osabis[i].name) == 0)
       return osabis[i].osabi;
 
-  non_fatal (_("Unknown OSABI: %s\n"), osabi);
+  error (_("Unknown OSABI: %s\n"), osabi);
 
   return -1;
 }
@@ -1068,7 +563,7 @@ elf_machine (const char *mach)
   if (strcasecmp (mach, "none") == 0)
     return EM_NONE;
 
-  non_fatal (_("Unknown machine type: %s\n"), mach);
+  error (_("Unknown machine type: %s\n"), mach);
 
   return -1;
 }
@@ -1086,7 +581,7 @@ elf_class (int mach)
     case EM_NONE:
       return ELFCLASSNONE;
     default:
-      non_fatal (_("Unknown machine type: %d\n"), mach);
+      error (_("Unknown machine type: %d\n"), mach);
       return -1;
     }
 }
@@ -1105,7 +600,7 @@ elf_type (const char *type)
   if (strcasecmp (type, "none") == 0)
     return ET_NONE;
 
-  non_fatal (_("Unknown type: %s\n"), type);
+  error (_("Unknown type: %s\n"), type);
 
   return -1;
 }
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 11a11ae..da68eeb 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -55,6 +55,7 @@
 #include "elf-bfd.h"
 #include "progress.h"
 #include "bucomm.h"
+#include "elfcomm.h"
 #include "dwarf.h"
 #include "getopt.h"
 #include "safe-ctype.h"
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 8c20888..3f4167b 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -61,6 +61,7 @@
 
 #include "bfd.h"
 #include "bucomm.h"
+#include "elfcomm.h"
 #include "dwarf.h"
 
 #include "elf/common.h"
@@ -146,8 +147,6 @@
 #include "elf/xstormy16.h"
 #include "elf/xtensa.h"
 
-#include "aout/ar.h"
-
 #include "getopt.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
@@ -260,8 +259,6 @@ typedef enum print_mode
 }
 print_mode;
 
-static void (* byte_put) (unsigned char *, bfd_vma, int);
-
 #define UNKNOWN -1
 
 #define SECTION_NAME(X)						\
@@ -272,9 +269,6 @@ static void (* byte_put) (unsigned char *, bfd_vma, int);
 
 #define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order!  */
 
-#define BYTE_GET(field)		byte_get (field, sizeof (field))
-#define BYTE_GET_SIGNED(field)	byte_get_signed (field, sizeof (field))
-
 #define GET_ELF_SYMBOLS(file, section)			\
   (is_32bit_elf ? get_32bit_elf_symbols (file, section)	\
    : get_64bit_elf_symbols (file, section))
@@ -284,11 +278,6 @@ static void (* byte_put) (unsigned char *, bfd_vma, int);
    already been called and verified that the string exists.  */
 #define GET_DYNAMIC_NAME(offset)	(dynamic_strings + offset)
 
-/* This is just a bit of syntatic sugar.  */
-#define streq(a,b)	  (strcmp ((a), (b)) == 0)
-#define strneq(a,b,n)	  (strncmp ((a), (b), (n)) == 0)
-#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
-
 #define REMOVE_ARCH_BITS(ADDR) do {		\
     if (elf_header.e_machine == EM_ARM)		\
       (ADDR) &= ~1;				\
@@ -340,36 +329,6 @@ get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
   return mvar;
 }
 
-static void
-byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
-{
-  switch (size)
-    {
-    case 8:
-      field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
-      field[6] = ((value >> 24) >> 24) & 0xff;
-      field[5] = ((value >> 24) >> 16) & 0xff;
-      field[4] = ((value >> 24) >> 8) & 0xff;
-      /* Fall through.  */
-    case 4:
-      field[3] = (value >> 24) & 0xff;
-      /* Fall through.  */
-    case 3:
-      field[2] = (value >> 16) & 0xff;
-      /* Fall through.  */
-    case 2:
-      field[1] = (value >> 8) & 0xff;
-      /* Fall through.  */
-    case 1:
-      field[0] = value & 0xff;
-      break;
-
-    default:
-      error (_("Unhandled data length: %d\n"), size);
-      abort ();
-    }
-}
-
 /* Print a VMA value.  */
 
 static int
@@ -503,41 +462,6 @@ print_symbol (int width, const char * symbol)
   return num_printed;
 }
 
-static void
-byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
-{
-  switch (size)
-    {
-    case 8:
-      field[7] = value & 0xff;
-      field[6] = (value >> 8) & 0xff;
-      field[5] = (value >> 16) & 0xff;
-      field[4] = (value >> 24) & 0xff;
-      value >>= 16;
-      value >>= 16;
-      /* Fall through.  */
-    case 4:
-      field[3] = value & 0xff;
-      value >>= 8;
-      /* Fall through.  */
-    case 3:
-      field[2] = value & 0xff;
-      value >>= 8;
-      /* Fall through.  */
-    case 2:
-      field[1] = value & 0xff;
-      value >>= 8;
-      /* Fall through.  */
-    case 1:
-      field[0] = value & 0xff;
-      break;
-
-    default:
-      error (_("Unhandled data length: %d\n"), size);
-      abort ();
-    }
-}
-
 /* Return a pointer to section NAME, or NULL if no such section exists.  */
 
 static Elf_Internal_Shdr *
@@ -12507,432 +12431,6 @@ process_object (char * file_name, FILE * file)
   return 0;
 }
 
-/* Return the path name for a proxy entry in a thin archive, adjusted relative
-   to the path name of the thin archive itself if necessary.  Always returns
-   a pointer to malloc'ed memory.  */
-
-static char *
-adjust_relative_path (char * file_name, char * name, int name_len)
-{
-  char * member_file_name;
-  const char * base_name = lbasename (file_name);
-
-  /* This is a proxy entry for a thin archive member.
-     If the extended name table contains an absolute path
-     name, or if the archive is in the current directory,
-     use the path name as given.  Otherwise, we need to
-     find the member relative to the directory where the
-     archive is located.  */
-  if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
-    {
-      member_file_name = (char *) malloc (name_len + 1);
-      if (member_file_name == NULL)
-        {
-          error (_("Out of memory\n"));
-          return NULL;
-        }
-      memcpy (member_file_name, name, name_len);
-      member_file_name[name_len] = '\0';
-    }
-  else
-    {
-      /* Concatenate the path components of the archive file name
-         to the relative path name from the extended name table.  */
-      size_t prefix_len = base_name - file_name;
-      member_file_name = (char *) malloc (prefix_len + name_len + 1);
-      if (member_file_name == NULL)
-        {
-          error (_("Out of memory\n"));
-          return NULL;
-        }
-      memcpy (member_file_name, file_name, prefix_len);
-      memcpy (member_file_name + prefix_len, name, name_len);
-      member_file_name[prefix_len + name_len] = '\0';
-    }
-  return member_file_name;
-}
-
-/* Structure to hold information about an archive file.  */
-
-struct archive_info
-{
-  char * file_name;                     /* Archive file name.  */
-  FILE * file;                          /* Open file descriptor.  */
-  unsigned long index_num;              /* Number of symbols in table.  */
-  unsigned long * index_array;          /* The array of member offsets.  */
-  char * sym_table;                     /* The symbol table.  */
-  unsigned long sym_size;               /* Size of the symbol table.  */
-  char * longnames;                     /* The long file names table.  */
-  unsigned long longnames_size;         /* Size of the long file names table.  */
-  unsigned long nested_member_origin;   /* Origin in the nested archive of the current member.  */
-  unsigned long next_arhdr_offset;      /* Offset of the next archive header.  */
-  bfd_boolean is_thin_archive;          /* TRUE if this is a thin archive.  */
-  struct ar_hdr arhdr;                  /* Current archive header.  */
-};
-
-/* Read the symbol table and long-name table from an archive.  */
-
-static int
-setup_archive (struct archive_info * arch, char * file_name, FILE * file,
-               bfd_boolean is_thin_archive, bfd_boolean read_symbols)
-{
-  size_t got;
-  unsigned long size;
-
-  arch->file_name = strdup (file_name);
-  arch->file = file;
-  arch->index_num = 0;
-  arch->index_array = NULL;
-  arch->sym_table = NULL;
-  arch->sym_size = 0;
-  arch->longnames = NULL;
-  arch->longnames_size = 0;
-  arch->nested_member_origin = 0;
-  arch->is_thin_archive = is_thin_archive;
-  arch->next_arhdr_offset = SARMAG;
-
-  /* Read the first archive member header.  */
-  if (fseek (file, SARMAG, SEEK_SET) != 0)
-    {
-      error (_("%s: failed to seek to first archive header\n"), file_name);
-      return 1;
-    }
-  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
-  if (got != sizeof arch->arhdr)
-    {
-      if (got == 0)
-	return 0;
-
-      error (_("%s: failed to read archive header\n"), file_name);
-      return 1;
-    }
-
-  /* See if this is the archive symbol table.  */
-  if (const_strneq (arch->arhdr.ar_name, "/               ")
-      || const_strneq (arch->arhdr.ar_name, "/SYM64/         "))
-    {
-      size = strtoul (arch->arhdr.ar_size, NULL, 10);
-      size = size + (size & 1);
-
-      arch->next_arhdr_offset += sizeof arch->arhdr + size;
-
-      if (read_symbols)
-	{
-	  unsigned long i;
-	  /* A buffer used to hold numbers read in from an archive index.
-	     These are always 4 bytes long and stored in big-endian format.  */
-#define SIZEOF_AR_INDEX_NUMBERS 4
-	  unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
-	  unsigned char * index_buffer;
-
-	  /* Check the size of the archive index.  */
-	  if (size < SIZEOF_AR_INDEX_NUMBERS)
-	    {
-	      error (_("%s: the archive index is empty\n"), file_name);
-	      return 1;
-	    }
-
-	  /* Read the numer of entries in the archive index.  */
-	  got = fread (integer_buffer, 1, sizeof integer_buffer, file);
-	  if (got != sizeof (integer_buffer))
-	    {
-	      error (_("%s: failed to read archive index\n"), file_name);
-	      return 1;
-	    }
-	  arch->index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer);
-	  size -= SIZEOF_AR_INDEX_NUMBERS;
-
-	  /* Read in the archive index.  */
-	  if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS)
-	    {
-	      error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
-		     file_name, arch->index_num);
-	      return 1;
-	    }
-	  index_buffer = (unsigned char *)
-              malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
-	  if (index_buffer == NULL)
-	    {
-	      error (_("Out of memory whilst trying to read archive symbol index\n"));
-	      return 1;
-	    }
-	  got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, arch->index_num, file);
-	  if (got != arch->index_num)
-	    {
-	      free (index_buffer);
-	      error (_("%s: failed to read archive index\n"), file_name);
-	      return 1;
-	    }
-	  size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS;
-
-	  /* Convert the index numbers into the host's numeric format.  */
-	  arch->index_array = (long unsigned int *)
-              malloc (arch->index_num * sizeof (* arch->index_array));
-	  if (arch->index_array == NULL)
-	    {
-	      free (index_buffer);
-	      error (_("Out of memory whilst trying to convert the archive symbol index\n"));
-	      return 1;
-	    }
-
-	  for (i = 0; i < arch->index_num; i++)
-	    arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
-						        SIZEOF_AR_INDEX_NUMBERS);
-	  free (index_buffer);
-
-	  /* The remaining space in the header is taken up by the symbol table.  */
-	  if (size < 1)
-	    {
-	      error (_("%s: the archive has an index but no symbols\n"), file_name);
-	      return 1;
-	    }
-	  arch->sym_table = (char *) malloc (size);
-	  arch->sym_size = size;
-	  if (arch->sym_table == NULL)
-	    {
-	      error (_("Out of memory whilst trying to read archive index symbol table\n"));
-	      return 1;
-	    }
-	  got = fread (arch->sym_table, 1, size, file);
-	  if (got != size)
-	    {
-	      error (_("%s: failed to read archive index symbol table\n"), file_name);
-	      return 1;
-	    }
-  	}
-      else
-	{
-	  if (fseek (file, size, SEEK_CUR) != 0)
-	    {
-	      error (_("%s: failed to skip archive symbol table\n"), file_name);
-	      return 1;
-	    }
-	}
-
-      /* Read the next archive header.  */
-      got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
-      if (got != sizeof arch->arhdr)
-	{
-	  if (got == 0)
-            return 0;
-	  error (_("%s: failed to read archive header following archive index\n"), file_name);
-	  return 1;
-	}
-    }
-  else if (read_symbols)
-    printf (_("%s has no archive index\n"), file_name);
-
-  if (const_strneq (arch->arhdr.ar_name, "//              "))
-    {
-      /* This is the archive string table holding long member names.  */
-      arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
-      arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
-
-      arch->longnames = (char *) malloc (arch->longnames_size);
-      if (arch->longnames == NULL)
-	{
-	  error (_("Out of memory reading long symbol names in archive\n"));
-	  return 1;
-	}
-
-      if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
-	{
-	  free (arch->longnames);
-	  arch->longnames = NULL;
-	  error (_("%s: failed to read long symbol name string table\n"), file_name);
-	  return 1;
-	}
-
-      if ((arch->longnames_size & 1) != 0)
-	getc (file);
-    }
-
-  return 0;
-}
-
-/* Release the memory used for the archive information.  */
-
-static void
-release_archive (struct archive_info * arch)
-{
-  if (arch->file_name != NULL)
-    free (arch->file_name);
-  if (arch->index_array != NULL)
-    free (arch->index_array);
-  if (arch->sym_table != NULL)
-    free (arch->sym_table);
-  if (arch->longnames != NULL)
-    free (arch->longnames);
-}
-
-/* Open and setup a nested archive, if not already open.  */
-
-static int
-setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
-{
-  FILE * member_file;
-
-  /* Have we already setup this archive?  */
-  if (nested_arch->file_name != NULL
-      && streq (nested_arch->file_name, member_file_name))
-    return 0;
-
-  /* Close previous file and discard cached information.  */
-  if (nested_arch->file != NULL)
-    fclose (nested_arch->file);
-  release_archive (nested_arch);
-
-  member_file = fopen (member_file_name, "rb");
-  if (member_file == NULL)
-    return 1;
-  return setup_archive (nested_arch, member_file_name, member_file, FALSE, FALSE);
-}
-
-static char *
-get_archive_member_name_at (struct archive_info *  arch,
-			    unsigned long          offset,
-			    struct archive_info *  nested_arch);
-
-/* Get the name of an archive member from the current archive header.
-   For simple names, this will modify the ar_name field of the current
-   archive header.  For long names, it will return a pointer to the
-   longnames table.  For nested archives, it will open the nested archive
-   and get the name recursively.  NESTED_ARCH is a single-entry cache so
-   we don't keep rereading the same information from a nested archive.  */
-
-static char *
-get_archive_member_name (struct archive_info *  arch,
-                         struct archive_info *  nested_arch)
-{
-  unsigned long j, k;
-
-  if (arch->arhdr.ar_name[0] == '/')
-    {
-      /* We have a long name.  */
-      char * endp;
-      char * member_file_name;
-      char * member_name;
-
-      arch->nested_member_origin = 0;
-      k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
-      if (arch->is_thin_archive && endp != NULL && * endp == ':')
-        arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
-
-      while ((j < arch->longnames_size)
-             && (arch->longnames[j] != '\n')
-             && (arch->longnames[j] != '\0'))
-        j++;
-      if (arch->longnames[j-1] == '/')
-        j--;
-      arch->longnames[j] = '\0';
-
-      if (!arch->is_thin_archive || arch->nested_member_origin == 0)
-        return arch->longnames + k;
-
-      /* This is a proxy for a member of a nested archive.
-         Find the name of the member in that archive.  */
-      member_file_name = adjust_relative_path (arch->file_name,
-					       arch->longnames + k, j - k);
-      if (member_file_name != NULL
-          && setup_nested_archive (nested_arch, member_file_name) == 0)
-	{
-          member_name = get_archive_member_name_at (nested_arch,
-						    arch->nested_member_origin,
-						    NULL);
-	  if (member_name != NULL)
-	    {
-	      free (member_file_name);
-	      return member_name;
-	    }
-	}
-      free (member_file_name);
-
-      /* Last resort: just return the name of the nested archive.  */
-      return arch->longnames + k;
-    }
-
-  /* We have a normal (short) name.  */
-  for (j = 0; j < sizeof (arch->arhdr.ar_name); j++)
-    if (arch->arhdr.ar_name[j] == '/')
-      {
-	arch->arhdr.ar_name[j] = '\0';
-	return arch->arhdr.ar_name;
-      }
-
-  /* The full ar_name field is used.  Don't rely on ar_date starting
-     with a zero byte.  */
-  {
-    char *name = xmalloc (sizeof (arch->arhdr.ar_name) + 1);
-    memcpy (name, arch->arhdr.ar_name, sizeof (arch->arhdr.ar_name));
-    name[sizeof (arch->arhdr.ar_name)] = '\0';
-    return name;
-  }
-}
-
-/* Get the name of an archive member at a given OFFSET within an archive ARCH.  */
-
-static char *
-get_archive_member_name_at (struct archive_info * arch,
-                            unsigned long         offset,
-			    struct archive_info * nested_arch)
-{
-  size_t got;
-
-  if (fseek (arch->file, offset, SEEK_SET) != 0)
-    {
-      error (_("%s: failed to seek to next file name\n"), arch->file_name);
-      return NULL;
-    }
-  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
-  if (got != sizeof arch->arhdr)
-    {
-      error (_("%s: failed to read archive header\n"), arch->file_name);
-      return NULL;
-    }
-  if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
-    {
-      error (_("%s: did not find a valid archive header\n"), arch->file_name);
-      return NULL;
-    }
-
-  return get_archive_member_name (arch, nested_arch);
-}
-
-/* Construct a string showing the name of the archive member, qualified
-   with the name of the containing archive file.  For thin archives, we
-   use square brackets to denote the indirection.  For nested archives,
-   we show the qualified name of the external member inside the square
-   brackets (e.g., "thin.a[normal.a(foo.o)]").  */
-
-static char *
-make_qualified_name (struct archive_info * arch,
-                     struct archive_info * nested_arch,
-                     char * member_name)
-{
-  size_t len;
-  char * name;
-
-  len = strlen (arch->file_name) + strlen (member_name) + 3;
-  if (arch->is_thin_archive && arch->nested_member_origin != 0)
-    len += strlen (nested_arch->file_name) + 2;
-
-  name = (char *) malloc (len);
-  if (name == NULL)
-    {
-      error (_("Out of memory\n"));
-      return NULL;
-    }
-
-  if (arch->is_thin_archive && arch->nested_member_origin != 0)
-    snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name);
-  else if (arch->is_thin_archive)
-    snprintf (name, len, "%s[%s]", arch->file_name, member_name);
-  else
-    snprintf (name, len, "%s(%s)", arch->file_name, member_name);
-
-  return name;
-}
-
 /* Process an ELF archive.
    On entry the file is positioned just after the ARMAG string.  */
 


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