From 009a61c9a1881bcd7844281a85d1ee597343cf48 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 21 Aug 2013 08:15:23 +0000 Subject: 2013-08-21 Tristan Gingold * coff-rs6000.c (_bfd_xcoff_sizeof_headers): Also count .ovrflo sections. * coffcode.h (coff_compute_section_file_positions): Force match between file offset and vma offset. --- bfd/ChangeLog | 7 +++++++ bfd/coff-rs6000.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ bfd/coffcode.h | 54 ++++++++++++++++++++++++++++-------------------------- 3 files changed, 89 insertions(+), 26 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3c36e070c1..824c1716d0 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2013-08-21 Tristan Gingold + + * coff-rs6000.c (_bfd_xcoff_sizeof_headers): Also count + .ovrflo sections. + * coffcode.h (coff_compute_section_file_positions): Force + match between file offset and vma offset. + 2013-08-21 Alan Modra * elflink.c (_bfd_elf_merge_symbol): Set *poldbfd, *poldweak, diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 309ea7749d..0386e9a2fd 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -2570,6 +2570,60 @@ _bfd_xcoff_sizeof_headers (bfd *abfd, else size += SMALL_AOUTSZ; size += abfd->section_count * SCNHSZ; + + if (info->strip != strip_all) + { + /* There can be additional sections just for dealing with overflow in + reloc and lineno counts. But the numbers of relocs and lineno aren't + known when bfd_sizeof_headers is called, so we compute them by + summing the numbers from input sections. */ + struct nbr_reloc_lineno + { + unsigned int reloc_count; + unsigned int lineno_count; + }; + struct nbr_reloc_lineno *n_rl; + bfd *sub; + int max_index; + asection *s; + + /* Although the number of sections is known, the maximum value of + section->index isn't (because some sections may have been removed). + Don't try to renumber sections, just compute the upper bound. */ + max_index = 0; + for (s = abfd->sections; s != NULL; s = s->next) + if (s->index > max_index) + max_index = s->index; + + /* Allocate the per section counters. It could be possible to use a + preallocated array as the number of sections is limited on XCOFF, + but this creates a maintainance issue. */ + n_rl = bfd_zmalloc ((max_index + 1) * sizeof (*n_rl)); + if (n_rl == NULL) + return -1; + + /* Sum. */ + for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + for (s = sub->sections; s != NULL; s = s->next) + { + struct nbr_reloc_lineno *e = &n_rl[s->output_section->index]; + e->reloc_count += s->reloc_count; + e->lineno_count += s->lineno_count; + } + + /* Add the size of a section for each section with an overflow. */ + for (s = abfd->sections; s != NULL; s = s->next) + { + struct nbr_reloc_lineno *e = &n_rl[s->index]; + + if (e->reloc_count >= 0xffff + || (e->lineno_count >= 0xffff && info->strip != strip_debugger)) + size += SCNHSZ; + } + + free (n_rl); + } + return size; } diff --git a/bfd/coffcode.h b/bfd/coffcode.h index a198e1c730..542b5b7039 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -3363,36 +3363,38 @@ coff_compute_section_file_positions (bfd * abfd) padding the previous section up if necessary. */ old_sofar = sofar; + sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); + #ifdef RS6000COFF_C - /* AIX loader checks the text section alignment of (vma - filepos) - So even though the filepos may be aligned wrt the o_algntext, for - AIX executables, this check fails. This shows up when a native - AIX executable is stripped with gnu strip because the default vma - of native is 0x10000150 but default for gnu is 0x10000140. Gnu - stripped gnu excutable passes this check because the filepos is - 0x0140. This problem also show up with 64 bit shared objects. The - data section must also be aligned. */ + /* Make sure the file offset and the vma of .text/.data are at the + same page offset, so that the file can be mmap'ed without being + relocated. Failing that, AIX is able to load and execute the + program, but it will be silently relocated (possible as + executables are PIE). But the relocation is slightly costly and + complexify the use of addr2line or gdb. So better to avoid it, + like does the native linker. Usually gnu ld makes sure that + the vma of .text is the file offset so this issue shouldn't + appear unless you are stripping such an executable. + + AIX loader checks the text section alignment of (vma - filepos), + and the native linker doesn't try to align the text sections. + For example: + + 0 .text 000054cc 10000128 10000128 00000128 2**5 + CONTENTS, ALLOC, LOAD, CODE + */ + if (!strcmp (current->name, _TEXT) || !strcmp (current->name, _DATA)) { - bfd_vma pad; - bfd_vma align; - - sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); - - align = 1 << current->alignment_power; - pad = abs (current->vma - sofar) % align; - - if (pad) - { - pad = align - pad; - sofar += pad; - } - } - else -#else - { - sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); + bfd_vma align = 4096; + bfd_vma sofar_off = sofar % align; + bfd_vma vma_off = current->vma % align; + + if (vma_off > sofar_off) + sofar += vma_off - sofar_off; + else if (vma_off < sofar_off) + sofar += align + vma_off - sofar_off; } #endif if (previous != NULL) -- cgit v1.2.1