Bump version to 24.2
[bpt/emacs.git] / src / unexelf.c
index b58c785..ac9c9e7 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1985-1988, 1990, 1992, 1999-2011
+/* Copyright (C) 1985-1988, 1990, 1992, 1999-2012
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -391,6 +391,7 @@ temacs:
 extern void fatal (const char *msgid, ...);
 
 #include <sys/types.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <memory.h>
@@ -452,7 +453,7 @@ typedef struct {
        long cbRfdOffset;
        long cbExtOffset;
 } HDRR, *pHDRR;
-#define cbHDRR sizeof(HDRR)
+#define cbHDRR sizeof (HDRR)
 #define hdrNil ((pHDRR)0)
 #endif
 
@@ -548,11 +549,11 @@ typedef struct {
    */
 
 #define OLD_SECTION_H(n) \
-     (*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
+     (*(ElfW (Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
 #define NEW_SECTION_H(n) \
-     (*(ElfW(Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
+     (*(ElfW (Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
 #define NEW_PROGRAM_H(n) \
-     (*(ElfW(Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
+     (*(ElfW (Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
 
 #define PATCH_INDEX(n) \
   do { \
@@ -562,8 +563,8 @@ typedef unsigned char byte;
 
 /* Round X up to a multiple of Y.  */
 
-static ElfW(Addr)
-round_up (ElfW(Addr) x, ElfW(Addr) y)
+static ElfW (Addr)
+round_up (ElfW (Addr) x, ElfW (Addr) y)
 {
   int rem = x % y;
   if (rem == 0)
@@ -580,7 +581,7 @@ round_up (ElfW(Addr) x, ElfW(Addr) y)
 
 static int
 find_section (const char *name, const char *section_names, const char *file_name,
-             ElfW(Ehdr) *old_file_h, ElfW(Shdr) *old_section_h, int noerror)
+             ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h, int noerror)
 {
   int idx;
 
@@ -634,24 +635,26 @@ unexec (const char *new_name, const char *old_name)
 
   /* Pointers to the file, program and section headers for the old and
      new files.  */
-  ElfW(Ehdr) *old_file_h, *new_file_h;
-  ElfW(Phdr) *old_program_h, *new_program_h;
-  ElfW(Shdr) *old_section_h, *new_section_h;
+  ElfW (Ehdr) *old_file_h, *new_file_h;
+  ElfW (Phdr) *old_program_h, *new_program_h;
+  ElfW (Shdr) *old_section_h, *new_section_h;
 
   /* Point to the section name table in the old file.  */
   char *old_section_names;
 
-  ElfW(Addr) old_bss_addr, new_bss_addr;
-  ElfW(Word) old_bss_size, new_data2_size;
-  ElfW(Off)  new_data2_offset;
-  ElfW(Addr) new_data2_addr;
-  ElfW(Off)  old_bss_offset;
-  ElfW(Word) new_data2_incr;
+  ElfW (Addr) old_bss_addr, new_bss_addr;
+  ElfW (Word) old_bss_size, new_data2_size;
+  ElfW (Off)  new_data2_offset;
+  ElfW (Addr) new_data2_addr;
+  ElfW (Off)  old_bss_offset;
+  ElfW (Word) new_data2_incr;
 
   int n, nn;
   int old_bss_index, old_sbss_index, old_plt_index;
   int old_data_index, new_data2_index;
+#if defined _SYSTYPE_SYSV || defined __sgi
   int old_mdebug_index;
+#endif
   struct stat stat_buf;
   int old_file_size;
 
@@ -687,16 +690,18 @@ unexec (const char *new_name, const char *old_name)
 
   /* Get pointers to headers & section names */
 
-  old_file_h = (ElfW(Ehdr) *) old_base;
-  old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff);
-  old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff);
+  old_file_h = (ElfW (Ehdr) *) old_base;
+  old_program_h = (ElfW (Phdr) *) ((byte *) old_base + old_file_h->e_phoff);
+  old_section_h = (ElfW (Shdr) *) ((byte *) old_base + old_file_h->e_shoff);
   old_section_names = (char *) old_base
     + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
 
   /* Find the mdebug section, if any.  */
 
+#if defined _SYSTYPE_SYSV || defined __sgi
   old_mdebug_index = find_section (".mdebug", old_section_names,
                                   old_name, old_file_h, old_section_h, 1);
+#endif
 
   /* Find the old .bss section.  Figure out parameters of the new
      data2 and bss sections.  */
@@ -754,7 +759,7 @@ unexec (const char *new_name, const char *old_name)
 
 #if defined (emacs) || !defined (DEBUG)
   new_break = sbrk (0);
-  new_bss_addr = (ElfW(Addr)) new_break;
+  new_bss_addr = (ElfW (Addr)) new_break;
 #else
   new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
 #endif
@@ -780,7 +785,7 @@ unexec (const char *new_name, const char *old_name)
   fprintf (stderr, "new_data2_incr %x\n", new_data2_incr);
 #endif
 
-  if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
+  if ((uintptr_t) new_bss_addr < (uintptr_t) old_bss_addr + old_bss_size)
     fatal (".bss shrank when undumping???\n", 0, 0);
 
   /* Set the output file to the right size.  Allocate a buffer to hold
@@ -801,9 +806,9 @@ unexec (const char *new_name, const char *old_name)
   if (new_base == MAP_FAILED)
     fatal ("Can't allocate buffer for %s\n", old_name, 0);
 
-  new_file_h = (ElfW(Ehdr) *) new_base;
-  new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
-  new_section_h = (ElfW(Shdr) *)
+  new_file_h = (ElfW (Ehdr) *) new_base;
+  new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
+  new_section_h = (ElfW (Shdr) *)
     ((byte *) new_base + old_file_h->e_shoff + new_data2_incr);
 
   /* Make our new file, program and section headers as copies of the
@@ -839,7 +844,7 @@ unexec (const char *new_name, const char *old_name)
   for (n = new_file_h->e_phnum - 1; n >= 0; n--)
     {
       /* Compute maximum of all requirements for alignment of section.  */
-      ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align;
+      ElfW (Word) alignment = (NEW_PROGRAM_H (n)).p_align;
       if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
        alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
 
@@ -1014,7 +1019,7 @@ temacs:
          /* The conditional bit below was in Oliva's original code
             (1999-08-25) and seems to have been dropped by mistake
             subsequently.  It prevents a crash at startup under X in
-            `IRIX64 6.5 6.5.17m', whether compiled on that relase or
+            `IRIX64 6.5 6.5.17m', whether compiled on that release or
             an earlier one.  It causes no trouble on the other ELF
             platforms I could test (Irix 6.5.15m, Solaris 8, Debian
             Potato x86, Debian Woody SPARC); however, it's reported
@@ -1048,7 +1053,7 @@ temacs:
       memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
              NEW_SECTION_H (nn).sh_size);
 
-#ifdef __alpha__
+#if defined __alpha__ && !defined __OpenBSD__
       /* Update Alpha COFF symbol table: */
       if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
          == 0)
@@ -1067,14 +1072,14 @@ temacs:
          symhdr->cbRfdOffset += new_data2_size;
          symhdr->cbExtOffset += new_data2_size;
        }
-#endif /* __alpha__ */
+#endif /* __alpha__ && !__OpenBSD__ */
 
 #if defined (_SYSTYPE_SYSV)
       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;
+         int diff = NEW_SECTION_H (nn).sh_offset
+               - OLD_SECTION_H (old_mdebug_index).sh_offset;
          HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
 
          if (diff)
@@ -1153,9 +1158,9 @@ temacs:
       if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
          || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
        {
-         ElfW(Shdr) *spt = &NEW_SECTION_H (nn);
+         ElfW (Shdr) *spt = &NEW_SECTION_H (nn);
          unsigned int num = spt->sh_size / spt->sh_entsize;
-         ElfW(Sym) * sym = (ElfW(Sym) *) (NEW_SECTION_H (nn).sh_offset +
+         ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset +
                                           new_base);
          for (; num--; sym++)
            {
@@ -1173,7 +1178,7 @@ temacs:
   for (n = new_file_h->e_shnum - 1; n; n--)
     {
       byte *symnames;
-      ElfW(Sym) *symp, *symendp;
+      ElfW (Sym) *symp, *symendp;
 
       if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM
          && NEW_SECTION_H (n).sh_type != SHT_SYMTAB)
@@ -1181,8 +1186,8 @@ temacs:
 
       symnames = ((byte *) new_base
                  + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset);
-      symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base);
-      symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
+      symp = (ElfW (Sym) *) (NEW_SECTION_H (n).sh_offset + new_base);
+      symendp = (ElfW (Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
 
       for (; symp < symendp; symp ++)
        {
@@ -1214,9 +1219,15 @@ temacs:
              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);
+             if (nn == old_bss_index)
+               memset (new, 0, symp->st_size);
+             else
+               {
+                 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
        }
@@ -1226,7 +1237,7 @@ temacs:
      that it can undo relocations performed by the runtime linker.  */
   for (n = new_file_h->e_shnum - 1; n; n--)
     {
-      ElfW(Shdr) section = NEW_SECTION_H (n);
+      ElfW (Shdr) section = NEW_SECTION_H (n);
 
       /* Cause a compilation error if anyone uses n instead of nn below.  */
       #define n ((void) 0);
@@ -1258,21 +1269,21 @@ temacs:
              || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
                          ".data1"))
            {
-             ElfW(Addr) offset = (NEW_SECTION_H (nn).sh_addr
+             ElfW (Addr) offset = (NEW_SECTION_H (nn).sh_addr
                                   - NEW_SECTION_H (nn).sh_offset);
              caddr_t reloc = old_base + section.sh_offset, end;
              for (end = reloc + section.sh_size; reloc < end;
                   reloc += section.sh_entsize)
                {
-                 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset;
+                 ElfW (Addr) addr = ((ElfW (Rel) *) reloc)->r_offset - offset;
 #ifdef __alpha__
                  /* The Alpha ELF binutils currently have a bug that
                     sometimes results in relocs that contain all
                     zeroes.  Work around this for now...  */
-                 if (((ElfW(Rel) *) reloc)->r_offset == 0)
+                 if (((ElfW (Rel) *) reloc)->r_offset == 0)
                    continue;
 #endif
-                 memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr)));
+                 memcpy (new_base + addr, old_base + addr, sizeof (ElfW (Addr)));
                }
            }
          break;