This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]