diff --git a/emacs-24-0010-ELF-unexec-Correct-section-header-index.patch b/emacs-24-0010-ELF-unexec-Correct-section-header-index.patch new file mode 100644 index 0000000..4e811df --- /dev/null +++ b/emacs-24-0010-ELF-unexec-Correct-section-header-index.patch @@ -0,0 +1,69 @@ +From 0a97fb1992c8cc3612a2358f576f774ea1f36777 Mon Sep 17 00:00:00 2001 +From: Alan Modra +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 +--- + src/unexelf.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +Index: emacs-24.5/src/unexelf.c +=================================================================== +--- emacs-24.5.orig/src/unexelf.c ++++ emacs-24.5/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 diff --git a/emacs-24-0011-ELF-unexec-Tidy-code.patch b/emacs-24-0011-ELF-unexec-Tidy-code.patch new file mode 100644 index 0000000..f91a19d --- /dev/null +++ b/emacs-24-0011-ELF-unexec-Tidy-code.patch @@ -0,0 +1,422 @@ +From 9fa97f0c2c1afae39b6662a836910deb1e0130ad Mon Sep 17 00:00:00 2001 +From: Alan Modra +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 +--- + src/unexelf.c | 210 ++++++++++++++++++++++++++-------------------------------- + 1 file changed, 96 insertions(+), 114 deletions(-) + +Index: emacs-24.5/src/unexelf.c +=================================================================== +--- emacs-24.5.orig/src/unexelf.c ++++ emacs-24.5/src/unexelf.c +@@ -813,20 +813,11 @@ unexec (const char *new_name, const char + 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 + 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 + 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 + ) + { + /* 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. */ diff --git a/emacs-24-0012-ELF-unexec-Merge-Alpha-and-MIPS-COFF-debug-handling.patch b/emacs-24-0012-ELF-unexec-Merge-Alpha-and-MIPS-COFF-debug-handling.patch new file mode 100644 index 0000000..3817e1d --- /dev/null +++ b/emacs-24-0012-ELF-unexec-Merge-Alpha-and-MIPS-COFF-debug-handling.patch @@ -0,0 +1,174 @@ +From 2cb9075979e413e4cc31c85d3bd830f791cc574b Mon Sep 17 00:00:00 2001 +From: Alan Modra +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 +--- + src/unexelf.c | 96 +++++++++++++++++----------------------------------------- + 1 file changed, 29 insertions(+), 67 deletions(-) + +Index: emacs-24.5/src/unexelf.c +=================================================================== +--- emacs-24.5.orig/src/unexelf.c ++++ emacs-24.5/src/unexelf.c +@@ -660,9 +660,6 @@ unexec (const char *new_name, const char + 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_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 */ diff --git a/emacs-24-0013-ELF-unexec-Symbol-table-patching.patch b/emacs-24-0013-ELF-unexec-Symbol-table-patching.patch new file mode 100644 index 0000000..39ecc6d --- /dev/null +++ b/emacs-24-0013-ELF-unexec-Symbol-table-patching.patch @@ -0,0 +1,50 @@ +From 2776e4ffe1f4cf965a6b99201097ca7d4ee2f95c Mon Sep 17 00:00:00 2001 +From: Alan Modra +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 +--- + src/unexelf.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +Index: emacs-24.5/src/unexelf.c +=================================================================== +--- emacs-24.5.orig/src/unexelf.c ++++ emacs-24.5/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); diff --git a/emacs-24-0014-ELF-unexec-_OBJC_-symbols-in-bss-sections.patch b/emacs-24-0014-ELF-unexec-_OBJC_-symbols-in-bss-sections.patch new file mode 100644 index 0000000..8fd15ed --- /dev/null +++ b/emacs-24-0014-ELF-unexec-_OBJC_-symbols-in-bss-sections.patch @@ -0,0 +1,70 @@ +From af11708e83ab826202593ab1b9c22601c46a5056 Mon Sep 17 00:00:00 2001 +From: Alan Modra +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 +--- + src/unexelf.c | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +Index: emacs-24.5/src/unexelf.c +=================================================================== +--- emacs-24.5.orig/src/unexelf.c ++++ emacs-24.5/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 diff --git a/emacs-24-0015-ELF-unexec-R_-_NONE-relocs.patch b/emacs-24-0015-ELF-unexec-R_-_NONE-relocs.patch new file mode 100644 index 0000000..b56d9da --- /dev/null +++ b/emacs-24-0015-ELF-unexec-R_-_NONE-relocs.patch @@ -0,0 +1,58 @@ +From f9d91515971443b754b9c9eaac45a293d0e620c1 Mon Sep 17 00:00:00 2001 +From: Alan Modra +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 +--- + src/unexelf.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +Index: emacs-24.5/src/unexelf.c +=================================================================== +--- emacs-24.5.orig/src/unexelf.c ++++ emacs-24.5/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; diff --git a/emacs-24-0016-ELF-unexec-Drive-from-PT_LOAD-header-rather-than-sec.patch b/emacs-24-0016-ELF-unexec-Drive-from-PT_LOAD-header-rather-than-sec.patch new file mode 100644 index 0000000..2738ba7 --- /dev/null +++ b/emacs-24-0016-ELF-unexec-Drive-from-PT_LOAD-header-rather-than-sec.patch @@ -0,0 +1,481 @@ +From 75dc7e12d73ad8c1bf9583515e41913980883dbe Mon Sep 17 00:00:00 2001 +From: Alan Modra +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 +--- + src/unexelf.c | 292 +++++++++++++++------------------------------------------- + 1 file changed, 78 insertions(+), 214 deletions(-) + +Index: emacs-24.5/src/unexelf.c +=================================================================== +--- emacs-24.5.orig/src/unexelf.c ++++ emacs-24.5/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_ + (*(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 + /* 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_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 + 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 + 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 + 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 + /* 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 + 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 + 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 + 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. +- +-> 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; ++ section should now be off by NEW_DATA2_SIZE. */ ++ ++ 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; diff --git a/emacs-24-0017-ELF-unexec-Don-t-insert-a-new-section.patch b/emacs-24-0017-ELF-unexec-Don-t-insert-a-new-section.patch new file mode 100644 index 0000000..3020349 --- /dev/null +++ b/emacs-24-0017-ELF-unexec-Don-t-insert-a-new-section.patch @@ -0,0 +1,706 @@ +From ee3beb72e75cdffa08b99e2f9d4829665feccb18 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Sun, 8 Nov 2015 09:29:00 -0800 +Subject: ELF unexec: Don't insert a new section + +Emacs should build on ppc64el. A problem with the bss has been fixed. + +This upstream patch has been added [8/10]: + + ELF unexec: Don't insert a new section + + Reuse the .bss section instead, making it SHT_PROGBITS. This way we + don't need to mess with symbol st_shndx, or section sh_link and + sh_info. + + This does lead to eu-elflint complaints about symbols defined in .bss + with a needed version, because normally it is undefined symbols that + have needed versions; Defined symbols have version definitions. + The exception is symbols defined by the linker in .dynbss for + variables copied from a shared library in order to avoid text + relocations, with copy relocs to copy their initial values from the + shared library. These symbols are both defined and have needed + versions, and eu-elflink only expects to see them in SHT_NOBITS + sections. Of course there is no real problem with having such symbols + in SHT_PROGBITS sections. glibc ld.so handles them fine. + + * unexelf.c: Delete outdated comments. + (PATCH_INDEX): Delete. + (find_section): Delete. + (unexec): Don't add a new section. Instead reuse the last bss + section, extending it to cover dumped data. Make bss sections + SHT_PROGBITS. Remove all patching of sh_link, sh_info and + st_shndx. Rename bss sections. + +Origin: upstream, commit: 3008c521740c5ad46a4eaf343b438b02c25e4de5 +Bug: http://debbugs.gnu.org/20614 +Bug-Debian: http://bugs.debian.org/808347 +Added-by: Rob Browning +--- + src/unexelf.c | 526 +++++----------------------------------------------------- + 1 file changed, 51 insertions(+), 475 deletions(-) + +Index: emacs-24.5/src/unexelf.c +=================================================================== +--- emacs-24.5.orig/src/unexelf.c ++++ emacs-24.5/src/unexelf.c +@@ -40,347 +40,6 @@ what you give them. Help stamp out sof + * On some machines, an existing old_name file is required. + * + */ +- +-/* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co. +- * ELF support added. +- * +- * Basic theory: the data space of the running process needs to be +- * dumped to the output file. Normally we would just enlarge the size +- * of .data, scooting everything down. But we can't do that in ELF, +- * because there is often something between the .data space and the +- * .bss space. +- * +- * In the temacs dump below, notice that the Global Offset Table +- * (.got) and the Dynamic link data (.dynamic) come between .data1 and +- * .bss. It does not work to overlap .data with these fields. +- * +- * The solution is to create a new .data segment. This segment is +- * filled with data from the current process. Since the contents of +- * various sections refer to sections by index, the new .data segment +- * is made the last in the table to avoid changing any existing index. +- +- * This is an example of how the section headers are changed. "Addr" +- * is a process virtual address. "Offset" is a file offset. +- +-raid:/nfs/raid/src/dist-18.56/src> dump -h temacs +- +-temacs: +- +- **** SECTION HEADER TABLE **** +- [No] Type Flags Addr Offset Size Name +- Link Info Adralgn Entsize +- +- [1] 1 2 0x80480d4 0xd4 0x13 .interp +- 0 0 0x1 0 +- +- [2] 5 2 0x80480e8 0xe8 0x388 .hash +- 3 0 0x4 0x4 +- +- [3] 11 2 0x8048470 0x470 0x7f0 .dynsym +- 4 1 0x4 0x10 +- +- [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr +- 0 0 0x1 0 +- +- [5] 9 2 0x8049010 0x1010 0x338 .rel.plt +- 3 7 0x4 0x8 +- +- [6] 1 6 0x8049348 0x1348 0x3 .init +- 0 0 0x4 0 +- +- [7] 1 6 0x804934c 0x134c 0x680 .plt +- 0 0 0x4 0x4 +- +- [8] 1 6 0x80499cc 0x19cc 0x3c56f .text +- 0 0 0x4 0 +- +- [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini +- 0 0 0x4 0 +- +- [10] 1 2 0x8085f40 0x3df40 0x69c .rodata +- 0 0 0x4 0 +- +- [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1 +- 0 0 0x4 0 +- +- [12] 1 3 0x8088330 0x3f330 0x20afc .data +- 0 0 0x4 0 +- +- [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1 +- 0 0 0x4 0 +- +- [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got +- 0 0 0x4 0x4 +- +- [15] 6 3 0x80a9874 0x60874 0x80 .dynamic +- 4 0 0x4 0x8 +- +- [16] 8 3 0x80a98f4 0x608f4 0x449c .bss +- 0 0 0x4 0 +- +- [17] 2 0 0 0x608f4 0x9b90 .symtab +- 18 371 0x4 0x10 +- +- [18] 3 0 0 0x6a484 0x8526 .strtab +- 0 0 0x1 0 +- +- [19] 3 0 0 0x729aa 0x93 .shstrtab +- 0 0 0x1 0 +- +- [20] 1 0 0 0x72a3d 0x68b7 .comment +- 0 0 0x1 0 +- +- raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs +- +- xemacs: +- +- **** SECTION HEADER TABLE **** +- [No] Type Flags Addr Offset Size Name +- Link Info Adralgn Entsize +- +- [1] 1 2 0x80480d4 0xd4 0x13 .interp +- 0 0 0x1 0 +- +- [2] 5 2 0x80480e8 0xe8 0x388 .hash +- 3 0 0x4 0x4 +- +- [3] 11 2 0x8048470 0x470 0x7f0 .dynsym +- 4 1 0x4 0x10 +- +- [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr +- 0 0 0x1 0 +- +- [5] 9 2 0x8049010 0x1010 0x338 .rel.plt +- 3 7 0x4 0x8 +- +- [6] 1 6 0x8049348 0x1348 0x3 .init +- 0 0 0x4 0 +- +- [7] 1 6 0x804934c 0x134c 0x680 .plt +- 0 0 0x4 0x4 +- +- [8] 1 6 0x80499cc 0x19cc 0x3c56f .text +- 0 0 0x4 0 +- +- [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini +- 0 0 0x4 0 +- +- [10] 1 2 0x8085f40 0x3df40 0x69c .rodata +- 0 0 0x4 0 +- +- [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1 +- 0 0 0x4 0 +- +- [12] 1 3 0x8088330 0x3f330 0x20afc .data +- 0 0 0x4 0 +- +- [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1 +- 0 0 0x4 0 +- +- [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got +- 0 0 0x4 0x4 +- +- [15] 6 3 0x80a9874 0x60874 0x80 .dynamic +- 4 0 0x4 0x8 +- +- [16] 8 3 0x80c6800 0x7d800 0 .bss +- 0 0 0x4 0 +- +- [17] 2 0 0 0x7d800 0x9b90 .symtab +- 18 371 0x4 0x10 +- +- [18] 3 0 0 0x87390 0x8526 .strtab +- 0 0 0x1 0 +- +- [19] 3 0 0 0x8f8b6 0x93 .shstrtab +- 0 0 0x1 0 +- +- [20] 1 0 0 0x8f949 0x68b7 .comment +- 0 0 0x1 0 +- +- [21] 1 3 0x80a98f4 0x608f4 0x1cf0c .data +- 0 0 0x4 0 +- +- * This is an example of how the file header is changed. "Shoff" is +- * the section header offset within the file. Since that table is +- * after the new .data section, it is moved. "Shnum" is the number of +- * sections, which we increment. +- * +- * "Phoff" is the file offset to the program header. "Phentsize" and +- * "Shentsz" are the program and section header entries sizes respectively. +- * These can be larger than the apparent struct sizes. +- +- raid:/nfs/raid/src/dist-18.56/src> dump -f temacs +- +- temacs: +- +- **** ELF HEADER **** +- Class Data Type Machine Version +- Entry Phoff Shoff Flags Ehsize +- Phentsize Phnum Shentsz Shnum Shstrndx +- +- 1 1 2 3 1 +- 0x80499cc 0x34 0x792f4 0 0x34 +- 0x20 5 0x28 21 19 +- +- raid:/nfs/raid/src/dist-18.56/src> dump -f xemacs +- +- xemacs: +- +- **** ELF HEADER **** +- Class Data Type Machine Version +- Entry Phoff Shoff Flags Ehsize +- Phentsize Phnum Shentsz Shnum Shstrndx +- +- 1 1 2 3 1 +- 0x80499cc 0x34 0x96200 0 0x34 +- 0x20 5 0x28 22 19 +- +- * These are the program headers. "Offset" is the file offset to the +- * segment. "Vaddr" is the memory load address. "Filesz" is the +- * segment size as it appears in the file, and "Memsz" is the size in +- * memory. Below, the third segment is the code and the fourth is the +- * data: the difference between Filesz and Memsz is .bss +- +- raid:/nfs/raid/src/dist-18.56/src> dump -o temacs +- +- temacs: +- ***** PROGRAM EXECUTION HEADER ***** +- Type Offset Vaddr Paddr +- Filesz Memsz Flags Align +- +- 6 0x34 0x8048034 0 +- 0xa0 0xa0 5 0 +- +- 3 0xd4 0 0 +- 0x13 0 4 0 +- +- 1 0x34 0x8048034 0 +- 0x3f2f9 0x3f2f9 5 0x1000 +- +- 1 0x3f330 0x8088330 0 +- 0x215c4 0x25a60 7 0x1000 +- +- 2 0x60874 0x80a9874 0 +- 0x80 0 7 0 +- +- raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs +- +- xemacs: +- ***** PROGRAM EXECUTION HEADER ***** +- Type Offset Vaddr Paddr +- Filesz Memsz Flags Align +- +- 6 0x34 0x8048034 0 +- 0xa0 0xa0 5 0 +- +- 3 0xd4 0 0 +- 0x13 0 4 0 +- +- 1 0x34 0x8048034 0 +- 0x3f2f9 0x3f2f9 5 0x1000 +- +- 1 0x3f330 0x8088330 0 +- 0x3e4d0 0x3e4d0 7 0x1000 +- +- 2 0x60874 0x80a9874 0 +- 0x80 0 7 0 +- +- +- */ +- +-/* Modified by wtien@urbana.mcd.mot.com of Motorola Inc. +- * +- * The above mechanism does not work if the unexeced ELF file is being +- * re-layout by other applications (such as `strip'). All the applications +- * that re-layout the internal of ELF will layout all sections in ascending +- * order of their file offsets. After the re-layout, the data2 section will +- * still be the LAST section in the section header vector, but its file offset +- * is now being pushed far away down, and causes part of it not to be mapped +- * in (ie. not covered by the load segment entry in PHDR vector), therefore +- * causes the new binary to fail. +- * +- * The solution is to modify the unexec algorithm to insert the new data2 +- * section header right before the new bss section header, so their file +- * offsets will be in the ascending order. Since some of the section's (all +- * sections AFTER the bss section) indexes are now changed, we also need to +- * modify some fields to make them point to the right sections. This is done +- * by macro PATCH_INDEX. All the fields that need to be patched are: +- * +- * 1. ELF header e_shstrndx field. +- * 2. section header sh_link and sh_info field. +- * 3. symbol table entry st_shndx field. +- * +- * The above example now should look like: +- +- **** SECTION HEADER TABLE **** +- [No] Type Flags Addr Offset Size Name +- Link Info Adralgn Entsize +- +- [1] 1 2 0x80480d4 0xd4 0x13 .interp +- 0 0 0x1 0 +- +- [2] 5 2 0x80480e8 0xe8 0x388 .hash +- 3 0 0x4 0x4 +- +- [3] 11 2 0x8048470 0x470 0x7f0 .dynsym +- 4 1 0x4 0x10 +- +- [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr +- 0 0 0x1 0 +- +- [5] 9 2 0x8049010 0x1010 0x338 .rel.plt +- 3 7 0x4 0x8 +- +- [6] 1 6 0x8049348 0x1348 0x3 .init +- 0 0 0x4 0 +- +- [7] 1 6 0x804934c 0x134c 0x680 .plt +- 0 0 0x4 0x4 +- +- [8] 1 6 0x80499cc 0x19cc 0x3c56f .text +- 0 0 0x4 0 +- +- [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini +- 0 0 0x4 0 +- +- [10] 1 2 0x8085f40 0x3df40 0x69c .rodata +- 0 0 0x4 0 +- +- [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1 +- 0 0 0x4 0 +- +- [12] 1 3 0x8088330 0x3f330 0x20afc .data +- 0 0 0x4 0 +- +- [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1 +- 0 0 0x4 0 +- +- [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got +- 0 0 0x4 0x4 +- +- [15] 6 3 0x80a9874 0x60874 0x80 .dynamic +- 4 0 0x4 0x8 +- +- [16] 1 3 0x80a98f4 0x608f4 0x1cf0c .data +- 0 0 0x4 0 +- +- [17] 8 3 0x80c6800 0x7d800 0 .bss +- 0 0 0x4 0 +- +- [18] 2 0 0 0x7d800 0x9b90 .symtab +- 19 371 0x4 0x10 +- +- [19] 3 0 0 0x87390 0x8526 .strtab +- 0 0 0x1 0 +- +- [20] 3 0 0 0x8f8b6 0x93 .shstrtab +- 0 0 0x1 0 +- +- [21] 1 0 0 0x8f949 0x68b7 .comment +- 0 0 0x1 0 +- +- */ + + /* We do not use mmap because that fails with NFS. + Instead we read the whole file, modify it, and write it out. */ +@@ -552,45 +211,15 @@ entry_address (void *section_h, ptrdiff_ + #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; + +-/* 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 false; return -1 if NOERROR is true. */ +- +-static ptrdiff_t +-find_section (const char *name, const char *section_names, const char *file_name, +- ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h, +- bool noerror) +-{ +- ptrdiff_t idx; +- +- for (idx = 1; idx < old_file_h->e_shnum; idx++) +- { +- char const *found_name = section_names + OLD_SECTION_H (idx).sh_name; +-#ifdef UNEXELF_DEBUG +- fprintf (stderr, "Looking for %s - found %s\n", name, found_name); +-#endif +- if (strcmp (name, found_name) == 0) +- return idx; +- } +- +- if (! noerror) +- fatal ("Can't find %s in %s", name, file_name); +- return -1; +-} +- + /* **************************************************************** + * unexec + * + * driving logic. + * +- * In ELF, this works by replacing the old .bss section with a new +- * .data section, and inserting an empty .bss immediately afterwards. ++ * In ELF, this works by replacing the old bss SHT_NOBITS section with ++ * a new, larger, SHT_PROGBITS section. + * + */ + void +@@ -615,18 +244,16 @@ unexec (const char *new_name, const char + ElfW (Phdr) *old_program_h, *new_program_h; + ElfW (Shdr) *old_section_h, *new_section_h; + +- /* Point to the section name table in the old file. */ +- char *old_section_names; ++ /* Point to the section name table. */ ++ char *old_section_names, *new_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 (Off) old_bss_offset, new_data2_offset; + +- ptrdiff_t n, nn; +- ptrdiff_t old_bss_index, old_data_index; ++ ptrdiff_t n; ++ ptrdiff_t old_bss_index; + struct stat stat_buf; + off_t old_file_size; + int mask; +@@ -689,7 +316,7 @@ unexec (const char *new_name, const char + 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. */ ++ /* Find the last bss style section in the bss segment range. */ + old_bss_index = -1; + for (n = old_file_h->e_shnum; --n > 0; ) + { +@@ -698,22 +325,15 @@ unexec (const char *new_name, const char + && 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_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. */ +- +- old_data_index = find_section (".data", old_section_names, +- old_name, old_file_h, old_section_h, 0); +- + new_break = sbrk (0); + 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_bss_offset; + +@@ -723,7 +343,6 @@ unexec (const char *new_name, const char + DEBUG_LOG (old_bss_size); + DEBUG_LOG (old_bss_offset); + DEBUG_LOG (new_bss_addr); +- DEBUG_LOG (new_data2_addr); + DEBUG_LOG (new_data2_size); + DEBUG_LOG (new_data2_offset); + #endif +@@ -739,7 +358,7 @@ unexec (const char *new_name, const char + 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_size; ++ new_file_size = old_file_size + new_data2_size; + + if (ftruncate (new_file, new_file_size)) + fatal ("Can't ftruncate (%s): %s", new_name, strerror (errno)); +@@ -755,21 +374,18 @@ unexec (const char *new_name, const char + new_file_h = (ElfW (Ehdr) *) new_base; + memcpy (new_file_h, old_file_h, old_file_h->e_ehsize); + +- /* Fix up file header. We'll add one section. Section header is +- further away now. */ ++ /* Fix up file header. Section header is further away now. */ + + 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 + 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); ++ memcpy (new_section_h, old_section_h, ++ old_file_h->e_shnum * old_file_h->e_shentsize); + + #ifdef UNEXELF_DEBUG + DEBUG_LOG (old_file_h->e_shoff); +@@ -788,42 +404,21 @@ unexec (const char *new_name, const char + /* 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. 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. */ +- for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++) ++ /* Walk through all section headers, copying data and updating. */ ++ for (n = 1; n < old_file_h->e_shnum; n++) + { + 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. */ +- if (n == old_bss_index) +- { +- /* Steal the data section header for this data2 section. */ +- memcpy (new_shdr, &OLD_SECTION_H (old_data_index), +- new_file_h->e_shentsize); +- +- new_shdr->sh_addr = new_data2_addr; +- new_shdr->sh_offset = new_data2_offset; +- new_shdr->sh_size = new_data2_size; +- new_shdr->sh_addralign = 1; +- nn++; +- new_shdr++; +- } +- +- memcpy (new_shdr, old_shdr, old_file_h->e_shentsize); ++ ElfW (Shdr) *new_shdr = &NEW_SECTION_H (n); + + 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)) + { ++ /* This section now has file backing. */ ++ new_shdr->sh_type = SHT_PROGBITS; ++ + /* 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 +@@ -838,35 +433,20 @@ unexec (const char *new_name, const char + 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_SIZE. */ +- +- 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 +- header table entry. */ +- if (new_shdr->sh_offset > new_file_h->e_shoff) +- new_shdr->sh_offset += new_file_h->e_shentsize; ++ /* Extend the size of the last bss section to cover dumped ++ data. */ ++ if (n == old_bss_index) ++ new_shdr->sh_size = new_bss_addr - new_shdr->sh_addr; ++ ++ /* We have already copied this section from the current ++ process. */ ++ continue; + } + +- /* 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_shdr->sh_link); +- /* For symbol tables, info is a symbol table index, +- so don't change it. */ +- if (new_shdr->sh_type != SHT_SYMTAB +- && new_shdr->sh_type != SHT_DYNSYM) +- PATCH_INDEX (new_shdr->sh_info); ++ /* Any section that was originally placed after the .bss ++ section should now be offset by NEW_DATA2_SIZE. */ ++ if (new_shdr->sh_offset >= old_bss_offset) ++ new_shdr->sh_offset += new_data2_size; + + /* Now, start to copy the content of sections. */ + if (new_shdr->sh_type == SHT_NULL +@@ -982,24 +562,6 @@ unexec (const char *new_name, const char + } + } + #endif /* __sgi */ +- +- /* Patch st_shndx field of symbol table. */ +- if (new_shdr->sh_type == SHT_SYMTAB +- || new_shdr->sh_type == SHT_DYNSYM) +- { +- 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_XINDEX) +- fatal ("SHT_SYMTAB_SHNDX unsupported"); +- if (sym->st_shndx == SHN_UNDEF +- || sym->st_shndx >= SHN_LORESERVE) +- continue; +- +- PATCH_INDEX (sym->st_shndx); +- } +- } + } + + /* Update the symbol values of _edata and _end. */ +@@ -1043,15 +605,10 @@ unexec (const char *new_name, const char + ElfW (Shdr) *new_shdr = &NEW_SECTION_H (symp->st_shndx); + if (new_shdr->sh_type != SHT_NOBITS) + { +- ElfW (Shdr) *old_shdr; ++ ElfW (Shdr) *old_shdr = &OLD_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--; +- old_shdr = &OLD_SECTION_H (nn); + if (old_shdr->sh_type == SHT_NOBITS) + memset (new_base + newoff, 0, symp->st_size); + else +@@ -1066,6 +623,25 @@ unexec (const char *new_name, const char + } + } + ++ /* Modify the names of sections we changed from SHT_NOBITS to ++ SHT_PROGBITS. This is really just cosmetic, but some tools that ++ (wrongly) operate on section names rather than types might be ++ confused by a SHT_PROGBITS .bss section. */ ++ new_section_names = ((char *) new_base ++ + NEW_SECTION_H (new_file_h->e_shstrndx).sh_offset); ++ for (n = new_file_h->e_shnum; 0 < --n; ) ++ { ++ ElfW (Shdr) *old_shdr = &OLD_SECTION_H (n); ++ ElfW (Shdr) *new_shdr = &NEW_SECTION_H (n); ++ ++ /* Replace the leading '.' with ','. When .shstrtab is string ++ merged this will rename both .bss and .rela.bss to ,bss and ++ .rela,bss. */ ++ if (old_shdr->sh_type == SHT_NOBITS ++ && new_shdr->sh_type == SHT_PROGBITS) ++ *(new_section_names + new_shdr->sh_name) = ','; ++ } ++ + /* This loop seeks out relocation sections for the data section, so + that it can undo relocations performed by the runtime loader. */ + for (n = new_file_h->e_shnum; 0 < --n; ) diff --git a/emacs-24-0018-src-unexelf.c-NEW_PROGRAM_H-Remove-unused-macro-Bug-.patch b/emacs-24-0018-src-unexelf.c-NEW_PROGRAM_H-Remove-unused-macro-Bug-.patch new file mode 100644 index 0000000..dfd8544 --- /dev/null +++ b/emacs-24-0018-src-unexelf.c-NEW_PROGRAM_H-Remove-unused-macro-Bug-.patch @@ -0,0 +1,41 @@ +From 9b52726df50cc9b4fdfce2ed1dc114311dc60a93 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +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 +--- + src/unexelf.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +Index: emacs-24.5/src/unexelf.c +=================================================================== +--- emacs-24.5.orig/src/unexelf.c ++++ emacs-24.5/src/unexelf.c +@@ -208,8 +208,6 @@ entry_address (void *section_h, ptrdiff_ + (*(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 + 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; diff --git a/emacs-24-0019-ELF-unexec-align-section-header.patch b/emacs-24-0019-ELF-unexec-align-section-header.patch new file mode 100644 index 0000000..5d8d2d6 --- /dev/null +++ b/emacs-24-0019-ELF-unexec-align-section-header.patch @@ -0,0 +1,64 @@ +From 0de7316751e94c29aeb4b75731ac6e8c9eba77e6 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +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 +--- + src/unexelf.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +Index: emacs-24.5/src/unexelf.c +=================================================================== +--- emacs-24.5.orig/src/unexelf.c ++++ emacs-24.5/src/unexelf.c +@@ -247,7 +247,7 @@ unexec (const char *new_name, const char + + 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 + + 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 + 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++) diff --git a/emacs.spec b/emacs.spec index 25aebb6..3e6d258 100644 --- a/emacs.spec +++ b/emacs.spec @@ -32,6 +32,17 @@ Patch6: emacs-mercurial.patch # http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=439f483be35a000e7a3bec6acf395ce4d54d6323 # http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=9c86325b69d75e9b17ff468f5a2220597979635f Patch7: emacs-gdb-ascii.patch +# All upstreamed, see the patches for more info +Patch8: emacs-24-0010-ELF-unexec-Correct-section-header-index.patch +Patch9: emacs-24-0011-ELF-unexec-Tidy-code.patch +Patch10: emacs-24-0012-ELF-unexec-Merge-Alpha-and-MIPS-COFF-debug-handling.patch +Patch11: emacs-24-0013-ELF-unexec-Symbol-table-patching.patch +Patch12: emacs-24-0014-ELF-unexec-_OBJC_-symbols-in-bss-sections.patch +Patch13: emacs-24-0015-ELF-unexec-R_-_NONE-relocs.patch +Patch14: emacs-24-0016-ELF-unexec-Drive-from-PT_LOAD-header-rather-than-sec.patch +Patch15: emacs-24-0017-ELF-unexec-Don-t-insert-a-new-section.patch +Patch16: emacs-24-0018-src-unexelf.c-NEW_PROGRAM_H-Remove-unused-macro-Bug-.patch +Patch17: emacs-24-0019-ELF-unexec-align-section-header.patch BuildRequires: atk-devel BuildRequires: cairo-devel @@ -177,6 +188,16 @@ packages that add functionality to Emacs. %patch5 -p1 -b .bbdb %patch6 -p1 %patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 autoconf # We prefer our emacs.desktop file @@ -448,6 +469,9 @@ update-desktop-database &> /dev/null || : %dir %{_datadir}/emacs/site-lisp/site-start.d %changelog +* Mon Feb 15 2016 Jan Synáček - 1:24.5-10 +- fix build failure on ppc64le (#1306793) + * Mon Feb 8 2016 Jan Synáček - 1:24.5-10 - refix: set default value for smime-CA-directory (#1131558)