[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#22061: Acknowledgement (24.5; Build failure on sparc64, Bus Error in
From: |
David Matthew Mattli |
Subject: |
bug#22061: Acknowledgement (24.5; Build failure on sparc64, Bus Error in src/unexelf.c) |
Date: |
Mon, 30 Nov 2015 11:46:44 -0600 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) |
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.