Subject: patches for emacs 2.0.3 undumping on pmax
To: None <port-pmax@netbsd.org>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: port-pmax
Date: 01/31/1999 15:24:34
The following patch builds an undumped emacs that works for me.

The reason it doenst work out of the box is due to sbss differences
(we want some of the same sbss handling done for Sony news), and also
a hiccup with laying out the undumped .bss section slightly too far
away from the .sbss  section.

This doesnt correctly handle the .mdebug section; i cant find where
NetBSD defines a struct for ECOFF debuging symbols.



--- src/m/pmax.h.DIST	Sat Sep  6 22:23:09 1997
+++ src/m/pmax.h	Sun Jan 31 15:12:16 1999
@@ -31,8 +31,8 @@
 #undef START_FILES
 #undef RUN_TIME_REMAP
 #define START_FILES pre-crt0.o /usr/lib/crt0.o
-#define CANNOT_DUMP
 #undef UNEXEC
+#define UNEXEC unexelf.o
 #endif /* NetBSD || OpenBSD */
 
 /* Supposedly the following will overcome a kernel bug.  */
--- src/unexelf.c.DIST	Sun Aug  9 19:33:12 1998
+++ src/unexelf.c	Sun Jan 31 15:13:53 1999
@@ -501,9 +501,16 @@
 #  include <sys/exec_ecoff.h>
 #  define HDRR		struct ecoff_symhdr
 #  define pHDRR		HDRR *
-# endif
+# endif /* __alpha__*/
+
+# ifdef __mips__
+#  define SHT_MIPS_DEBUG	DT_MIPS_FLAGS
+#  define HDRR		struct Elf_Shdr
+# endif /* __mips__ */
+
 #endif /* __NetBSD__ */
 
+
 #ifdef __OpenBSD__
 # include <sys/exec_elf.h>
 #endif
@@ -527,6 +534,14 @@
 extern void fatal (char *, ...);
 #endif
 
+#if defined ( __sony_news) && defined (_SYSTYPE_SYSV)
+# define HAVE_MIPS_SBSS
+#endif
+
+#if defined (__mips__) && (defined(__NetBSD__) || defined(__OpenBSD__))
+# define HAVE_MIPS_SBSS
+#endif
+
 #ifndef ELF_BSS_SECTION_NAME
 #define ELF_BSS_SECTION_NAME ".bss"
 #endif
@@ -585,6 +600,47 @@
   return x - rem + y;
 }
 
+#if defined(__alpha__) || (defined ( __sony_news) && defined (_SYSTYPE_SYSV))
+/* We are using  ECOFF symbols embedded in ELF. */
+
+void
+relocate_ecoff_symhdr(symhdr, diff)
+    HDRR *symhdr;
+    Elfw(Word) diff;
+{
+  symhdr->cbLineOffset += diff;
+  symhdr->cbDnOffset   += diff;
+  symhdr->cbPdOffset   += diff;
+  symhdr->cbSymOffset  += diff;
+  symhdr->cbOptOffset  += diff;
+  symhdr->cbAuxOffset  += diff;
+  symhdr->cbSsOffset   += diff;
+  symhdr->cbSsExtOffset += diff;
+  symhdr->cbFdOffset   += diff;
+  symhdr->cbRfdOffset  += diff;
+  symhdr->cbExtOffset  += diff;
+}
+#endif /* __alpha__ or __sony_news and systype_sysv */
+
+#ifdef notyet
+void
+relocate_elf_proghdr(p, diff)
+    HDRR *symhdr;
+    Elfw(Word) diff;
+{
+	phdr->sh_name  += diff;
+	phdr->sh_type  += diff;
+	phdr->sh_flags += diff;
+	phdr->sh_addr  += diff;
+	phdr->sh_offset += diff;
+	phdr->sh_size  += diff;
+	phdr->sh_link  += diff;
+	phdr->sh_info  += diff;
+	phdr->sh_addralign += diff;
+	phdr->sh_entsize += diff;
+};
+#endif /* notyet */
+
 /* ****************************************************************
  * unexec
  *
@@ -620,9 +676,10 @@
   ElfW(Addr) new_data2_addr;
 
   int n, nn, old_bss_index, old_data_index, new_data2_index;
-#if defined ( __sony_news) && defined (_SYSTYPE_SYSV)
+#ifdef HAVE_MIPS_SBSS
   int old_sbss_index, old_mdebug_index;
-#endif /* __sony_news && _SYSTYPE_SYSV */
+  int bss_phdr_index;
+#endif /* HAVE_MIPS_SBSS */
   struct stat stat_buf;
 
   /* Open the old file & map it into the address space. */
