]> code.delx.au - gnu-emacs/blobdiff - src/unexsgi.c
* window.c (Fwindow_live_p): Use WINDOW_LIVE_P.
[gnu-emacs] / src / unexsgi.c
index 41df908d5a4a55926fdc42bbd4bb529d751f8b19..cd0067f08d93942f38b23eee49cd3275df90f23c 100644 (file)
@@ -1,19 +1,22 @@
 /* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992
    Free Software Foundation, Inc.
 
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2, or (at your option)
-    any later version.
+This file is part of GNU Emacs.
 
-    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.
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
 
-    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
 
 In other words, you are welcome to use, share and improve this program.
 You are forbidden to forbid anyone else to use, share and improve
@@ -409,6 +412,7 @@ Filesz      Memsz       Flags       Align
 
  */
 \f
+#include <config.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <sys/stat.h>
@@ -458,6 +462,45 @@ round_up (x, y)
   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;
+     Elf32_Ehdr *old_file_h;
+     Elf32_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 .bss in %s.\n", file_name, 0);
+    }
+
+  return idx;
+}
+
 /* ****************************************************************
  * unexec
  *
@@ -526,51 +569,20 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
     = (char *) old_base + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
 
   /* Find the mdebug section, if any.  */
-  for (old_mdebug_index = 1; old_mdebug_index < 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 = -1;     /* just means no such section was present */
+
+  old_mdebug_index = find_section (".mdebug", old_section_names,
+                                  old_name, old_file_h, old_section_h, 1);
 
   /* Find the old .bss section. */
 
-  for (old_bss_index = 1; old_bss_index < 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,
-                  ".bss"))
-       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);
 
   /* Find the old .data section.  Figure out parameters of
      the new data2 and bss sections.  */
 
-  for (old_data_index = 1;
-       old_data_index < old_file_h->e_shnum;
-       old_data_index++)
-    {
-#ifdef DEBUG
-      fprintf (stderr, "Looking for .data - found %s\n",
-              old_section_names + OLD_SECTION_H(old_data_index).sh_name);
-#endif
-      if (!strcmp (old_section_names + OLD_SECTION_H(old_data_index).sh_name,
-                  ".data"))
-       break;
-    }
-  if (old_data_index == old_file_h->e_shnum)
-    fatal ("Can't find .data in %s.\n", old_name, 0);
+  old_data_index = find_section (".data", old_section_names,
+                                old_name, old_file_h, old_section_h, 0);
 
   old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
   old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
@@ -713,16 +725,9 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
     {
       caddr_t src;
 
-      if (n < old_bss_index)
+      /* If it is bss section, insert the new data2 section before it.  */
+      if (n == old_bss_index)
        {
-         memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n), 
-                 old_file_h->e_shentsize);
-         
-       }
-      else if (n == old_bss_index)
-       {
-         
-         /* If it is bss section, insert the new data2 section before it.  */
          /* Steal the data section header for this data2 section.  */
          memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
                  new_file_h->e_shentsize);
@@ -753,20 +758,18 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
          NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign;
          NEW_SECTION_H (nn).sh_size = 0;
        }
-      else                     /* n > old_bss_index */
+      else
        {
-         
          memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n), 
                  old_file_h->e_shentsize);
-      
-       }
 
-      /* Any section that was original placed AFTER the bss
-        section must now be adjusted by NEW_OFFSETS_SHIFT.  */
+         /* Any section that was original placed AFTER the bss
+            section must now be adjusted by NEW_OFFSETS_SHIFT.  */
+
+         if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
+           NEW_SECTION_H (nn).sh_offset += new_offsets_shift;
+       }
 
-      if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
-       NEW_SECTION_H (nn).sh_offset += new_offsets_shift;
-      
       /* If any section hdr refers to the section after the new .data
         section, make it refer to next one because we have inserted 
         a new section in between.  */
@@ -786,9 +789,18 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
       /* Write out the sections. .data and .data1 (and data2, called
         ".data" in the strings table) get copied from the current process
         instead of the old file.  */
-      if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
-         || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1")
-         || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".got"))
+      if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
+         || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data1")
+#ifdef IRIX6_5
+         /* Under IRIX 6.5 gcc places objects with adresses relative to 
+            shared symbols in the section .rodata, which are adjusted at
+            startup time. Unfortunately they aren't adjusted after unexec,
+            so with this configuration we must get .rodata also from memory. 
+            Do any other configurations need this, too?
+            <Wolfgang.Glas@hfm.tu-graz.ac.at> 1999-06-08.  */
+         || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".rodata")
+#endif
+         || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".got"))
        src = (caddr_t) OLD_SECTION_H (n).sh_addr;
       else
        src = old_base + OLD_SECTION_H (n).sh_offset;
@@ -859,9 +871,9 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
                                           + new_base);
          for (; num--; sym++)
            {
+             /* don't patch special section indices. */
              if (sym->st_shndx == SHN_UNDEF
-                 || sym->st_shndx == SHN_ABS
-                 || sym->st_shndx == SHN_COMMON)
+                 || sym->st_shndx >= SHN_LORESERVE)
                continue;
        
              PATCH_INDEX (sym->st_shndx);