最近の Debian GNU/Linux の potato および woody で build できなかった件
ですが、最新の開発版の binutils に関わる問題だったようです。
同様の問題は Emacs でも起こっており、Emacs 20.6.90 でこれに対する修正
が入っていました。
これは XEmacs 21.2.33 およびこれを元にする UTF-2000 にほぼそのまま適用
可能であるようなので、patch を作ってみました。
なお、既に林さんもこの問題に対する patch を作ってらっしゃいますが、
Emacs 20.6.90 のものの方が section を探す部分が一般化されており筋が良
いような気がします。
また、Emacs 20.6.90 での修正は SGI の machine に対する修正も含んでいる
ようです。私の手元に SGI の machine がないので、この修正がちゃんと動く
のか確かめることができません。もし確認可能な方がいらっしゃるなら調べて
いただけないでしょうか?
林さん、もしよろしければ、林さんの修正とこの修正を比較検討して頂けない
でしょうか?
+ 2000-05-24  MORIOKA Tomohiko  <tomo(a)kanji.zinbun.kyoto-u.ac.jp>
+ 
+ 	* unexelf.c: Sync up with Emacs 20.6.90 to fix problem with most
+ 	current development versions of binutils.
+ 
Index: unexelf.c
===================================================================
RCS file: /cvs/root/XEmacs/src/unexelf.c,v
retrieving revision 1.1.3.2.6.2
retrieving revision 1.1.3.2.6.3
diff -c -r1.1.3.2.6.2 -r1.1.3.2.6.3
*** unexelf.c	2000/05/22 07:45:16	1.1.3.2.6.2
--- unexelf.c	2000/05/24 11:40:13	1.1.3.2.6.3
***************
*** 1,4 ****
! /* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992, 1993
     Free Software Foundation, Inc.
  
  This file is part of XEmacs.
--- 1,4 ----
! /* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992, 1993, 1999, 2000
     Free Software Foundation, Inc.
  
  This file is part of XEmacs.
***************
*** 18,24 ****
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! /* Synched up with: FSF 20.4. */
  
  /*
   * unexec.c - Convert a running program into an a.out file.
--- 18,24 ----
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! /* Synched up with: FSF 20.6.90. */
  
  /*
   * unexec.c - Convert a running program into an a.out file.
***************
*** 49,59 ****
   * The value you specify may be rounded down to a suitable boundary
   * as required by the machine you are using.
   *
-  * Specifying zero for data_start means the boundary between text and data
-  * should not be the same as when the program was loaded.
-  * If NO_REMAP is defined, the argument data_start is ignored and the
-  * segment boundaries are never changed.
-  *
   * Bss_start indicates how much of the data segment is to be saved in the
   * a.out file and restored when the program is executed.  It gives the lowest
   * unsaved address, and is rounded up to a page boundary.  The default when 0
--- 49,54 ----
***************
*** 63,71 ****
   *
   * The new file is set up to start at entry_address.
   *
-  * If you make improvements I'd like to get them too.
-  * harpo!utah-cs!thomas, thomas@Utah-20
-  *
   */
  
  /* Even more heavily modified by james(a)bigtex.cactus.org of Dell Computer Co.
--- 58,63 ----
***************
*** 433,439 ****
  #include <sym.h>
  #endif /* __sony_news && _SYSTYPE_SYSV */
  #ifdef __sgi
! #include <sym.h> /* for HDRR declaration */
  #endif /* __sgi */
  
  #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__)
--- 425,431 ----
  #include <sym.h>
  #endif /* __sony_news && _SYSTYPE_SYSV */
  #ifdef __sgi
! #include <syms.h> /* for HDRR declaration */
  #endif /* __sgi */
  
  #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__)
***************
*** 482,507 ****
  # endif
  # include <sys/exec_elf.h>
  
! # define PT_LOAD	Elf_pt_load
! # define SHT_SYMTAB	Elf_sht_symtab
! # define SHT_DYNSYM	Elf_sht_dynsym
! # define SHT_NULL	Elf_sht_null
! # define SHT_NOBITS	Elf_sht_nobits
! # define SHT_REL	Elf_sht_rel
! # define SHT_RELA	Elf_sht_rela
! 
! # define SHN_UNDEF	Elf_eshn_undefined
! # 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__
--- 474,491 ----
  # endif
  # include <sys/exec_elf.h>
  
! # ifndef PT_LOAD
! #  define PT_LOAD	Elf_pt_load
! #  define SHT_SYMTAB	Elf_sht_symtab
! #  define SHT_DYNSYM	Elf_sht_dynsym
! #  define SHT_NULL	Elf_sht_null
! #  define SHT_NOBITS	Elf_sht_nobits
! #  define SHT_REL	Elf_sht_rel
! #  define SHT_RELA	Elf_sht_rela
! 
! #  define SHN_UNDEF	Elf_eshn_undefined
! #  define SHN_ABS	Elf_eshn_absolute
! #  define SHN_COMMON	Elf_eshn_common
  # endif
  
  # ifdef __alpha__
***************
*** 521,530 ****
  
  #ifndef ElfW
  # ifdef __STDC__
