commit emacs for openSUSE:Factory
Hello community, here is the log from the commit of package emacs for openSUSE:Factory checked in at 2016-02-28 02:25:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/emacs (Old) and /work/SRC/openSUSE:Factory/.emacs.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "emacs" Changes: -------- --- /work/SRC/openSUSE:Factory/emacs/emacs.changes 2015-12-01 10:01:32.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.emacs.new/emacs.changes 2016-02-28 02:25:23.000000000 +0100 @@ -1,0 +2,17 @@ +Tue Feb 2 14:18:51 UTC 2016 - normand@linux.vnet.ibm.com + +- Add a set of patches to avoid build error with binutils 2.28 + emacs-24-0010-ELF-unexec-Correct-section-header-index.patch + emacs-24-0011-ELF-unexec-Tidy-code.patch + emacs-24-0012-ELF-unexec-Merge-Alpha-and-MIPS-COFF-debug-handling.patch + emacs-24-0013-ELF-unexec-Symbol-table-patching.patch + emacs-24-0014-ELF-unexec-_OBJC_-symbols-in-bss-sections.patch + emacs-24-0015-ELF-unexec-R_-_NONE-relocs.patch + emacs-24-0016-ELF-unexec-Drive-from-PT_LOAD-header-rather-than-sec.patch + emacs-24-0017-ELF-unexec-Don-t-insert-a-new-section.patch + emacs-24-0018-src-unexelf.c-NEW_PROGRAM_H-Remove-unused-macro-Bug-.patch + emacs-24-0019-ELF-unexec-align-section-header.patch + list previously identified in debian bug + https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=808347 + +------------------------------------------------------------------- New: ---- emacs-24-0010-ELF-unexec-Correct-section-header-index.patch emacs-24-0011-ELF-unexec-Tidy-code.patch emacs-24-0012-ELF-unexec-Merge-Alpha-and-MIPS-COFF-debug-handling.patch emacs-24-0013-ELF-unexec-Symbol-table-patching.patch emacs-24-0014-ELF-unexec-_OBJC_-symbols-in-bss-sections.patch emacs-24-0015-ELF-unexec-R_-_NONE-relocs.patch emacs-24-0016-ELF-unexec-Drive-from-PT_LOAD-header-rather-than-sec.patch emacs-24-0017-ELF-unexec-Don-t-insert-a-new-section.patch emacs-24-0018-src-unexelf.c-NEW_PROGRAM_H-Remove-unused-macro-Bug-.patch emacs-24-0019-ELF-unexec-align-section-header.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ emacs.spec ++++++ --- /var/tmp/diff_new_pack.BVAU62/_old 2016-02-28 02:25:26.000000000 +0100 +++ /var/tmp/diff_new_pack.BVAU62/_new 2016-02-28 02:25:26.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package emacs # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -114,6 +114,18 @@ Patch15: emacs-24.3-iconic.patch Patch16: emacs-24.4-flyspell.patch Patch22: emacs-24.1-bnc628268.patch + +Patch30: emacs-24-0010-ELF-unexec-Correct-section-header-index.patch +Patch31: emacs-24-0011-ELF-unexec-Tidy-code.patch +Patch32: emacs-24-0012-ELF-unexec-Merge-Alpha-and-MIPS-COFF-debug-handling.patch +Patch33: emacs-24-0013-ELF-unexec-Symbol-table-patching.patch +Patch34: emacs-24-0014-ELF-unexec-_OBJC_-symbols-in-bss-sections.patch +Patch35: emacs-24-0015-ELF-unexec-R_-_NONE-relocs.patch +Patch36: emacs-24-0016-ELF-unexec-Drive-from-PT_LOAD-header-rather-than-sec.patch +Patch37: emacs-24-0017-ELF-unexec-Don-t-insert-a-new-section.patch +Patch38: emacs-24-0018-src-unexelf.c-NEW_PROGRAM_H-Remove-unused-macro-Bug-.patch +Patch39: emacs-24-0019-ELF-unexec-align-section-header.patch + BuildRoot: %{_tmppath}/%{name}-%{version}-build %{expand: %%global include_info %(test -s /usr/share/info/info.info* && echo 0 || echo 1)} %{expand: %%global _exec_prefix %(type -p pkg-config &>/dev/null && pkg-config --variable prefix x11 || echo /usr/X11R6)} @@ -228,6 +240,16 @@ %patch16 -p0 -b .flyspell %patch22 -p0 -b .obsolate %patch -p0 -b .0 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 %if %{without autoconf} # We don't want to run autoconf ++++++ emacs-24-0010-ELF-unexec-Correct-section-header-index.patch ++++++
From 0a97fb1992c8cc3612a2358f576f774ea1f36777 Mon Sep 17 00:00:00 2001 From: Alan Modra <amodra@gmail.com> Date: Sun, 8 Nov 2015 09:28:59 -0800 Subject: ELF unexec: Correct section header index
Emacs should build on ppc64el. A problem with the bss has been fixed. This upstream patch has been added [1/10]: ELF unexec: Correct section header index First a small fix. The code incorrectly uses "NEW_SECTION_H (n)" when it should have been using "NEW_SECTION_H (nn)" to find the name of the section currently being processed. Of course, before the bss sections, n and nn have the same value, so this doesn't matter except in the case of .sbss. For .sbss this probably meant .bss (most likely the next section) was copied from memory. A later patch removes the bogus .sbss handling anyway. * unexelf.c (unexec): Use correct index to look up names. Origin: upstream, commit: 0bcd08ef052bca9b8d08696068c2a0c387d0dd56 Bug: http://debbugs.gnu.org/20614 Bug-Debian: http://bugs.debian.org/808347 Added-by: Rob Browning <rlb@defaultvalue.org> --- src/unexelf.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index 59e2725..d4a36f8 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -1016,12 +1016,12 @@ temacs: /* Write out the sections. .data and .data1 (and data2, called ".data" in the strings table) get copied from the current process instead of the old file. */ - if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") - || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), + if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") + || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), ".sdata") - || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), + || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), ".lit4") - || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), + || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), ".lit8") /* The conditional bit below was in Oliva's original code (1999-08-25) and seems to have been dropped by mistake @@ -1044,14 +1044,14 @@ temacs: loader, but I never got anywhere with an SGI support call seeking clues. -- fx 2002-11-29. */ #ifdef IRIX6_5 - || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), + || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), ".got") #endif - || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), + || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), ".sdata1") - || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), + || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), ".data1") - || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), + || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), ".sbss")) src = (caddr_t) OLD_SECTION_H (n).sh_addr; else ++++++ emacs-24-0011-ELF-unexec-Tidy-code.patch ++++++
From 9fa97f0c2c1afae39b6662a836910deb1e0130ad Mon Sep 17 00:00:00 2001 From: Alan Modra <amodra@gmail.com> Date: Sun, 8 Nov 2015 09:28:59 -0800 Subject: ELF unexec: Tidy code
Emacs should build on ppc64el. A problem with the bss has been fixed. This upstream patch has been added [2/10]: ELF unexec: Tidy code Separate out some of the more mechanical changes so following patches are smaller. * unexelf.c (unexec): Rearrange initialisation of program header vars. Use pointer vars in loops rather than indexing section header array via macros. Simplify _OBJC_ sym code and reloc handling code. Origin: upstream, commit: 856f4eaba8a76953e0bbcfc7ebb0ca4f2e3cf351 Bug: http://debbugs.gnu.org/20614 Bug-Debian: http://bugs.debian.org/808347 Added-by: Rob Browning <rlb@defaultvalue.org> --- src/unexelf.c | 210 +++++++++++++++++++++++++++------------------------------- 1 file changed, 96 insertions(+), 114 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index d4a36f8..f7465cb 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -813,20 +813,11 @@ unexec (const char *new_name, const char *old_name) if (new_base == MAP_FAILED) fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno)); - 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 originals. */ + new_file_h = (ElfW (Ehdr) *) new_base; memcpy (new_file_h, old_file_h, old_file_h->e_ehsize); - memcpy (new_program_h, old_program_h, - old_file_h->e_phnum * old_file_h->e_phentsize); - - /* Modify the e_shstrndx if necessary. */ - PATCH_INDEX (new_file_h->e_shstrndx); /* Fix up file header. We'll add one section. Section header is further away now. */ @@ -834,6 +825,16 @@ unexec (const char *new_name, const char *old_name) new_file_h->e_shoff += new_data2_incr; new_file_h->e_shnum += 1; + /* Modify the e_shstrndx if necessary. */ + PATCH_INDEX (new_file_h->e_shstrndx); + + 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); + + memcpy (new_program_h, old_program_h, + old_file_h->e_phnum * old_file_h->e_phentsize); + #ifdef UNEXELF_DEBUG DEBUG_LOG (old_file_h->e_shoff); fprintf (stderr, "Old section count %td\n", (ptrdiff_t) old_file_h->e_shnum); @@ -906,32 +907,35 @@ unexec (const char *new_name, const char *old_name) for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++) { caddr_t src; + ElfW (Shdr) *old_shdr = &OLD_SECTION_H (n); + ElfW (Shdr) *new_shdr = &NEW_SECTION_H (nn); + /* If it is (s)bss section, insert the new data2 section before it. */ /* new_data2_index is the index of either old_sbss or old_bss, that was chosen as a section for new_data2. */ if (n == new_data2_index) { /* Steal the data section header for this data2 section. */ - memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index), + memcpy (new_shdr, &OLD_SECTION_H (old_data_index), new_file_h->e_shentsize); - NEW_SECTION_H (nn).sh_addr = new_data2_addr; - NEW_SECTION_H (nn).sh_offset = new_data2_offset; - NEW_SECTION_H (nn).sh_size = new_data2_size; + new_shdr->sh_addr = new_data2_addr; + new_shdr->sh_offset = new_data2_offset; + new_shdr->sh_size = new_data2_size; /* Use the bss section's alignment. This will assure that the new data2 section always be placed in the same spot as the old bss section by any other application. */ - NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign; + new_shdr->sh_addralign = old_shdr->sh_addralign; /* Now copy over what we have in the memory now. */ - memcpy (NEW_SECTION_H (nn).sh_offset + new_base, - (caddr_t) OLD_SECTION_H (n).sh_addr, + memcpy (new_shdr->sh_offset + new_base, + (caddr_t) old_shdr->sh_addr, new_data2_size); nn++; + new_shdr++; } - memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n), - old_file_h->e_shentsize); + memcpy (new_shdr, old_shdr, old_file_h->e_shentsize); if (n == old_bss_index /* The new bss and sbss section's size is zero, and its file offset @@ -940,13 +944,13 @@ unexec (const char *new_name, const char *old_name) ) { /* NN should be `old_s?bss_index + 1' at this point. */ - NEW_SECTION_H (nn).sh_offset = new_data2_offset + new_data2_size; - NEW_SECTION_H (nn).sh_addr = new_data2_addr + new_data2_size; + new_shdr->sh_offset = new_data2_offset + new_data2_size; + new_shdr->sh_addr = new_data2_addr + new_data2_size; /* Let the new bss section address alignment be the same as the section address alignment followed the old bss section, so this section will be placed in exactly the same place. */ - NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign; - NEW_SECTION_H (nn).sh_size = 0; + new_shdr->sh_addralign = OLD_SECTION_H (nn).sh_addralign; + new_shdr->sh_size = 0; } else { @@ -976,53 +980,50 @@ temacs: 25 1709 0x4 0x10 */ - if (NEW_SECTION_H (nn).sh_offset >= old_bss_offset - || (NEW_SECTION_H (nn).sh_offset + NEW_SECTION_H (nn).sh_size + if (new_shdr->sh_offset >= old_bss_offset + || (new_shdr->sh_offset + new_shdr->sh_size > new_data2_offset)) - NEW_SECTION_H (nn).sh_offset += new_data2_incr; + new_shdr->sh_offset += new_data2_incr; /* Any section that was originally placed after the section header table should now be off by the size of one section header table entry. */ - if (NEW_SECTION_H (nn).sh_offset > new_file_h->e_shoff) - NEW_SECTION_H (nn).sh_offset += new_file_h->e_shentsize; + if (new_shdr->sh_offset > new_file_h->e_shoff) + new_shdr->sh_offset += new_file_h->e_shentsize; } /* If any section hdr refers to the section after the new .data section, make it refer to next one because we have inserted a new section in between. */ - PATCH_INDEX (NEW_SECTION_H (nn).sh_link); + PATCH_INDEX (new_shdr->sh_link); /* For symbol tables, info is a symbol table index, so don't change it. */ - 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 (new_shdr->sh_type != SHT_SYMTAB + && new_shdr->sh_type != SHT_DYNSYM) + PATCH_INDEX (new_shdr->sh_info); if (old_sbss_index != -1) - if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".sbss")) + if (!strcmp (old_section_names + new_shdr->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; + new_shdr->sh_offset = + round_up (new_shdr->sh_offset, + new_shdr->sh_addralign); + new_shdr->sh_type = SHT_PROGBITS; } /* Now, start to copy the content of sections. */ - if (NEW_SECTION_H (nn).sh_type == SHT_NULL - || NEW_SECTION_H (nn).sh_type == SHT_NOBITS) + if (new_shdr->sh_type == SHT_NULL + || new_shdr->sh_type == SHT_NOBITS) continue; /* Write out the sections. .data and .data1 (and data2, called ".data" in the strings table) get copied from the current process instead of the old file. */ - if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") - || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), - ".sdata") - || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), - ".lit4") - || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), - ".lit8") + if (!strcmp (old_section_names + new_shdr->sh_name, ".data") + || !strcmp (old_section_names + new_shdr->sh_name, ".sdata") + || !strcmp (old_section_names + new_shdr->sh_name, ".lit4") + || !strcmp (old_section_names + new_shdr->sh_name, ".lit8") /* 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 @@ -1044,28 +1045,22 @@ temacs: loader, but I never got anywhere with an SGI support call seeking clues. -- fx 2002-11-29. */ #ifdef IRIX6_5 - || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), - ".got") + || !strcmp (old_section_names + new_shdr->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), - ".data1") - || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), - ".sbss")) - src = (caddr_t) OLD_SECTION_H (n).sh_addr; + || !strcmp (old_section_names + new_shdr->sh_name, ".sdata1") + || !strcmp (old_section_names + new_shdr->sh_name, ".data1") + || !strcmp (old_section_names + new_shdr->sh_name, ".sbss")) + src = (caddr_t) old_shdr->sh_addr; else - src = old_base + OLD_SECTION_H (n).sh_offset; + src = old_base + old_shdr->sh_offset; - memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, - NEW_SECTION_H (nn).sh_size); + memcpy (new_shdr->sh_offset + new_base, src, new_shdr->sh_size); #if defined __alpha__ && !defined __OpenBSD__ /* Update Alpha COFF symbol table: */ - if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug") - == 0) + if (strcmp (old_section_names + old_shdr->sh_name, ".mdebug") == 0) { - pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base); + pHDRR symhdr = (pHDRR) (new_shdr->sh_offset + new_base); symhdr->cbLineOffset += new_data2_size; symhdr->cbDnOffset += new_data2_size; @@ -1082,13 +1077,13 @@ temacs: #endif /* __alpha__ && !__OpenBSD__ */ #if defined (_SYSTYPE_SYSV) - if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG + if (new_shdr->sh_type == SHT_MIPS_DEBUG && old_mdebug_index != -1) { - ptrdiff_t new_offset = NEW_SECTION_H (nn).sh_offset; + ptrdiff_t new_offset = new_shdr->sh_offset; ptrdiff_t old_offset = OLD_SECTION_H (old_mdebug_index).sh_offset; ptrdiff_t diff = new_offset - old_offset; - HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base); + HDRR *phdr = (HDRR *) (new_shdr->sh_offset + new_base); if (diff) { @@ -1124,8 +1119,8 @@ temacs: n_phdrr->__fileaddr += movement; \ } - HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset); - HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset); + HDRR *o_phdrr = (HDRR *) ((byte *) old_base + old_shdr->sh_offset); + HDRR *n_phdrr = (HDRR *) ((byte *) new_base + new_shdr->sh_offset); unsigned movement = new_data2_size; MDEBUGADJUST (idnMax, cbDnOffset); @@ -1142,8 +1137,8 @@ temacs: requires special handling. */ if (n_phdrr->cbLine > 0) { - if (o_phdrr->cbLineOffset > (OLD_SECTION_H (n).sh_offset - + OLD_SECTION_H (n).sh_size)) + if (o_phdrr->cbLineOffset > (old_shdr->sh_offset + + old_shdr->sh_size)) { /* line data is in a hole in elf. do special copy and adjust for this ld mistake. @@ -1163,13 +1158,11 @@ temacs: #endif /* __sgi */ /* If it is the symbol table, its st_shndx field needs to be patched. */ - if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB - || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) + if (new_shdr->sh_type == SHT_SYMTAB + || new_shdr->sh_type == SHT_DYNSYM) { - ElfW (Shdr) *spt = &NEW_SECTION_H (nn); - ptrdiff_t num = spt->sh_size / spt->sh_entsize; - ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset + - new_base); + ptrdiff_t num = new_shdr->sh_size / new_shdr->sh_entsize; + ElfW (Sym) *sym = (ElfW (Sym) *) (new_shdr->sh_offset + new_base); for (; num--; sym++) { if ((sym->st_shndx == SHN_UNDEF) @@ -1187,15 +1180,16 @@ temacs: { byte *symnames; ElfW (Sym) *symp, *symendp; + ElfW (Shdr) *sym_shdr = &NEW_SECTION_H (n); - if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM - && NEW_SECTION_H (n).sh_type != SHT_SYMTAB) + if (sym_shdr->sh_type != SHT_DYNSYM + && sym_shdr->sh_type != SHT_SYMTAB) continue; 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); + + NEW_SECTION_H (sym_shdr->sh_link).sh_offset); + symp = (ElfW (Sym) *) (sym_shdr->sh_offset + new_base); + symendp = (ElfW (Sym) *) ((byte *) symp + sym_shdr->sh_size); for (; symp < symendp; symp ++) { @@ -1219,22 +1213,21 @@ temacs: if (strncmp ((char *) (symnames + symp->st_name), "_OBJC_", sizeof ("_OBJC_") - 1) == 0) { - caddr_t old, new; + ElfW (Shdr) *new_shdr = &NEW_SECTION_H (symp->st_shndx); + ptrdiff_t reladdr = symp->st_value - new_shdr->sh_addr; + ptrdiff_t newoff = reladdr + new_shdr->sh_offset; - new = ((symp->st_value - NEW_SECTION_H (symp->st_shndx).sh_addr) - + NEW_SECTION_H (symp->st_shndx).sh_offset + new_base); /* "Unpatch" index. */ nn = symp->st_shndx; if (nn > old_bss_index) nn--; if (nn == old_bss_index) - memset (new, 0, symp->st_size); + memset (new_base + newoff, 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); + ElfW (Shdr) *old_shdr = &OLD_SECTION_H (nn); + ptrdiff_t oldoff = reladdr + old_shdr->sh_offset; + memcpy (new_base + newoff, old_base + oldoff, symp->st_size); } } #endif @@ -1245,13 +1238,10 @@ temacs: that it can undo relocations performed by the runtime linker. */ for (n = new_file_h->e_shnum; 0 < --n; ) { - ElfW (Shdr) section = NEW_SECTION_H (n); - - /* Cause a compilation error if anyone uses n instead of nn below. */ - #define n ((void) 0); - n /* Prevent 'macro "n" is not used' warnings. */ + ElfW (Shdr) *rel_shdr = &NEW_SECTION_H (n); + ElfW (Shdr) *shdr; - switch (section.sh_type) + switch (rel_shdr->sh_type) { default: break; @@ -1260,28 +1250,22 @@ temacs: /* This code handles two different size structs, but there should be no harm in that provided that r_offset is always the first member. */ - nn = section.sh_info; - if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") - || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), - ".sdata") - || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), - ".lit4") - || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), - ".lit8") + shdr = &NEW_SECTION_H (rel_shdr->sh_info); + if (!strcmp (old_section_names + shdr->sh_name, ".data") + || !strcmp (old_section_names + shdr->sh_name, ".sdata") + || !strcmp (old_section_names + shdr->sh_name, ".lit4") + || !strcmp (old_section_names + shdr->sh_name, ".lit8") #ifdef IRIX6_5 /* see above */ - || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), - ".got") + || !strcmp (old_section_names + shdr->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), - ".data1")) + || !strcmp (old_section_names + shdr->sh_name, ".sdata1") + || !strcmp (old_section_names + shdr->sh_name, ".data1")) { - 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) offset = shdr->sh_addr - shdr->sh_offset; + caddr_t reloc = old_base + rel_shdr->sh_offset, end; + for (end = reloc + rel_shdr->sh_size; + reloc < end; + reloc += rel_shdr->sh_entsize) { ElfW (Addr) addr = ((ElfW (Rel) *) reloc)->r_offset - offset; #ifdef __alpha__ @@ -1296,8 +1280,6 @@ temacs: } break; } - - #undef n } /* Write out new_file, and free the buffers. */ ++++++ emacs-24-0012-ELF-unexec-Merge-Alpha-and-MIPS-COFF-debug-handling.patch ++++++
From 2cb9075979e413e4cc31c85d3bd830f791cc574b Mon Sep 17 00:00:00 2001 From: Alan Modra <amodra@gmail.com> Date: Sun, 8 Nov 2015 09:28:59 -0800 Subject: ELF unexec: Merge Alpha and MIPS COFF debug handling
Emacs should build on ppc64el. A problem with the bss has been fixed. This upstream patch has been added [3/10]: ELF unexec: Merge Alpha and MIPS COFF debug handling * unexelf.c (unexec): Merge Alpha and MIPS COFF debug handling. Don't find .mdebug section index, find the section in the loop. Allow for unlikely possibility that .mdebug is located at sh_offset before bss segment, by calculating move from difference in sh_offset rather than just assuming new_data2_size. Simplify cbLineOffset handling. Origin: upstream, commit: 47c6e3035b8182c6436de4673473de7824ad59f1 Bug: http://debbugs.gnu.org/20614 Bug-Debian: http://bugs.debian.org/808347 Added-by: Rob Browning <rlb@defaultvalue.org> --- src/unexelf.c | 96 ++++++++++++++++++----------------------------------------- 1 file changed, 29 insertions(+), 67 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index f7465cb..07c2ebe 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -660,9 +660,6 @@ unexec (const char *new_name, const char *old_name) ptrdiff_t n, nn; ptrdiff_t old_bss_index, old_sbss_index, old_plt_index; ptrdiff_t old_data_index, new_data2_index; -#if defined _SYSTYPE_SYSV || defined __sgi - ptrdiff_t old_mdebug_index; -#endif struct stat stat_buf; off_t old_file_size; int mask; @@ -707,13 +704,6 @@ unexec (const char *new_name, const char *old_name) 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. */ @@ -1056,51 +1046,31 @@ temacs: memcpy (new_shdr->sh_offset + new_base, src, new_shdr->sh_size); -#if defined __alpha__ && !defined __OpenBSD__ - /* Update Alpha COFF symbol table: */ - if (strcmp (old_section_names + old_shdr->sh_name, ".mdebug") == 0) - { - pHDRR symhdr = (pHDRR) (new_shdr->sh_offset + new_base); - - symhdr->cbLineOffset += new_data2_size; - symhdr->cbDnOffset += new_data2_size; - symhdr->cbPdOffset += new_data2_size; - symhdr->cbSymOffset += new_data2_size; - symhdr->cbOptOffset += new_data2_size; - symhdr->cbAuxOffset += new_data2_size; - symhdr->cbSsOffset += new_data2_size; - symhdr->cbSsExtOffset += new_data2_size; - symhdr->cbFdOffset += new_data2_size; - symhdr->cbRfdOffset += new_data2_size; - symhdr->cbExtOffset += new_data2_size; - } -#endif /* __alpha__ && !__OpenBSD__ */ - -#if defined (_SYSTYPE_SYSV) - if (new_shdr->sh_type == SHT_MIPS_DEBUG - && old_mdebug_index != -1) +#if (defined __alpha__ && !defined __OpenBSD__) || defined _SYSTYPE_SYSV + /* Update Alpha and MIPS COFF debug symbol table. */ + if (strcmp (old_section_names + new_shdr->sh_name, ".mdebug") == 0 + && new_shdr->sh_offset - old_shdr->sh_offset != 0 +#if defined _SYSTYPE_SYSV + && new_shdr->sh_type == SHT_MIPS_DEBUG +#endif + ) { - ptrdiff_t new_offset = new_shdr->sh_offset; - ptrdiff_t old_offset = OLD_SECTION_H (old_mdebug_index).sh_offset; - ptrdiff_t diff = new_offset - old_offset; + ptrdiff_t diff = new_shdr->sh_offset - old_shdr->sh_offset; HDRR *phdr = (HDRR *) (new_shdr->sh_offset + new_base); - if (diff) - { - phdr->cbLineOffset += diff; - phdr->cbDnOffset += diff; - phdr->cbPdOffset += diff; - phdr->cbSymOffset += diff; - phdr->cbOptOffset += diff; - phdr->cbAuxOffset += diff; - phdr->cbSsOffset += diff; - phdr->cbSsExtOffset += diff; - phdr->cbFdOffset += diff; - phdr->cbRfdOffset += diff; - phdr->cbExtOffset += diff; - } + phdr->cbLineOffset += diff; + phdr->cbDnOffset += diff; + phdr->cbPdOffset += diff; + phdr->cbSymOffset += diff; + phdr->cbOptOffset += diff; + phdr->cbAuxOffset += diff; + phdr->cbSsOffset += diff; + phdr->cbSsExtOffset += diff; + phdr->cbFdOffset += diff; + phdr->cbRfdOffset += diff; + phdr->cbExtOffset += diff; } -#endif /* _SYSTYPE_SYSV */ +#endif /* __alpha__ || _SYSTYPE_SYSV */ #if __sgi /* Adjust the HDRR offsets in .mdebug and copy the @@ -1111,7 +1081,8 @@ temacs: the ld bug that gets the line table in a hole in the elf file rather than in the .mdebug section proper. David Anderson. davea@sgi.com Jan 16,1994. */ - if (n == old_mdebug_index) + if (strcmp (old_section_names + new_shdr->sh_name, ".mdebug") == 0 + && new_shdr->sh_offset - old_shdr->sh_offset != 0) { #define MDEBUGADJUST(__ct,__fileaddr) \ if (n_phdrr->__ct > 0) \ @@ -1121,7 +1092,7 @@ temacs: HDRR *o_phdrr = (HDRR *) ((byte *) old_base + old_shdr->sh_offset); HDRR *n_phdrr = (HDRR *) ((byte *) new_base + new_shdr->sh_offset); - unsigned movement = new_data2_size; + ptrdiff_t movement = new_shdr->sh_offset - old_shdr->sh_offset; MDEBUGADJUST (idnMax, cbDnOffset); MDEBUGADJUST (ipdMax, cbPdOffset); @@ -1137,22 +1108,13 @@ temacs: requires special handling. */ if (n_phdrr->cbLine > 0) { + n_phdrr->cbLineOffset += movement; + if (o_phdrr->cbLineOffset > (old_shdr->sh_offset + old_shdr->sh_size)) - { - /* line data is in a hole in elf. do special copy and adjust - for this ld mistake. - */ - n_phdrr->cbLineOffset += movement; - - memcpy (n_phdrr->cbLineOffset + new_base, - o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine); - } - else - { - /* somehow line data is in .mdebug as it is supposed to be. */ - MDEBUGADJUST (cbLine, cbLineOffset); - } + /* If not covered by section, it hasn't yet been copied. */ + memcpy (n_phdrr->cbLineOffset + new_base, + o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine); } } #endif /* __sgi */ ++++++ emacs-24-0013-ELF-unexec-Symbol-table-patching.patch ++++++
From 2776e4ffe1f4cf965a6b99201097ca7d4ee2f95c Mon Sep 17 00:00:00 2001 From: Alan Modra <amodra@gmail.com> Date: Sun, 8 Nov 2015 09:29:00 -0800 Subject: ELF unexec: Symbol table patching
Emacs should build on ppc64el. A problem with the bss has been fixed. This upstream patch has been added [4/10]: ELF unexec: Symbol table patching No st_shndx value larger than SHN_LORESERVE should be changed. * unexelf.c (unexec): Don't adjust any st_shndx larger than SHN_LORESERVE. Error on SHN_XINDEX. Origin: upstream, commit: 190b968f189cb7d06223bb39045ec9055df67f68 Bug: http://debbugs.gnu.org/20614 Bug-Debian: http://bugs.debian.org/808347 Added-by: Rob Browning <rlb@defaultvalue.org> --- src/unexelf.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index 07c2ebe..010ecd3 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -1119,7 +1119,7 @@ temacs: } #endif /* __sgi */ - /* If it is the symbol table, its st_shndx field needs to be patched. */ + /* Patch st_shndx field of symbol table. */ if (new_shdr->sh_type == SHT_SYMTAB || new_shdr->sh_type == SHT_DYNSYM) { @@ -1127,9 +1127,10 @@ temacs: ElfW (Sym) *sym = (ElfW (Sym) *) (new_shdr->sh_offset + new_base); for (; num--; sym++) { - if ((sym->st_shndx == SHN_UNDEF) - || (sym->st_shndx == SHN_ABS) - || (sym->st_shndx == SHN_COMMON)) + if (sym->st_shndx == SHN_XINDEX) + fatal ("SHT_SYMTAB_SHNDX unsupported"); + if (sym->st_shndx == SHN_UNDEF + || sym->st_shndx >= SHN_LORESERVE) continue; PATCH_INDEX (sym->st_shndx); ++++++ emacs-24-0014-ELF-unexec-_OBJC_-symbols-in-bss-sections.patch ++++++
From af11708e83ab826202593ab1b9c22601c46a5056 Mon Sep 17 00:00:00 2001 From: Alan Modra <amodra@gmail.com> Date: Sun, 8 Nov 2015 09:29:00 -0800 Subject: ELF unexec: _OBJC_ symbols in bss sections
Emacs should build on ppc64el. A problem with the bss has been fixed. This upstream patch has been added [5/10]: ELF unexec: _OBJC_ symbols in bss sections This code assumed that there was only one bss section. Rather than checking for a particular index, check the section type. Also, handle the possibility that the section was SHT_NOBITS originally and is unchanged, in which case no clearing is needed (and sh_offset isn't necessarily valid, which can lead to a wild memset). * unexelf.c (unexec): Properly handle _OBJC_ symbols in bss sections. Origin: upstream, commit: 3ff9fc0e8d738be5004c65c3be314af9aca68148 Bug: http://debbugs.gnu.org/20614 Bug-Debian: http://bugs.debian.org/808347 Added-by: Rob Browning <rlb@defaultvalue.org> --- src/unexelf.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index 010ecd3..58f0ad0 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -1177,20 +1177,25 @@ temacs: "_OBJC_", sizeof ("_OBJC_") - 1) == 0) { ElfW (Shdr) *new_shdr = &NEW_SECTION_H (symp->st_shndx); - ptrdiff_t reladdr = symp->st_value - new_shdr->sh_addr; - ptrdiff_t newoff = reladdr + new_shdr->sh_offset; - - /* "Unpatch" index. */ - nn = symp->st_shndx; - if (nn > old_bss_index) - nn--; - if (nn == old_bss_index) - memset (new_base + newoff, 0, symp->st_size); - else + if (new_shdr->sh_type != SHT_NOBITS) { - ElfW (Shdr) *old_shdr = &OLD_SECTION_H (nn); - ptrdiff_t oldoff = reladdr + old_shdr->sh_offset; - memcpy (new_base + newoff, old_base + oldoff, symp->st_size); + ElfW (Shdr) *old_shdr; + ptrdiff_t reladdr = symp->st_value - new_shdr->sh_addr; + ptrdiff_t newoff = reladdr + new_shdr->sh_offset; + + /* "Unpatch" index. */ + nn = symp->st_shndx; + if (nn > old_bss_index) + nn--; + old_shdr = &OLD_SECTION_H (nn); + if (old_shdr->sh_type == SHT_NOBITS) + memset (new_base + newoff, 0, symp->st_size); + else + { + ptrdiff_t oldoff = reladdr + old_shdr->sh_offset; + memcpy (new_base + newoff, old_base + oldoff, + symp->st_size); + } } } #endif ++++++ emacs-24-0015-ELF-unexec-R_-_NONE-relocs.patch ++++++
From f9d91515971443b754b9c9eaac45a293d0e620c1 Mon Sep 17 00:00:00 2001 From: Alan Modra <amodra@gmail.com> Date: Sun, 8 Nov 2015 09:29:00 -0800 Subject: ELF unexec: R_*_NONE relocs
Emacs should build on ppc64el. A problem with the bss has been fixed. This upstream patch has been added [6/10]: ELF unexec: R_*_NONE relocs These should be ignored on all targets. * unexelf.c (unexec): Ignore R_*_NONE relocs for any target, not just Alpha. Comment on reloc size assumption. Origin: upstream, commit: 8285c2ab8050de218c0c06182659ee0a7b23a0f6 Bug: http://debbugs.gnu.org/20614 Bug-Debian: http://bugs.debian.org/808347 Added-by: Rob Browning <rlb@defaultvalue.org> --- src/unexelf.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index 58f0ad0..1d9387e 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -1203,7 +1203,7 @@ temacs: } /* This loop seeks out relocation sections for the data section, so - that it can undo relocations performed by the runtime linker. */ + that it can undo relocations performed by the runtime loader. */ for (n = new_file_h->e_shnum; 0 < --n; ) { ElfW (Shdr) *rel_shdr = &NEW_SECTION_H (n); @@ -1236,14 +1236,14 @@ temacs: reloc += rel_shdr->sh_entsize) { 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... */ + /* Ignore R_*_NONE relocs. */ if (((ElfW (Rel) *) reloc)->r_offset == 0) continue; -#endif - memcpy (new_base + addr, old_base + addr, sizeof (ElfW (Addr))); + /* Assume reloc applies to a word. + ??? This is not always true, eg. TLS module/index + pair in .got which occupies two words. */ + memcpy (new_base + addr, old_base + addr, + sizeof (ElfW (Addr))); } } break; ++++++ emacs-24-0016-ELF-unexec-Drive-from-PT_LOAD-header-rather-than-sec.patch ++++++
From 75dc7e12d73ad8c1bf9583515e41913980883dbe Mon Sep 17 00:00:00 2001 From: Alan Modra <amodra@gmail.com> Date: Sun, 8 Nov 2015 09:29:00 -0800 Subject: ELF unexec: Drive from PT_LOAD header rather than sections
Emacs should build on ppc64el. A problem with the bss has been fixed. This upstream patch has been added [7/10]: ELF unexec: Drive from PT_LOAD header rather than sections This rewrites bss handling in the ELF unexec code. Finding bss sections by name results in complicated code that - does not account for all names of possible bss sections, - assumes specific ordering of bss sections, - can wrongly choose a SHT_NOBITS section not in the bss segment, - incorrectly calculates bss size (no accounting for alignment gaps), - assumes .data and .bss are in the same segment. All of these problems and more are solved by finding the bss segment in PT_LOAD headers, ie. the address range included in p_memsz but not p_filesz of the last PT_LOAD header, then matching SHT_NOBITS sections in that address range. * unexelf.c: Delete old ppc comment. (OLD_PROGRAM_H): Define. (round_up): Delete. (unexec): Don't search for bss style sections by name. Instead, use the last PT_LOAD header address range covered by p_memsz but not p_filesz and match any SHT_NOBITS section in that address range. Simplify initialisation of section header vars. Don't assume that section headers are above bss segment. Move copying of bss area out of section loop. Align .data2 section to 1, since it now covers the entire bss area. For SHT_NOBITS sections in the bss segment, leave sh_addr and sh_addralign unchanged, but correct sh_offset. Clear memory corresponding to SHT_NOBITS .plt section. Delete comment and hacks for sections partly overlapping bss range now that the full range is properly calculated. Delete now dead .sbss code. (Bug#20614) Origin: upstream, commit: 0d6442265e5b709af5eebedf8f0d6b82974f4c31 Bug: http://debbugs.gnu.org/20614 Bug-Debian: http://bugs.debian.org/808347 Added-by: Rob Browning <rlb@defaultvalue.org> --- src/unexelf.c | 290 ++++++++++++++++------------------------------------------ 1 file changed, 77 insertions(+), 213 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index 1d9387e..c659f3e 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -535,29 +535,6 @@ verify ((! TYPE_SIGNED (ElfW (Half)) /* Get the address of a particular section or program header entry, * accounting for the size of the entries. */ -/* - On PPC Reference Platform running Solaris 2.5.1 - the plt section is also of type NOBI like the bss section. - (not really stored) and therefore sections after the bss - section start at the plt offset. The plt section is always - the one just before the bss section. - Thus, we modify the test from - if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset) - to - if (NEW_SECTION_H (nn).sh_offset >= - OLD_SECTION_H (old_bss_index-1).sh_offset) - This is just a hack. We should put the new data section - before the .plt section. - And we should not have this routine at all but use - the libelf library to read the old file and create the new - file. - The changed code is minimal and depends on prep set in m/prep.h - Erik Deumens - Quantum Theory Project - University of Florida - deumens@qtp.ufl.edu - Apr 23, 1996 - */ static void * entry_address (void *section_h, ptrdiff_t idx, ptrdiff_t entsize) @@ -570,23 +547,14 @@ entry_address (void *section_h, ptrdiff_t idx, ptrdiff_t entsize) (*(ElfW (Shdr) *) entry_address (old_section_h, n, old_file_h->e_shentsize)) #define NEW_SECTION_H(n) \ (*(ElfW (Shdr) *) entry_address (new_section_h, n, new_file_h->e_shentsize)) +#define OLD_PROGRAM_H(n) \ + (*(ElfW (Phdr) *) entry_address (old_program_h, n, old_file_h->e_phentsize)) #define NEW_PROGRAM_H(n) \ (*(ElfW (Phdr) *) entry_address (new_program_h, n, new_file_h->e_phentsize)) #define PATCH_INDEX(n) ((n) += old_bss_index <= (n)) typedef unsigned char byte; -/* Round X up to a multiple of Y. */ - -static ElfW (Addr) -round_up (ElfW (Addr) x, ElfW (Addr) y) -{ - ElfW (Addr) rem = x % y; - if (rem == 0) - return x; - 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. @@ -650,16 +618,15 @@ unexec (const char *new_name, const char *old_name) /* Point to the section name table in the old file. */ char *old_section_names; + ElfW (Phdr) *old_bss_seg, *new_bss_seg; 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; ptrdiff_t n, nn; - ptrdiff_t old_bss_index, old_sbss_index, old_plt_index; - ptrdiff_t old_data_index, new_data2_index; + ptrdiff_t old_bss_index, old_data_index; struct stat stat_buf; off_t old_file_size; int mask; @@ -704,54 +671,40 @@ unexec (const char *new_name, const char *old_name) 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. */ - - 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_NOBITS) - old_sbss_index = -1; - - /* PowerPC64 has .plt in the BSS section. */ - old_plt_index = find_section (".plt", old_section_names, - old_name, old_file_h, old_section_h, 1); - if (old_plt_index != -1) - if (OLD_SECTION_H (old_plt_index).sh_type != SHT_NOBITS) - old_plt_index = -1; - - if (old_sbss_index == -1 && old_plt_index == -1) - { - old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; - old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; - old_bss_offset = OLD_SECTION_H (old_bss_index).sh_offset; - new_data2_index = old_bss_index; - } - else if (old_plt_index != -1 - && (old_sbss_index == -1 - || (OLD_SECTION_H (old_sbss_index).sh_addr - > OLD_SECTION_H (old_plt_index).sh_addr))) + /* Find the PT_LOAD header covering the highest address. This + segment will be where bss sections are located, past p_filesz. */ + old_bss_seg = 0; + for (n = old_file_h->e_phnum; --n >= 0; ) { - old_bss_addr = OLD_SECTION_H (old_plt_index).sh_addr; - old_bss_size = OLD_SECTION_H (old_bss_index).sh_size - + OLD_SECTION_H (old_plt_index).sh_size; - if (old_sbss_index != -1) - old_bss_size += OLD_SECTION_H (old_sbss_index).sh_size; - old_bss_offset = OLD_SECTION_H (old_plt_index).sh_offset; - new_data2_index = old_plt_index; + ElfW (Phdr) *seg = &OLD_PROGRAM_H (n); + if (seg->p_type == PT_LOAD + && (old_bss_seg == 0 + || seg->p_vaddr > old_bss_seg->p_vaddr)) + old_bss_seg = seg; } - else + + /* Note that old_bss_addr may be lower than the first bss section + address, since the section may need aligning. */ + old_bss_addr = old_bss_seg->p_vaddr + old_bss_seg->p_filesz; + old_bss_offset = old_bss_seg->p_offset + old_bss_seg->p_filesz; + old_bss_size = old_bss_seg->p_memsz - old_bss_seg->p_filesz; + + /* Find the first bss style section in the bss segment range. */ + old_bss_index = -1; + for (n = old_file_h->e_shnum; --n > 0; ) { - 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_offset = OLD_SECTION_H (old_sbss_index).sh_offset; - new_data2_index = old_sbss_index; + ElfW (Shdr) *shdr = &OLD_SECTION_H (n); + if (shdr->sh_type == SHT_NOBITS + && shdr->sh_addr >= old_bss_addr + && shdr->sh_addr + shdr->sh_size <= old_bss_addr + old_bss_size + && (old_bss_index == -1 + || OLD_SECTION_H (old_bss_index).sh_addr > shdr->sh_addr)) + old_bss_index = n; } + if (old_bss_index == -1) + fatal ("no bss section found"); + /* Find the old .data section. Figure out parameters of the new data2 and bss sections. */ @@ -762,13 +715,7 @@ unexec (const char *new_name, const char *old_name) new_bss_addr = (ElfW (Addr)) new_break; 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); - /* This is the amount by which the sections following the bss sections - must be shifted in the image. It can differ from new_data2_size if - the end of the old .data section (and thus the offset of the .bss - section) was unaligned. */ - new_data2_incr = new_data2_size + (new_data2_offset - old_bss_offset); + new_data2_offset = old_bss_offset; #ifdef UNEXELF_DEBUG fprintf (stderr, "old_bss_index %td\n", old_bss_index); @@ -779,7 +726,6 @@ unexec (const char *new_name, const char *old_name) DEBUG_LOG (new_data2_addr); DEBUG_LOG (new_data2_size); DEBUG_LOG (new_data2_offset); - DEBUG_LOG (new_data2_incr); #endif if (new_bss_addr < old_bss_addr + old_bss_size) @@ -793,7 +739,7 @@ unexec (const char *new_name, const char *old_name) if (new_file < 0) fatal ("Can't creat (%s): %s", new_name, strerror (errno)); - new_file_size = old_file_size + old_file_h->e_shentsize + new_data2_incr; + new_file_size = old_file_size + old_file_h->e_shentsize + new_data2_size; if (ftruncate (new_file, new_file_size)) fatal ("Can't ftruncate (%s): %s", new_name, strerror (errno)); @@ -812,15 +758,15 @@ unexec (const char *new_name, const char *old_name) /* Fix up file header. We'll add one section. Section header is further away now. */ - new_file_h->e_shoff += new_data2_incr; + if (new_file_h->e_shoff >= old_bss_offset) + new_file_h->e_shoff += new_data2_size; new_file_h->e_shnum += 1; /* Modify the e_shstrndx if necessary. */ PATCH_INDEX (new_file_h->e_shstrndx); - 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); + new_program_h = (ElfW (Phdr) *) ((byte *) new_base + new_file_h->e_phoff); + new_section_h = (ElfW (Shdr) *) ((byte *) new_base + new_file_h->e_shoff); memcpy (new_program_h, old_program_h, old_file_h->e_phnum * old_file_h->e_phentsize); @@ -832,65 +778,21 @@ unexec (const char *new_name, const char *old_name) fprintf (stderr, "New section count %td\n", (ptrdiff_t) new_file_h->e_shnum); #endif - /* Fix up a new program header. Extend the writable data segment so - that the bss area is covered too. Find that segment by looking - for a segment that ends just before the .bss area. Make sure - that no segments are above the new .data2. Put a loop at the end - to adjust the offset and address of any segment that is above - data2, just in case we decide to allow this later. */ + /* Fix up program header. Extend the writable data segment so + that the bss area is covered too. */ - for (n = new_file_h->e_phnum; --n >= 0; ) - { - /* Compute maximum of all requirements for alignment of section. */ - 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; - -#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 /* __sgi */ - if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz - > (old_sbss_index == -1 - ? old_bss_addr - : round_up (old_bss_addr, alignment))) - fatal ("Program segment above .bss in %s", old_name); - - if (NEW_PROGRAM_H (n).p_type == PT_LOAD - && (round_up ((NEW_PROGRAM_H (n)).p_vaddr - + (NEW_PROGRAM_H (n)).p_filesz, - alignment) - == round_up (old_bss_addr, alignment))) - break; - } - if (n < 0) - fatal ("Couldn't find segment next to .bss in %s", old_name); - - /* Make sure that the size includes any padding before the old .bss - section. */ - NEW_PROGRAM_H (n).p_filesz = new_bss_addr - NEW_PROGRAM_H (n).p_vaddr; - NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz; - -#if 0 /* Maybe allow section after data2 - does this ever happen? */ - for (n = new_file_h->e_phnum; --n >= 0; ) - { - if (NEW_PROGRAM_H (n).p_vaddr - && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr) - NEW_PROGRAM_H (n).p_vaddr += new_data2_size - old_bss_size; + new_bss_seg = new_program_h + (old_bss_seg - old_program_h); + new_bss_seg->p_filesz = new_bss_addr - new_bss_seg->p_vaddr; + new_bss_seg->p_memsz = new_bss_seg->p_filesz; - if (NEW_PROGRAM_H (n).p_offset >= new_data2_offset) - NEW_PROGRAM_H (n).p_offset += new_data2_incr; - } -#endif + /* Copy over what we have in memory now for the bss area. */ + memcpy (new_base + new_data2_offset, (caddr_t) old_bss_addr, new_data2_size); /* Fix up section headers based on new .data2 section. Any section whose offset or virtual address is after the new .data2 section - gets its value adjusted. .bss size becomes zero and new address - is set. data2 section header gets added by copying the existing - .data header and modifying the offset, address and size. */ + gets its value adjusted. .bss size becomes zero. data2 section + header gets added by copying the existing .data header and + modifying the offset, address and size. */ /* Walk through all section headers, insert the new data2 section right before the new bss section. */ @@ -901,9 +803,7 @@ unexec (const char *new_name, const char *old_name) ElfW (Shdr) *new_shdr = &NEW_SECTION_H (nn); /* If it is (s)bss section, insert the new data2 section before it. */ - /* new_data2_index is the index of either old_sbss or old_bss, that was - chosen as a section for new_data2. */ - if (n == new_data2_index) + if (n == old_bss_index) { /* Steal the data section header for this data2 section. */ memcpy (new_shdr, &OLD_SECTION_H (old_data_index), @@ -912,68 +812,43 @@ unexec (const char *new_name, const char *old_name) new_shdr->sh_addr = new_data2_addr; new_shdr->sh_offset = new_data2_offset; new_shdr->sh_size = new_data2_size; - /* Use the bss section's alignment. This will assure that the - new data2 section always be placed in the same spot as the old - bss section by any other application. */ - new_shdr->sh_addralign = old_shdr->sh_addralign; - - /* Now copy over what we have in the memory now. */ - memcpy (new_shdr->sh_offset + new_base, - (caddr_t) old_shdr->sh_addr, - new_data2_size); + new_shdr->sh_addralign = 1; nn++; new_shdr++; } memcpy (new_shdr, old_shdr, old_file_h->e_shentsize); - if (n == old_bss_index - /* The new bss and sbss section's size is zero, and its file offset - and virtual address should be off by NEW_DATA2_SIZE. */ - || n == old_sbss_index || n == old_plt_index - ) + if (new_shdr->sh_type == SHT_NOBITS + && new_shdr->sh_addr >= old_bss_addr + && (new_shdr->sh_addr + new_shdr->sh_size + <= old_bss_addr + old_bss_size)) { - /* NN should be `old_s?bss_index + 1' at this point. */ - new_shdr->sh_offset = new_data2_offset + new_data2_size; - new_shdr->sh_addr = new_data2_addr + new_data2_size; - /* Let the new bss section address alignment be the same as the - section address alignment followed the old bss section, so - this section will be placed in exactly the same place. */ - new_shdr->sh_addralign = OLD_SECTION_H (nn).sh_addralign; + /* SHT_NOBITS sections do not need a valid sh_offset, so it + might be incorrect. Write the correct value. */ + new_shdr->sh_offset = (new_shdr->sh_addr - new_bss_seg->p_vaddr + + new_bss_seg->p_offset); + + /* If this is was a SHT_NOBITS .plt section, then it is + probably a PowerPC PLT. If it is PowerPC64 ELFv1 then + glibc ld.so doesn't initialize the toc pointer word. A + non-zero toc pointer word can defeat Power7 thread safety + during lazy update of a PLT entry. This only matters if + emacs becomes multi-threaded. */ + if (strcmp (old_section_names + new_shdr->sh_name, ".plt") == 0) + memset (new_shdr->sh_offset + new_base, 0, new_shdr->sh_size); + + /* Set the new bss and sbss section's size to zero, because + we've already covered this address range by .data2. */ new_shdr->sh_size = 0; } else { /* Any section that was originally placed after the .bss - section should now be off by NEW_DATA2_INCR. If a - section overlaps the .bss section, consider it to be - placed after the .bss section. Overlap can occur if the - section just before .bss has less-strict alignment; this - was observed between .symtab and .bss on Solaris 2.5.1 - (sparc) with GCC snapshot 960602. + section should now be off by NEW_DATA2_SIZE. */ -> dump -h temacs - -temacs: - - **** SECTION HEADER TABLE **** -[No] Type Flags Addr Offset Size Name - Link Info Adralgn Entsize - -[22] 1 3 0x335150 0x315150 0x4 .data.rel.local - 0 0 0x4 0 - -[23] 8 3 0x335158 0x315158 0x42720 .bss - 0 0 0x8 0 - -[24] 2 0 0 0x315154 0x1c9d0 .symtab - 25 1709 0x4 0x10 - */ - - if (new_shdr->sh_offset >= old_bss_offset - || (new_shdr->sh_offset + new_shdr->sh_size - > new_data2_offset)) - new_shdr->sh_offset += new_data2_incr; + if (new_shdr->sh_offset >= old_bss_offset) + new_shdr->sh_offset += new_data2_size; /* Any section that was originally placed after the section header table should now be off by the size of one section @@ -993,23 +868,13 @@ temacs: && new_shdr->sh_type != SHT_DYNSYM) PATCH_INDEX (new_shdr->sh_info); - if (old_sbss_index != -1) - if (!strcmp (old_section_names + new_shdr->sh_name, ".sbss")) - { - new_shdr->sh_offset = - round_up (new_shdr->sh_offset, - new_shdr->sh_addralign); - new_shdr->sh_type = SHT_PROGBITS; - } - /* Now, start to copy the content of sections. */ if (new_shdr->sh_type == SHT_NULL || new_shdr->sh_type == SHT_NOBITS) continue; - /* Write out the sections. .data and .data1 (and data2, called - ".data" in the strings table) get copied from the current process - instead of the old file. */ + /* Some sections are copied from the current process instead of + the old file. */ if (!strcmp (old_section_names + new_shdr->sh_name, ".data") || !strcmp (old_section_names + new_shdr->sh_name, ".sdata") || !strcmp (old_section_names + new_shdr->sh_name, ".lit4") @@ -1038,8 +903,7 @@ temacs: || !strcmp (old_section_names + new_shdr->sh_name, ".got") #endif || !strcmp (old_section_names + new_shdr->sh_name, ".sdata1") - || !strcmp (old_section_names + new_shdr->sh_name, ".data1") - || !strcmp (old_section_names + new_shdr->sh_name, ".sbss")) + || !strcmp (old_section_names + new_shdr->sh_name, ".data1")) src = (caddr_t) old_shdr->sh_addr; else src = old_base + old_shdr->sh_offset; ++++++ emacs-24-0017-ELF-unexec-Don-t-insert-a-new-section.patch ++++++ ++++ 705 lines (skipped) ++++++ emacs-24-0018-src-unexelf.c-NEW_PROGRAM_H-Remove-unused-macro-Bug-.patch ++++++
From 9b52726df50cc9b4fdfce2ed1dc114311dc60a93 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Sun, 8 Nov 2015 09:36:14 -0800 Subject: * src/unexelf.c (NEW_PROGRAM_H): Remove unused macro (Bug#20614).
Emacs should build on ppc64el. A problem with the bss has been fixed. This upstream patch has been added [9/10]: * src/unexelf.c (NEW_PROGRAM_H): Remove unused macro (Bug#20614). Origin: upstream, commit: 2ce0c0674eba9179ba57c537e387bc3f7b0e5b63 Bug: http://debbugs.gnu.org/20614 Bug-Debian: http://bugs.debian.org/808347 Added-by: Rob Browning <rlb@defaultvalue.org> --- src/unexelf.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index 9279c76..f2462d1 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -208,8 +208,6 @@ entry_address (void *section_h, ptrdiff_t idx, ptrdiff_t entsize) (*(ElfW (Shdr) *) entry_address (new_section_h, n, new_file_h->e_shentsize)) #define OLD_PROGRAM_H(n) \ (*(ElfW (Phdr) *) entry_address (old_program_h, n, old_file_h->e_phentsize)) -#define NEW_PROGRAM_H(n) \ - (*(ElfW (Phdr) *) entry_address (new_program_h, n, new_file_h->e_phentsize)) typedef unsigned char byte; @@ -250,7 +248,7 @@ unexec (const char *new_name, const char *old_name) ElfW (Phdr) *old_bss_seg, *new_bss_seg; ElfW (Addr) old_bss_addr, new_bss_addr; ElfW (Word) old_bss_size, new_data2_size; - ElfW (Off) old_bss_offset, new_data2_offset; + ElfW (Off) old_bss_offset, new_data2_offset; ptrdiff_t n; ptrdiff_t old_bss_index; ++++++ emacs-24-0019-ELF-unexec-align-section-header.patch ++++++
From 0de7316751e94c29aeb4b75731ac6e8c9eba77e6 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Mon, 16 Nov 2015 17:48:08 -0800 Subject: ELF unexec: align section header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit
Emacs should build on ppc64el. A problem with the bss has been fixed. This upstream patch has been added [10/10]: ELF unexec: align section header This ports the recent unexelf.c changes to Fedora x86-64 when configured with GCC’s -fsanitize=undefined option. * src/unexelf.c (unexec): Align new_data2_size to a multiple of ElfW (Shdr)’s alignment, so that NEW_SECTION_H returns a pointer aligned appropriately for its type. Origin: upstream, commit: c9fd597a4cffcae873b25381ee8cc755f0debe95 Bug: http://debbugs.gnu.org/20614 Bug-Debian: http://bugs.debian.org/808347 Added-by: Rob Browning <rlb@defaultvalue.org> --- src/unexelf.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index f2462d1..c69be0d 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -247,7 +247,7 @@ unexec (const char *new_name, const char *old_name) ElfW (Phdr) *old_bss_seg, *new_bss_seg; ElfW (Addr) old_bss_addr, new_bss_addr; - ElfW (Word) old_bss_size, new_data2_size; + ElfW (Word) old_bss_size, bss_size_growth, new_data2_size; ElfW (Off) old_bss_offset, new_data2_offset; ptrdiff_t n; @@ -332,7 +332,11 @@ unexec (const char *new_name, const char *old_name) new_break = sbrk (0); new_bss_addr = (ElfW (Addr)) new_break; - new_data2_size = new_bss_addr - old_bss_addr; + bss_size_growth = new_bss_addr - old_bss_addr; + new_data2_size = bss_size_growth; + new_data2_size += alignof (ElfW (Shdr)) - 1; + new_data2_size -= new_data2_size % alignof (ElfW (Shdr)); + new_data2_offset = old_bss_offset; #ifdef UNEXELF_DEBUG @@ -400,7 +404,8 @@ unexec (const char *new_name, const char *old_name) new_bss_seg->p_memsz = new_bss_seg->p_filesz; /* Copy over what we have in memory now for the bss area. */ - memcpy (new_base + new_data2_offset, (caddr_t) old_bss_addr, new_data2_size); + memcpy (new_base + new_data2_offset, (caddr_t) old_bss_addr, + bss_size_growth); /* Walk through all section headers, copying data and updating. */ for (n = 1; n < old_file_h->e_shnum; n++)
participants (1)
-
root@hilbert.suse.de