Subject: Re: bug#22061: Acknowledgement (24.5; Build failure on sparc64, Bus Error in src/unexelf.c)

From: David Matthew Mattli <[email-masked]>
Date: Mon, 30 Nov 2015 11:46:44 -0600

Looking at it some more I think I have a better understanding of what's
going on in the git master sources.

The SIGBUS occurs when accessing the pointer calculated with the
NEW_SECTION_H macro:

    static void *
    entry_address (void *section_h, ptrdiff_t idx, ptrdiff_t entsize)
    {
       char *h = section_h;
       return h + idx * entsize;
    }

    #define NEW_SECTION_H(n) \
      (*(ElfW (Shdr) *) entry_address (new_section_h, n,
      new_file_h->e_shentsize))

This should generate aligned addresses, assuming 'new_section_h' is
aligned because it's adding multiples of 'new_file_h->e_shentsize' which
is 64. However new_section_h is /not/ aligned so the output of the macro
is also unaligned.

    (gdb) print new_section_h
    $27 = (Elf64_Shdr *) 0xffff800114f76933
    (gdb) print (unsigned long)new_section_h % 8
    $28 = 3

The variable 'new_section_h' is assigned on line 380:

      new_section_h = (ElfW (Shdr) *) ((byte *) new_base +
      new_file_h->e_shoff);

So its the sum of new_base and 'new_file_h->e_shoff'. new_base is highly
aligned so the problem must be 'new_file_h->e_shoff'

    (gdb) print new_base
    $29 = (caddr_t) 0xffff800112ca8000 "\177ELF\002\002\001"
    (gdb) print new_file_h->e_shoff
    $30 = 36497715

In turn, 'new_file_h->e_shoff' s misalignment comes from when
new_data2_size is added to it on line 377.

    if (new_file_h->e_shoff >= old_bss_offset)
        new_file_h->e_shoff += new_data2_size;

Finally the value of new_data2_size is calculated on line 334:

  new_data2_size = new_bss_addr - old_bss_addr;

  (gdb) print (unsigned long)(new_data2_size) % 8
  $39 = 3

Because 'new_data2_size' is eventually added to 'new_section_h' it needs
to be aligned or 'new_section_h' has to be padded to a multiple of 8.

I think the easiest thing to do would be to round 'new_data2_size' to
the nearest multiple of 8.