! #  define ElfW(type)	Elf32_##type
  # else
! #  define ElfW(type)	Elf32_/**/type
  # endif
  #endif
  
  #ifndef ELF_BSS_SECTION_NAME
--- 505,522 ----
  
  #ifndef ElfW
  # ifdef __STDC__
! #  define ElfBitsW(bits, type) Elf##bits##_##type
  # else
! #  define ElfBitsW(bits, type) Elf/**/bits/**/_/**/type
  # endif
+ # ifdef _LP64
+ #  define ELFSIZE 64
+ # else
+ #  define ELFSIZE 32
+ # endif
+   /* This macro expands `bits' before invoking ElfBitsW.  */
+ # define ElfExpandBitsW(bits, type) ElfBitsW (bits, type)
+ # define ElfW(type) ElfExpandBitsW (ELFSIZE, type)
  #endif
  
  #ifndef ELF_BSS_SECTION_NAME
***************
*** 584,589 ****
--- 576,620 ----
    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,626 ****
    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;
    struct stat stat_buf;
  
    /* Open the old file & map it into the address space. */
--- 650,659 ----
    ElfW(Off)  new_data2_offset;
    ElfW(Addr) new_data2_addr;
  
!   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,716 ****
    old_section_names = (char *) old_base
      + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
  
    /* 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);
  
!   for (old_sbss_index = 1; old_sbss_index < (int) old_file_h->e_shnum;
!        old_sbss_index++)
!     {
! #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;
        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;
        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;
  
  #if defined (emacs) || !defined (DEBUG)
    new_bss_addr = (ElfW(Addr)) sbrk (0);
  #else
--- 684,727 ----
    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.
     */
  
!   old_bss_index = find_section (".bss", old_section_names,
! 				old_name, old_file_h, old_section_h, 0);
  
!   old_sbss_index = find_section (".sbss", old_section_names,
! 				 old_name, old_file_h, old_section_h, 1);
!   if (old_sbss_index != -1)
!     if (OLD_SECTION_H (old_sbss_index).sh_type == SHT_PROGBITS)
        old_sbss_index = -1;
! 
!   if (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_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_index = old_sbss_index;
      }
  
!   /* 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);
  #else
***************
*** 718,723 ****
--- 729,736 ----
  #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,814 ****
        if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
  	alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
  
! #ifdef __mips
  	  /* According to r02kar(a)x4u2.desy.de (Karsten Kuenne)
  	     and oliva(a)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 */
        if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz
  	  > (old_sbss_index == -1
  	     ? old_bss_addr
--- 815,827 ----
        if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
  	alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
  
! #ifdef __sgi
  	  /* According to r02kar(a)x4u2.desy.de (Karsten Kuenne)
  	     and oliva(a)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 /* __sgi */
        if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz
  	  > (old_sbss_index == -1
  	     ? old_bss_addr
***************
*** 944,949 ****
--- 957,971 ----
        if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB
  	  && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM)
  	PATCH_INDEX (NEW_SECTION_H (nn).sh_info);
+       
+       if (old_sbss_index != -1)
+ 	if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".sbss"))
+ 	  {
+ 	    NEW_SECTION_H (nn).sh_offset = 
+ 	      round_up (NEW_SECTION_H (nn).sh_offset,
+ 			NEW_SECTION_H (nn).sh_addralign);
+ 	    NEW_SECTION_H (nn).sh_type = SHT_PROGBITS;
+ 	  }
  
        /* Now, start to copy the content of sections.  */
        if (NEW_SECTION_H (nn).sh_type == SHT_NULL
***************
*** 959,976 ****
            /* 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"))
  	src = (caddr_t) OLD_SECTION_H (n).sh_addr;
        else
  	src = old_base + OLD_SECTION_H (n).sh_offset;
--- 981,998 ----
            /* 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 */
  	  || !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")
  	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
  		      ".sdata1")
  	  || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
! 		      ".data1")
! 	  || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name,
! 		      ".sbss"))
  	src = (caddr_t) OLD_SECTION_H (n).sh_addr;
        else
  	src = old_base + OLD_SECTION_H (n).sh_offset;
***************
*** 1000,1006 ****
  #endif /* __alpha__ */
  
  #if defined (__sony_news) && defined (_SYSTYPE_SYSV)
!       if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG && old_mdebug_index) 
          {
  	  int diff = NEW_SECTION_H(nn).sh_offset 
  	 	- OLD_SECTION_H(old_mdebug_index).sh_offset;
--- 1022,1029 ----
  #endif /* __alpha__ */
  
  #if defined (__sony_news) && 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;
***************
*** 1138,1151 ****
  	if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
  	    || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
  			".sdata")
- #ifdef __sgi
  	    || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
  			".lit4")
  	    || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
  			".lit8")
  	    || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
  			".got")
- #endif
  	    || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
  			".sdata1")
  	    || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
--- 1161,1172 ----
-- 
===『幾千億の分子に分かれても ========================================
     決して忘れない。    
     この宇宙が終るまで』              守岡 知彦 (MORIOKA Tomohiko)
====================== Email: <tomo(a)kanji.zinbun.kyoto-u.ac.jp> ======