@@ -672,7 +729,7 @@
   if (old_bss_index == old_file_h->e_shnum)
     fatal ("Can't find .bss in %s.\n", old_name, 0);
 
-#if defined (__sony_news) && defined (_SYSTYPE_SYSV)
+#ifdef HAVE_MIPS_SBSS
   for (old_sbss_index = 1; old_sbss_index < (int) old_file_h->e_shnum;
        old_sbss_index++)
     {
@@ -713,10 +770,10 @@
     }
     if (old_mdebug_index == old_file_h->e_shnum)
 	old_mdebug_index = 0;
-#else /* not (__sony_news && _SYSTYPE_SYSV) */	    
+#else /* not HAVE_MIPS_SBSS */
   old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
   old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
-#endif /* not (__sony_news && _SYSTYPE_SYSV) */	    
+#endif /* not HAVE_MIPS_SBSS */
 #if defined (emacs) || !defined (DEBUG)
   new_bss_addr = (ElfW(Addr)) sbrk (0);
 #else
@@ -724,9 +781,9 @@
 #endif
   new_data2_addr = old_bss_addr;
   new_data2_size = new_bss_addr - old_bss_addr;
-#if !defined (__sony_news) || !defined (_SYSTYPE_SYSV)
+#ifndef HAVE_MIPS_SBSS
   new_data2_offset = OLD_SECTION_H (old_bss_index).sh_offset;
-#endif /*  not (__sony_news && _SYSTYPE_SYSV) */
+#endif /*  not HAVE_MIPS_SBSS */
 
 #ifdef DEBUG
   fprintf (stderr, "old_bss_index %d\n", old_bss_index);
@@ -811,14 +868,14 @@
       if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
 	alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
 
-#if defined (__sony_news) && defined (_SYSTYPE_SYSV)
+#ifdef HAVE_MIPS_SBSS
       if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz
 	  > round_up (old_bss_addr, alignment))
 	fatal ("Program segment above .bss in %s\n", old_name, 0);
-#else /* not (__sony_news && _SYSTYPE_SYSV) */
+#else /* not HAVE_MIPS_SBSS */
       if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_bss_addr)
 	fatal ("Program segment above .bss in %s\n", old_name, 0);
-#endif /* not (__sony_news && _SYSTYPE_SYSV) */
+#endif /* not HAVE_MIPS_SBSS */
 
       if (NEW_PROGRAM_H (n).p_type == PT_LOAD
 	  && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
@@ -830,11 +887,16 @@
   if (n < 0)
     fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
 
+#ifdef HAVE_MIPS_SBSS
+  bss_phdr_index = n;
+#endif
+
   /* Make sure that the size includes any padding before the old .bss
      section.  */
   NEW_PROGRAM_H (n).p_filesz = new_bss_addr - NEW_PROGRAM_H (n).p_vaddr;
   NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
 
+
 #if 0 /* Maybe allow section after data2 - does this ever happen? */
   for (n = new_file_h->e_phnum - 1; n >= 0; n--)
     {
@@ -867,15 +929,15 @@
     {
       caddr_t src;
       int temp_index;
-#if defined (__sony_news) && defined (_SYSTYPE_SYSV)
+#ifdef HAVE_MIPS_SBSS
       /* If it is (s)bss section, insert the new data2 section before it.  */
       /* new_data2_index is the index of either old_sbss or old_bss, that was
 	 chosen as a section for new_data2.   */
       temp_index = new_data2_index;
-#else /* not (__sony_news && _SYSTYPE_SYSV) */
+#else /* not HAVE_MIPS_SBSS */
       /* If it is bss section, insert the new data2 section before it.  */
       temp_index = old_bss_index;
-#endif /* not (__sony_news && _SYSTYPE_SYSV) */
+#endif /* not HAVE_MIPS_SBSS */
       if (n == temp_index)
 	{
 	  /* Steal the data section header for this data2 section. */
@@ -901,11 +963,11 @@
 	      old_file_h->e_shentsize);
       
       if (n == old_bss_index
-#if defined (__sony_news) && defined (_SYSTYPE_SYSV)
+#ifdef HAVE_MIPS_SBSS
 	  /* The new bss and sbss section's size is zero, and its file offset
 	     and virtual address should be off by NEW_DATA2_SIZE.  */
 	  || n == old_sbss_index
-#endif /* __sony_news and _SYSTYPE_SYSV */
+#endif /* HAVE_MIPS_SBSS */
 	  )
 	{
 	  /* NN should be `old_bss_index + 1' at this point. */
@@ -916,6 +978,23 @@
 	     this section will be placed in exactly the same place. */
 	  NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign;
 	  NEW_SECTION_H (nn).sh_size = 0;
+#ifdef HAVE_MIPS_SBSS
+	  /* on netbsd/mips, .sbss and .bss segments end up at different
+	     addresses (due to padding?), far enough that strip decides
+	     the .bss is not covered by the program header. Since both
+	     sbss and bss are zero-sized,  just use the same addr and
+	     file offset for both, guaranteeing other tools will
+	     assign them to the same program section. XXX asssumes no
+	     loaded sections at higher offsets.  */
+
+	  if (n == old_bss_index) {
+	    	 int new_sbss_bss_pad = NEW_SECTION_H(nn).sh_addr -
+		    NEW_SECTION_H(nn - 1).sh_addr;
+		printf("sbss to bss offset =0x%x\n", new_sbss_bss_padding);
+		NEW_SECTION_H(nn).sh_addr =NEW_SECTION_H(nn - 1).sh_addr;
+		NEW_SECTION_H(nn).sh_offset =NEW_SECTION_H(nn - 1).sh_offset;
+	  }
+#endif  /* HAVE_MIPS_SBSS */
 	}
       else
 	{
@@ -970,14 +1049,14 @@
 	  || !strcmp ((old_section_names + NEW_SECTION_H(n).sh_name),
 		      ".sdata")
 #endif
-#if defined (__sony_news) && defined (_SYSTYPE_SYSV)
+#ifdef HAVE_MIPS_SBSS
 	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
 		      ".sdata")
 	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
 		      ".lit4")
 	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
 		      ".lit8")
-#endif /* __sony_news && _SYSTYPE_SYSV */
+#endif /* HAVE_MIPS_SBSS */
 	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
 		      ".data1"))
 	src = (caddr_t) OLD_SECTION_H (n).sh_addr;
