From a917c1886654dbabdfd6ad98aad66314f01f11b7 Mon Sep 17 00:00:00 2001 From: tomo Date: Wed, 24 May 2000 11:40:13 +0000 Subject: [PATCH] Sync with Emacs 20.6.90 to fix problem with latest binutils on Linux. --- src/unexelf.c | 199 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 110 insertions(+), 89 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index d91ae33..ffce626 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992, 1993 +/* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992, 1993, 1999, 2000 Free Software Foundation, Inc. This file is part of XEmacs. @@ -18,7 +18,7 @@ along with XEmacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Synched up with: FSF 20.4. */ +/* Synched up with: FSF 20.6.90. */ /* * unexec.c - Convert a running program into an a.out file. @@ -49,11 +49,6 @@ Boston, MA 02111-1307, USA. */ * 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 @@ -63,9 +58,6 @@ Boston, MA 02111-1307, USA. */ * * 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@bigtex.cactus.org of Dell Computer Co. @@ -433,7 +425,7 @@ extern void fatal (const char *, ...); #include #endif /* __sony_news && _SYSTYPE_SYSV */ #ifdef __sgi -#include /* for HDRR declaration */ +#include /* for HDRR declaration */ #endif /* __sgi */ #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__) @@ -482,26 +474,18 @@ typedef struct { # endif # include -# 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 +# 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,10 +505,18 @@ typedef struct { #ifndef ElfW # ifdef __STDC__ -# define ElfW(type) Elf32_##type +# define ElfBitsW(bits, type) Elf##bits##_##type +# else +# define ElfBitsW(bits, type) Elf/**/bits/**/_/**/type +# endif +# ifdef _LP64 +# define ELFSIZE 64 # else -# define ElfW(type) Elf32_/**/type +# 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,6 +576,45 @@ round_up (ElfW(Addr) x, ElfW(Addr) 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; + 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,8 +650,10 @@ unexec (char *new_name, char *old_name, unsigned int data_start, 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; + 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,65 +684,43 @@ unexec (char *new_name, char *old_name, unsigned int data_start, 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. */ - 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); + old_bss_index = find_section (".bss", old_section_names, + old_name, old_file_h, old_section_h, 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 = 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; - 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; + + 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_offset = OLD_SECTION_H(old_sbss_index).sh_offset; + 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; } - 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; + /* 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); @@ -718,6 +729,8 @@ unexec (char *new_name, char *old_name, unsigned int data_start, #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,13 +815,13 @@ unexec (char *new_name, char *old_name, unsigned int data_start, if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) alignment = OLD_SECTION_H (old_bss_index).sh_addralign; -#ifdef __mips +#ifdef __sgi /* According to r02kar@x4u2.desy.de (Karsten Kuenne) and oliva@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 */ +#endif /* __sgi */ if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > (old_sbss_index == -1 ? old_bss_addr @@ -944,6 +957,15 @@ unexec (char *new_name, char *old_name, unsigned int data_start, 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,18 +981,18 @@ unexec (char *new_name, char *old_name, unsigned int data_start, /* 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")) + ".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,7 +1022,8 @@ unexec (char *new_name, char *old_name, unsigned int data_start, #endif /* __alpha__ */ #if defined (__sony_news) && defined (_SYSTYPE_SYSV) - if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG && old_mdebug_index) + 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,14 +1161,12 @@ unexec (char *new_name, char *old_name, unsigned int data_start, 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), -- 1.7.10.4