changeset 103158:1a098eefd007

(unexec): Consider a section to precede the .bss section if its addresses overlap that of .bss. (unexec) [NS_IMPL_GNUSTEP]: Copy ObjC-related data from old file instead of dumping process.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Wed, 06 May 2009 02:27:20 +0000
parents 770f32ad0bfd
children 103cc47f370c
files src/unexelf.c
diffstat 1 files changed, 57 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/unexelf.c	Wed May 06 02:26:52 2009 +0000
+++ b/src/unexelf.c	Wed May 06 02:27:20 2009 +0000
@@ -985,9 +985,29 @@
 	     placed after the .bss section.  Overlap can occur if the
 	     section just before .bss has less-strict alignment; this
 	     was observed between .symtab and .bss on Solaris 2.5.1
-	     (sparc) with GCC snapshot 960602.  */
+	     (sparc) with GCC snapshot 960602.
+
+> dump -h temacs
+
+temacs:
+
+	   **** SECTION HEADER TABLE ****
+[No]	Type	Flags	Addr         Offset       Size        	Name
+	Link	Info	Adralgn      Entsize
 
-	  if (NEW_SECTION_H (nn).sh_offset >= old_bss_offset)
+[22]	1	3	0x335150     0x315150     0x4          	.data.rel.local
+	0	0	0x4          0            
+
+[23]	8	3	0x335158     0x315158     0x42720      	.bss
+	0	0	0x8          0            
+
+[24]	2	0	0            0x315154     0x1c9d0      	.symtab
+	25	1709	0x4          0x10         
+	  */
+
+	  if (NEW_SECTION_H (nn).sh_offset >= old_bss_offset
+	      || (NEW_SECTION_H (nn).sh_offset + NEW_SECTION_H (nn).sh_size
+		  > new_data2_offset))
 	    NEW_SECTION_H (nn).sh_offset += new_data2_incr;
 
 	  /* Any section that was originally placed after the section
@@ -1206,11 +1226,41 @@
       symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
 
       for (; symp < symendp; symp ++)
-	if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0
-	    || strcmp ((char *) (symnames + symp->st_name), "end") == 0
-	    || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0
-	    || strcmp ((char *) (symnames + symp->st_name), "edata") == 0)
-	  memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr));
+	{
+	  if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0
+	      || strcmp ((char *) (symnames + symp->st_name), "end") == 0
+	      || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0
+	      || strcmp ((char *) (symnames + symp->st_name), "edata") == 0)
+	    memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr));
+
+	  /* Strictly speaking, #ifdef below is not necessary.  But we
+	     keep it to indicate that this kind of change may also be
+	     necessary for other unexecs to support GNUstep.  */
+#ifdef NS_IMPL_GNUSTEP
+	  /* ObjC runtime modifies the values of some data structures
+	     such as classes and selectors in the .data section after
+	     loading.  As the dump process copies the .data section
+	     from the current process, that causes problems when the
+	     modified classes are reinitialized in the dumped
+	     executable.  We copy such data from the old file, not
+	     from the current process.  */
+	  if (strncmp ((char *) (symnames + symp->st_name),
+		       "_OBJC_", sizeof ("_OBJC_") - 1) == 0)
+	    {
+	      caddr_t old, new;
+
+	      new = ((symp->st_value - NEW_SECTION_H (symp->st_shndx).sh_addr)
+		     + NEW_SECTION_H (symp->st_shndx).sh_offset + new_base);
+	      /* "Unpatch" index.  */
+	      nn = symp->st_shndx;
+	      if (nn > old_bss_index)
+		nn--;
+	      old = ((symp->st_value - NEW_SECTION_H (symp->st_shndx).sh_addr)
+		     + OLD_SECTION_H (nn).sh_offset + old_base);
+	      memcpy (new, old, symp->st_size);
+	    }
+#endif
+	}
     }
 
   /* This loop seeks out relocation sections for the data section, so