@@ -993,22 +1072,11 @@
 	  == 0)
 	{
 	  pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base);
-
-	  symhdr->cbLineOffset += new_data2_size;
-	  symhdr->cbDnOffset += new_data2_size;
-	  symhdr->cbPdOffset += new_data2_size;
-	  symhdr->cbSymOffset += new_data2_size;
-	  symhdr->cbOptOffset += new_data2_size;
-	  symhdr->cbAuxOffset += new_data2_size;
-	  symhdr->cbSsOffset += new_data2_size;
-	  symhdr->cbSsExtOffset += new_data2_size;
-	  symhdr->cbFdOffset += new_data2_size;
-	  symhdr->cbRfdOffset += new_data2_size;
-	  symhdr->cbExtOffset += new_data2_size;
+	  relocate_ecoff_symhdr(symhdr, new_data2_size);
 	}
 #endif /* __alpha__ */
 
-#if defined (__sony_news) && defined (_SYSTYPE_SYSV)
+#ifdef HAVE_MIPS_SBSS
       if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG && old_mdebug_index) 
         {
 	  int diff = NEW_SECTION_H(nn).sh_offset 
@@ -1017,20 +1085,17 @@
 
 	  if (diff)
 	    {
-	      phdr->cbLineOffset += diff;
-	      phdr->cbDnOffset   += diff;
-	      phdr->cbPdOffset   += diff;
-	      phdr->cbSymOffset  += diff;
-	      phdr->cbOptOffset  += diff;
-	      phdr->cbAuxOffset  += diff;
-	      phdr->cbSsOffset   += diff;
-	      phdr->cbSsExtOffset += diff;
-	      phdr->cbFdOffset   += diff;
-	      phdr->cbRfdOffset  += diff;
-	      phdr->cbExtOffset  += diff;
+#if defined ( __sony_news) && defined (_SYSTYPE_SYSV)
+	      relocate_ecoff_symhdr(phdr, diff);
+#else
+	      /* xxxBSD with  GNU binutils has .mdebug, but not ecoff(???)  */
+#ifdef DEBUG
+	      printf("Dont know how to relocate mdebug syms by %0x\n", diff);
+#endif
+#endif
 	    }
 	}
-#endif /* __sony_news && _SYSTYPE_SYSV */
+#endif /* HAVE_MIPS_SBSS */
       /* If it is the symbol table, its st_shndx field needs to be patched.  */
       if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
 	  || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)