bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#20614: Segmentation fault when building on Power8 Little Endian


From: Petr Hracek
Subject: bug#20614: Segmentation fault when building on Power8 Little Endian
Date: Tue, 13 Oct 2015 09:30:14 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0

On 10/10/2015 05:44 PM, Andreas Schwab wrote:
Please try this patch instead:

diff --git a/src/unexelf.c b/src/unexelf.c
index 483da6e..2e8b4c7 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -616,6 +616,32 @@ find_section (const char *name, const char *section_names, 
const char *file_name
    return -1;
  }
+/* Find the index of the first bss (NOBITS) section, count the number
+   of bss sections that follow and compute the overall size of these
+   sections.  */
+static int
+find_bss_sections (const char *file_name,
+                  ElfW(Ehdr) *old_file_h, ElfW(Shdr) *old_section_h,
+                  ElfW (Word) *size, int *num)
+{
+  ptrdiff_t idx;
+
+  for (idx = 1; idx < old_file_h->e_shnum; idx++)
+    if (OLD_SECTION_H (idx).sh_type == SHT_NOBITS)
+      {
+       ptrdiff_t idx2 = idx;
+
+       while (OLD_SECTION_H (idx2 + 1).sh_type == SHT_NOBITS)
+         idx2++;
+       *size = (OLD_SECTION_H (idx2).sh_addr + OLD_SECTION_H (idx2).sh_size
+                - OLD_SECTION_H (idx).sh_addr);
+       *num = idx2 + 1 - idx;
+       return idx;
+      }
+  fatal ("Can't find bss section in %s", file_name);
+  return -1;
+}
+
  /* ****************************************************************
   * unexec
   *
@@ -652,13 +678,14 @@ unexec (const char *new_name, const char *old_name)
ElfW (Addr) old_bss_addr, new_bss_addr;
    ElfW (Word) old_bss_size, new_data2_size;
+  int n_bss_sections;
    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_bss_index;
    ptrdiff_t old_data_index, new_data2_index;
  #if defined _SYSTYPE_SYSV || defined __sgi
    ptrdiff_t old_mdebug_index;
@@ -716,50 +743,12 @@ unexec (const char *new_name, const char *old_name)
    /* 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;
+  old_bss_index = find_bss_sections (old_name, old_file_h, old_section_h,
+                                    &old_bss_size, &n_bss_sections);
- 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)))
-    {
-      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;
-    }
-  else
-    {
-      old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr;
-      old_bss_size = OLD_SECTION_H (old_bss_index).sh_size
-       + OLD_SECTION_H (old_sbss_index).sh_size;
-      old_bss_offset = OLD_SECTION_H (old_sbss_index).sh_offset;
-      new_data2_index = old_sbss_index;
-    }
+  old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
+  old_bss_offset = OLD_SECTION_H (old_bss_index).sh_offset;
+  new_data2_index = old_bss_index;
/* Find the old .data section. Figure out parameters of
       the new data2 and bss sections.  */
