X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Funexelf.c;h=54c48e107b7899c48e4b9b5fb286f83693f53fba;hb=115dcb8ceda461c57c7ec110071e24da4df1e9b4;hp=ffce6267081e3435bbaba35f4b7572b9cd8cc01b;hpb=a917c1886654dbabdfd6ad98aad66314f01f11b7;p=chise%2Fxemacs-chise.git- diff --git a/src/unexelf.c b/src/unexelf.c index ffce626..54c48e1 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992, 1993, 1999, 2000 +/* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992, 1993 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.6.90. */ +/* Synched up with: FSF 20.4. */ /* * unexec.c - Convert a running program into an a.out file. @@ -49,6 +49,11 @@ 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 @@ -58,6 +63,9 @@ 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. @@ -416,7 +424,7 @@ extern void fatal (const char *, ...); #include #include #include -#if !defined (__NetBSD__) && !defined (__OpenBSD__) +#ifdef HAVE_ELF_H #include #endif #include @@ -425,7 +433,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__) @@ -474,19 +482,17 @@ typedef struct { # endif # include -# 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 +# 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 # ifdef __alpha__ # include @@ -505,18 +511,10 @@ typedef struct { #ifndef ElfW # ifdef __STDC__ -# define ElfBitsW(bits, type) Elf##bits##_##type +# define ElfW(type) Elf32_##type # else -# define ElfBitsW(bits, type) Elf/**/bits/**/_/**/type +# define ElfW(type) Elf32_/**/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 @@ -576,45 +574,6 @@ 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 * @@ -650,10 +609,8 @@ unexec (char *new_name, char *old_name, unsigned int data_start, 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; + 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. */ @@ -684,43 +641,77 @@ 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. */ - 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; + 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); - if (old_sbss_index == -1) + for (old_sbss_index = 1; old_sbss_index < (int) old_file_h->e_shnum; + old_sbss_index++) { - old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; - old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; +#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_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; + 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. */ + 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; - old_data_index = find_section (".data", old_section_names, - old_name, old_file_h, old_section_h, 0); + for (old_data_index = 1; old_data_index < (int) 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) + old_data_index = 0; #if defined (emacs) || !defined (DEBUG) new_bss_addr = (ElfW(Addr)) sbrk (0); @@ -815,13 +806,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 __sgi +#ifdef __mips /* 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 /* __sgi */ +#endif /* __mips */ if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > (old_sbss_index == -1 ? old_bss_addr @@ -957,15 +948,6 @@ 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 @@ -981,18 +963,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") - || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, - ".sbss")) + ".data1")) src = (caddr_t) OLD_SECTION_H (n).sh_addr; else src = old_base + OLD_SECTION_H (n).sh_offset; @@ -1022,8 +1004,7 @@ 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 != -1) + 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; @@ -1161,12 +1142,14 @@ 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),