diff src/unexelf.c @ 359:8e84bee8ddd0 r21-1-9

Import from CVS: tag r21-1-9
author cvs
date Mon, 13 Aug 2007 10:57:55 +0200
parents 4711e16a8e49
children 1d62742628b6
line wrap: on
line diff
--- a/src/unexelf.c	Mon Aug 13 10:57:07 2007 +0200
+++ b/src/unexelf.c	Mon Aug 13 10:57:55 2007 +0200
@@ -433,7 +433,7 @@
 #include <sym.h>
 #endif /* __sony_news && _SYSTYPE_SYSV */
 #ifdef __sgi
-#include <sym.h> /* for HDRR declaration */
+#include <syms.h> /* for HDRR declaration */
 #endif /* __sgi */
 
 #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__)
@@ -494,16 +494,6 @@
 # define SHN_ABS	Elf_eshn_absolute
 # define SHN_COMMON	Elf_eshn_common
 
-/*
- * The magic of picking the right size types is handled by the ELFSIZE
- * definition above.
- */
-# ifdef __STDC__
-#  define ElfW(type)    Elf_##type
-# else
-#  define ElfW(type)    Elf_/**/type
-# endif
-
 # ifdef __alpha__
 #  include <sys/exec_ecoff.h>
 #  define HDRR		struct ecoff_symhdr
@@ -584,6 +574,45 @@
   return x - rem + y;
 }
 
+/* Return the index of the section named NAME.
+   SECTION_NAMES, FILE_NAME and FILE_H give information
+   about the file we are looking in.
+
+   If we don't find the section NAME, that is a fatal error
+   if NOERROR is 0; we return -1 if NOERROR is nonzero.  */
+
+static int
+find_section (name, section_names, file_name, old_file_h, old_section_h, noerror)
+     char *name;
+     char *section_names;
+     char *file_name;
+     ElfW(Ehdr) *old_file_h;
+     ElfW(Shdr) *old_section_h;
+     int noerror;
+{
+  int idx;
+
+  for (idx = 1; idx < old_file_h->e_shnum; idx++)
+    {
+#ifdef DEBUG
+      fprintf (stderr, "Looking for %s - found %s\n", name,
+	       section_names + OLD_SECTION_H (idx).sh_name);
+#endif
+      if (!strcmp (section_names + OLD_SECTION_H (idx).sh_name,
+		   name))
+	break;
+    }
+  if (idx == old_file_h->e_shnum)
+    {
+      if (noerror)
+	return -1;
+      else
+	fatal ("Can't find %s in %s.\n", name, file_name, 0);
+    }
+
+  return idx;
+}
+
 /* ****************************************************************
  * unexec
  *
@@ -619,8 +648,10 @@
   ElfW(Off)  new_data2_offset;
   ElfW(Addr) new_data2_addr;
 
-  int n, nn, old_bss_index, old_data_index, new_data2_index;
-  int old_sbss_index, old_mdebug_index;
+  int n, nn;
+  int old_bss_index, old_sbss_index;
+  int old_data_index, new_data2_index;
+  int old_mdebug_index;
   struct stat stat_buf;
 
   /* Open the old file & map it into the address space. */
@@ -651,65 +682,40 @@
   old_section_names = (char *) old_base
     + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
 
+  /* Find the mdebug section, if any.  */
+
+  old_mdebug_index = find_section (".mdebug", old_section_names,
+				   old_name, old_file_h, old_section_h, 1);
+
   /* Find the old .bss section.  Figure out parameters of the new
    * data2 and bss sections.
    */
 
-  for (old_bss_index = 1; old_bss_index < (int) old_file_h->e_shnum;
-       old_bss_index++)
-    {
-#ifdef DEBUG
-      fprintf (stderr, "Looking for .bss - found %s\n",
-	       old_section_names + OLD_SECTION_H (old_bss_index).sh_name);
-#endif
-      if (!strcmp (old_section_names + OLD_SECTION_H (old_bss_index).sh_name,
-		   ELF_BSS_SECTION_NAME))
-	break;
-    }
-  if (old_bss_index == old_file_h->e_shnum)
-    fatal ("Can't find .bss in %s.\n", old_name, 0);
+  old_bss_index = find_section (".bss", old_section_names,
+				old_name, old_file_h, old_section_h, 0);
 