@@ -851,20 +840,11 @@ unexec (const char *new_name, const char *old_name)
      {
        /* 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)
+      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)))
+         > round_up (old_bss_addr, alignment))
          fatal ("Program segment above .bss in %s", old_name);
if (NEW_PROGRAM_H (n).p_type == PT_LOAD
@@ -932,12 +912,10 @@ unexec (const char *new_name, const char *old_name)
        memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
              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 (n >= old_bss_index && n < old_bss_index + n_bss_sections)
        {
+         /* The new bss section's size is zero, and its file offset
+            and virtual address should be off by NEW_DATA2_SIZE.  */
          /* 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;
@@ -998,15 +976,6 @@ temacs:
          && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM)
        PATCH_INDEX (NEW_SECTION_H (nn).sh_info);
- if (old_sbss_index != -1)
-       if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".sbss"))
-         {
-           NEW_SECTION_H (nn).sh_offset =
-             round_up (NEW_SECTION_H (nn).sh_offset,
-                       NEW_SECTION_H (nn).sh_addralign);
-           NEW_SECTION_H (nn).sh_type = SHT_PROGBITS;
-         }
-
        /* Now, start to copy the content of sections.  */
        if (NEW_SECTION_H (nn).sh_type == SHT_NULL
          || NEW_SECTION_H (nn).sh_type == SHT_NOBITS)
@@ -1226,7 +1195,7 @@ temacs:
              nn = symp->st_shndx;
              if (nn > old_bss_index)
                nn--;
-             if (nn == old_bss_index)
+             if (nn >= old_bss_index && nn < old_bss_index + n_bss_sections)
                memset (new, 0, symp->st_size);
              else
                {
Well, with this patch emacs failed again with message like:
Dumping under the name emacs
emacs: Program segment above .bss in /home/phracek/rpmbuild/BUILD/emacs-24.3/src/temacs
make[2]: *** [bootstrap-emacs] Error 1
make[2]: Leaving directory `/home/phracek/rpmbuild/BUILD/emacs-24.3/src'
make[1]: *** [src] Error 2

Well:
Header seems to be fine:
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Ident Version:                     1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           PowerPC 64-bit
  Version:                           1 (current)
  Entry point address:               0x100184f0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          14281064 (bytes into file)
  Flags:                             0x2
  Size of this header:               64 (bytes)
  Size of program header entries:    56 (bytes)
  Number of program headers entries: 9
  Size of section header entries:    64 (bytes)
  Number of section headers entries: 34
  Section header string table index: 31

Section Headers:
[Nr] Name Type Addr Off Size ES Flags Lk Inf Al [ 0] NULL 0000000000000000 00000000 00000000 0 0 0 0 [ 1] .interp PROGBITS 0000000010000238 00000238 00000011 0 A 0 0 1 [ 2] .note.ABI-tag NOTE 000000001000024c 0000024c 00000020 0 A 0 0 4 [ 3] .note.gnu.build-id NOTE 000000001000026c 0000026c 00000024 0 A 0 0 4 [ 4] .gnu.hash GNU_HASH 0000000010000290 00000290 000000dc 0 A 5 0 8 [ 5] .dynsym DYNSYM 0000000010000370 00000370 000063f0 24 A 6 1 8 [ 6] .dynstr STRTAB 0000000010006760 00006760 00004ae9 0 A 0 0 1 [ 7] .gnu.version GNU_versym 000000001000b24a 0000b24a 00000854 2 A 5 0 2 [ 8] .gnu.version_r GNU_verneed 000000001000baa0 0000baa0 00000160 0 A 6 10 8 [ 9] .rela.toc RELA 000000001000bc00 0000bc00 00000330 24 A 5 0 8 [10] .rela.plt RELA 000000001000bf30 0000bf30 000060d8 24 A 5 20 8 [11] .init PROGBITS 0000000010012020 00012020 0000004c 0 AX 0 0 32 [12] .text PROGBITS 0000000010012080 00012080 00236f60 0 AX 0 0 32 [13] .fini PROGBITS 0000000010248fe0 00248fe0 00000024 0 AX 0 0 4 [14] .rodata PROGBITS 0000000010249008 00249008 0001fde0 0 A 0 0 8 [15] .eh_frame_hdr PROGBITS 0000000010268de8 00268de8 000073c4 0 A 0 0 4 [16] .eh_frame PROGBITS 00000000102701b0 002701b0 0002e2d8 0 A 0 0 8 [17] .data.rel.ro PROGBITS 00000000102af640 0029f640 00000430 0 WA 0 0 8 [18] .dynamic DYNAMIC 00000000102afa70 0029fa70 00000440 16 WA 6 0 8 [19] .got PROGBITS 00000000102afeb0 0029feb0 00000150 8 WA 0 0 8 [20] .plt NOBITS 00000000102b0000 002a0000 00002058 8 WA 0 0 8 [21] .data PROGBITS 00000000102b2058 002a2058 002c6d36 0 WA 0 0 8 [22] .bss NOBITS 0000000010578d90 00568d8e 00087740 0 WA 0 0 16 [23] .comment PROGBITS 0000000000000000 00568d8e 00000058 1 MS 0 0 1 [24] .debug_aranges PROGBITS 0000000000000000 00568de6 00001350 0 0 0 1 [25] .debug_info PROGBITS 0000000000000000 0056a136 003aea05 0 0 0 1 [26] .debug_abbrev PROGBITS 0000000000000000 00918b3b 00021af4 0 0 0 1 [27] .debug_line PROGBITS 0000000000000000 0093a62f 0007c2d9 0 0 0 1 [28] .debug_str PROGBITS 0000000000000000 009b6908 00047fb3 1 MS 0 0 1 [29] .debug_loc PROGBITS 0000000000000000 009fe8bb 00327db2 0 0 0 1 [30] .debug_ranges PROGBITS 0000000000000000 00d2666d 000781b0 0 0 0 1 [31] .shstrtab STRTAB 0000000000000000 00d9e81d 00000148 0 0 0 1 [32] .symtab SYMTAB 0000000000000000 00d9f1e8 00037ba8 24 33 5414 8 [33] .strtab STRTAB 0000000000000000 00dd6d90 0002e227 0 0 0 1

What debug information do you need?

--
Petr Hracek
Software Engineer
Developer Experience
Red Hat, Inc
Mob: +420777056169
email: phracek@redhat.com






reply via email to

[Prev in Thread] Current Thread [Next in Thread]