This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [patch] bfd/elf.c: fix section overlap warning again
OK, this is what I think we need. I'm committing the tc-rx.c
fixes, but will wait a while for comments on the other changes.
bfd/
* elf.c (assign_file_positions_for_load_sections): Catch overlap
for sections that wrap around the address space. Replace a
warning that duplicates ld's --check-sections error with a
warning that lma has been adjusted for overlapping sections.
ld/
* ldlang.c (lang_check_section_addresses): Catch overlap for
sections that wrap around the address space.
gas/
* config/tc-rx.c (md_estimate_size_before_relax): Fix format
specifier warnings for 32-bit host when --enable-64-bit-bfd.
(rx_relax_frag, md_convert_frag): Likewise.
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.511
diff -u -p -r1.511 elf.c
--- bfd/elf.c 18 May 2010 03:31:05 -0000 1.511
+++ bfd/elf.c 16 Jul 2010 03:51:41 -0000
@@ -4457,15 +4457,19 @@ assign_file_positions_for_load_sections
&& ((this_hdr->sh_flags & SHF_TLS) == 0
|| p->p_type == PT_TLS))))
{
- bfd_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
+ bfd_vma p_start = p->p_paddr;
+ bfd_vma p_end = p_start + p->p_memsz;
+ bfd_vma s_start = sec->lma;
+ bfd_vma adjust = s_start - p_end;
- if (sec->lma < p->p_paddr + p->p_memsz)
+ if (s_start < p_end
+ || p_end < p_start)
{
(*_bfd_error_handler)
- (_("%B: section %A lma 0x%lx overlaps previous sections"),
- abfd, sec, (unsigned long) sec->lma);
+ (_("%B: section %A lma %#lx adjusted to %#lx"), abfd, sec,
+ (unsigned long) s_start, (unsigned long) p_end);
adjust = 0;
- sec->lma = p->p_paddr + p->p_memsz;
+ sec->lma = p_end;
}
p->p_memsz += adjust;
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.335
diff -u -p -r1.335 ldlang.c
--- ld/ldlang.c 9 Apr 2010 14:40:12 -0000 1.335
+++ ld/ldlang.c 16 Jul 2010 03:51:44 -0000
@@ -4561,13 +4561,13 @@ sort_sections_by_lma (const void *arg1,
static void
lang_check_section_addresses (void)
{
- asection *s, *os;
+ asection *s, *p;
asection **sections, **spp;
unsigned int count;
bfd_vma s_start;
bfd_vma s_end;
- bfd_vma os_start;
- bfd_vma os_end;
+ bfd_vma p_start;
+ bfd_vma p_end;
bfd_size_type amt;
lang_memory_region_type *m;
@@ -4600,24 +4600,29 @@ lang_check_section_addresses (void)
spp = sections;
s = *spp++;
- s_start = bfd_section_lma (link_info.output_bfd, s);
+ s_start = s->lma;
s_end = s_start + TO_ADDR (s->size) - 1;
for (count--; count; count--)
{
/* We must check the sections' LMA addresses not their VMA
addresses because overlay sections can have overlapping VMAs
but they must have distinct LMAs. */
- os = s;
- os_start = s_start;
- os_end = s_end;
+ p = s;
+ p_start = s_start;
+ p_end = s_end;
s = *spp++;
- s_start = bfd_section_lma (link_info.output_bfd, s);
+ s_start = s->lma;
s_end = s_start + TO_ADDR (s->size) - 1;
- /* Look for an overlap. */
- if (s_end >= os_start && s_start <= os_end)
+ /* Look for an overlap. We have sorted sections by lma, so we
+ know that s_start >= p_start. Besides the obvious case of
+ overlap when the current section starts before the previous
+ one ends, we also must have overlap if the previous section
+ wraps around the address space. */
+ if (s_start <= p_end
+ || p_end < p_start)
einfo (_("%X%P: section %s loaded at [%V,%V] overlaps section %s loaded at [%V,%V]\n"),
- s->name, s_start, s_end, os->name, os_start, os_end);
+ s->name, s_start, s_end, p->name, p_start, p_end);
}
free (sections);
Index: gas/config/tc-rx.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-rx.c,v
retrieving revision 1.4
diff -u -p -r1.4 tc-rx.c
--- gas/config/tc-rx.c 2 Jul 2010 20:40:28 -0000 1.4
+++ gas/config/tc-rx.c 16 Jul 2010 03:51:45 -0000
@@ -1344,8 +1344,9 @@ md_estimate_size_before_relax (fragS * f
int delta;
tprintf ("\033[32m est frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
- fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal),
- fragP->fr_fix, fragP->fr_var, fragP->fr_offset,
+ (unsigned long) (fragP->fr_address
+ + (fragP->fr_opcode - fragP->fr_literal)),
+ (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
/* This is the size of the opcode that's accounted for in fr_fix. */
@@ -1376,8 +1377,9 @@ rx_relax_frag (segT segment ATTRIBUTE_UN
int ri;
tprintf ("\033[36mrelax frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d str %ld\033[0m\n",
- fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal),
- fragP->fr_fix, fragP->fr_var, fragP->fr_offset,
+ (unsigned long) (fragP->fr_address
+ + (fragP->fr_opcode - fragP->fr_literal)),
+ (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch);
optype = rx_opcode_type (fragP->fr_opcode);
@@ -1435,7 +1437,9 @@ rx_relax_frag (segT segment ATTRIBUTE_UN
switch (fragP->tc_frag_data->relax[ri].type)
{
case RX_RELAX_BRANCH:
- tprintf ("branch, addr %08lx pc %08lx disp %ld\n", addr0, mypc, addr0-mypc);
+ tprintf ("branch, addr %08lx pc %08lx disp %ld\n",
+ (unsigned long) addr0, (unsigned long) mypc,
+ (long) (addr0 - mypc));
disp = (int) addr0 - (int) mypc;
switch (optype)
@@ -1491,7 +1495,8 @@ rx_relax_frag (segT segment ATTRIBUTE_UN
break;
case RX_RELAX_IMM:
- tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n", addr0, mypc,
+ tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n",
+ (unsigned long) addr0, (unsigned long) mypc,
fragP->tc_frag_data->relax[ri].field_pos,
fragP->tc_frag_data->relax[ri].val_ofs);
@@ -1574,9 +1579,11 @@ md_convert_frag (bfd * abfd ATTRIBUTE_
fixS * fix = rxb->fixups[fi].fixP;
tprintf ("\033[31mconvrt frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
- fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal),
- fragP->fr_fix, fragP->fr_var, fragP->fr_offset,
- fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
+ (unsigned long) (fragP->fr_address
+ + (fragP->fr_opcode - fragP->fr_literal)),
+ (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
+ fragP->fr_literal, fragP->fr_opcode, fragP->fr_type,
+ fragP->fr_subtype);
#if TRACE_RELAX
{
@@ -1613,7 +1620,9 @@ md_convert_frag (bfd * abfd ATTRIBUTE_
reloc_type = BFD_RELOC_NONE;
reloc_adjust = 0;
- tprintf ("convert, op is %d, disp %d (%lx-%lx)\n", rx_opcode_type (fragP->fr_opcode), disp, addr0, mypc);
+ tprintf ("convert, op is %d, disp %d (%lx-%lx)\n",
+ rx_opcode_type (fragP->fr_opcode), disp,
+ (unsigned long) addr0, (unsigned long) mypc);
switch (fragP->tc_frag_data->relax[ri].type)
{
case RX_RELAX_BRANCH:
@@ -1917,7 +1926,7 @@ md_convert_frag (bfd * abfd ATTRIBUTE_
}
fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
- tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", fragP->fr_fix,
+ tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
fragP->fr_var = 0;
@@ -1925,7 +1934,8 @@ md_convert_frag (bfd * abfd ATTRIBUTE_
&& ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
!= fragP->fr_fix))
as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
- fragP->fr_fix, fragP->fr_address, fragP->fr_next->fr_address);
+ (long) fragP->fr_fix,
+ (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
}
#undef OPCODE
--
Alan Modra
Australia Development Lab, IBM