-  for (old_sbss_index = 1; old_sbss_index < (int) old_file_h->e_shnum;
-       old_sbss_index++)
+  old_sbss_index = find_section (".sbss", old_section_names,
+				 old_name, old_file_h, old_section_h, 1);
+
+  if (old_sbss_index == -1)
     {
-#ifdef DEBUG
-      fprintf (stderr, "Looking for .sbss - found %s\n",
-	       old_section_names + OLD_SECTION_H (old_sbss_index).sh_name);
-#endif
-      if (!strcmp (old_section_names + OLD_SECTION_H (old_sbss_index).sh_name,
-		   ".sbss"))
-	break;
-    }
-  if (old_sbss_index == old_file_h->e_shnum)
-    {
-      old_sbss_index = -1;
-      old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr;
-      old_bss_size = OLD_SECTION_H(old_bss_index).sh_size;
-      new_data2_offset = OLD_SECTION_H(old_bss_index).sh_offset;
+      old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
+      old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
       new_data2_index = old_bss_index;
     }
   else
     {
-      old_bss_addr = OLD_SECTION_H(old_sbss_index).sh_addr;
-      old_bss_size = OLD_SECTION_H(old_bss_index).sh_size
-	+ OLD_SECTION_H(old_sbss_index).sh_size;
-      new_data2_offset = OLD_SECTION_H(old_sbss_index).sh_offset;
+      old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr;
+      old_bss_size = OLD_SECTION_H (old_bss_index).sh_size
+	+ OLD_SECTION_H (old_sbss_index).sh_size;
       new_data2_index = old_sbss_index;
     }
 
-  for (old_mdebug_index = 1; old_mdebug_index < (int) old_file_h->e_shnum;
-       old_mdebug_index++)
-    {
-#ifdef DEBUG
-      fprintf (stderr, "Looking for .mdebug - found %s\n",
-	       old_section_names + OLD_SECTION_H (old_mdebug_index).sh_name);
-#endif
-      if (!strcmp (old_section_names + OLD_SECTION_H (old_mdebug_index).sh_name,
-		   ".mdebug"))
-	break;
-    }
-    if (old_mdebug_index == old_file_h->e_shnum)
-	old_mdebug_index = 0;
+  /* Find the old .data section.  Figure out parameters of
+     the new data2 and bss sections.  */
+
+  old_data_index = find_section (".data", old_section_names,
+				 old_name, old_file_h, old_section_h, 0);
 
 #if defined (emacs) || !defined (DEBUG)
   new_bss_addr = (ElfW(Addr)) sbrk (0);
@@ -718,6 +724,8 @@
 #endif
   new_data2_addr = old_bss_addr;
   new_data2_size = new_bss_addr - old_bss_addr;
+  new_data2_offset  = OLD_SECTION_H (old_data_index).sh_offset +
+    (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
 
 #ifdef DEBUG
   fprintf (stderr, "old_bss_index %d\n", old_bss_index);
@@ -802,13 +810,13 @@
       if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
 	alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
 
-#ifdef __mips
+#ifdef __sgi
 	  /* According to r02kar@x4u2.desy.de (Karsten Kuenne)
 	     and oliva@gnu.org (Alexandre Oliva), on IRIX 5.2, we
 	     always get "Program segment above .bss" when dumping
 	     when the executable doesn't have an sbss section.  */
       if (old_sbss_index != -1)
-#endif /* __mips */
+#endif /* __sgi */
       if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz
 	  > (old_sbss_index == -1
 	     ? old_bss_addr
@@ -956,18 +964,11 @@
       if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
 	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
 		      ".sdata")
-          /* Taking these sections from the current process, breaks
-             Linux in a subtle way. Binaries only run on the
-             architecture (e.g. i586 vs i686) of the dumping machine */
-#ifdef __sgi
 	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
 		      ".lit4")
 	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
 		      ".lit8")
 	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-		      ".got")
-#endif
-	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
 		      ".sdata1")
 	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
 		      ".data1"))
@@ -1000,7 +1001,8 @@
 #endif /* __alpha__ */
 
 #if defined (__sony_news) && defined (_SYSTYPE_SYSV)
-      if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG && old_mdebug_index) 
+      if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG
+	  && old_mdebug_index != -1) 
         {
 	  int diff = NEW_SECTION_H(nn).sh_offset 
 	 	- OLD_SECTION_H(old_mdebug_index).sh_offset;