最近の 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> ======