This is the mail archive of the binutils@sources.redhat.com 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]

Re: [Fwd: more on h8300-rtems/coff core dump]


Hi Joel,

  Well I have a patch that is a workaround for this problem.  Actually
  there seems to be two problems to workaround, and the patch covers
  them both.

  The first problem is that the relocs in the .rel section do not
  appear to be sorted by offset.  The code in bfd_coff_reloc16_get_relocated_section
  assumes that they are.  I added a call to qsort to fix this.

  The second problem is that some of the relocs reference offsets that
  are not word aligned.  Once again the code is ready to cope with
  this.

  If you dump the relocs out using 'objdump -r rtems-cpu.rel' for
  example you can see that the exit relocation is at an odd address.

    000000f1 DISP8             exit+0xffffffff

  Also the relocation for CPU_Thread_dispatch_pointer occurs after the
  relocation for Thread_Dispatch, but affects a word at a lower
  address in the .text section:

    00000154 24/pcrell         __Thread_Dispatch
    00000020 32/24 relaxable move  __CPU_Thread_dispatch_pointer

  I am not sure whether these things are actually problems with the
  relocs themselves, or if the relocated_section code is supposed to
  cope with them, so the patch assumes the latter, and works around
  them.

  Try it out and let me know how you get on.

Cheers
	Nick


Index: bfd/reloc16.c
===================================================================
RCS file: /cvs/src//src/bfd/reloc16.c,v
retrieving revision 1.4
diff -p -r1.4 reloc16.c
*** reloc16.c	2000/07/03 17:49:37	1.4
--- reloc16.c	2000/11/01 20:57:59
*************** bfd_coff_reloc16_relax_section (abfd, i,
*** 233,238 ****
--- 233,252 ----
    return true;
  }
  
+ static int
+ compare_relocs (a, b)
+      const void * a;
+      const void * b;
+ {
+   arelent ** a_reloc = (arelent **) a; 
+   arelent ** b_reloc = (arelent **) b;
+ 
+   if (a_reloc[0]->address < b_reloc[0]->address)
+     return -1;
+   
+   return a_reloc[0]->address != b_reloc[0]->address;
+ }
+ 
  bfd_byte *
  bfd_coff_reloc16_get_relocated_section_contents(in_abfd,
  						link_info,
*************** bfd_coff_reloc16_get_relocated_section_c
*** 281,316 ****
  					reloc_vector,
  					symbols);
    if (reloc_count < 0)
!     {
!       free (reloc_vector);
!       return NULL;
!     }
  
!   if (reloc_count > 0)
      {
        arelent **parent = reloc_vector;
-       arelent *reloc;
        unsigned int dst_address = 0;
        unsigned int src_address = 0;
!       unsigned int run;
!       unsigned int idx;
  
        /* Find how long a run we can do.  */
!       while (dst_address < link_order->size)
  	{
  	  reloc = *parent;
  	  if (reloc)
  	    {
  	      /* Note that the relaxing didn't tie up the addresses in the
  		 relocation, so we use the original address to work out the
  		 run of non-relocated data.  */
! 	      run = reloc->address - src_address;
  	      parent++;
  	    }
  	  else
! 	    {
! 	      run = link_order->size - dst_address;
! 	    }
  
  	  /* Copy the bytes.  */
  	  for (idx = 0; idx < run; idx++)
--- 295,336 ----
  					reloc_vector,
  					symbols);
    if (reloc_count < 0)
!     data = NULL;
  
!   else if (reloc_count > 0)
      {
        arelent **parent = reloc_vector;
        unsigned int dst_address = 0;
        unsigned int src_address = 0;
! 	 
!       /* Note the relocs might not be properly
! 	 ordered by offset, so sort them first.  */
!       qsort (parent, reloc_count, sizeof (* parent), compare_relocs);
  
        /* Find how long a run we can do.  */
!       while (dst_address < link_order->size
! 	     && (parent - reloc_vector) < reloc_count)
  	{
+ 	  arelent *reloc;
+ 	  unsigned int run;
+ 	  unsigned int idx;
+ 
  	  reloc = *parent;
+ 
  	  if (reloc)
  	    {
  	      /* Note that the relaxing didn't tie up the addresses in the
  		 relocation, so we use the original address to work out the
  		 run of non-relocated data.  */
! 	      if (reloc->address > src_address)
! 		run = reloc->address - src_address;
! 	      else
! 		run = 0;
! 	      
  	      parent++;
  	    }
  	  else
! 	    run = link_order->size - dst_address;
  
  	  /* Copy the bytes.  */
  	  for (idx = 0; idx < run; idx++)
*************** bfd_coff_reloc16_get_relocated_section_c
*** 318,330 ****
  
  	  /* Now do the relocation.  */
  	  if (reloc)
! 	    {
! 	      bfd_coff_reloc16_extra_cases (input_bfd, link_info, link_order,
! 					    reloc, data, &src_address,
! 					    &dst_address);
! 	    }
  	}
      }
    free ((char *) reloc_vector);
    return data;
  }
--- 338,349 ----
  
  	  /* Now do the relocation.  */
  	  if (reloc)
! 	    bfd_coff_reloc16_extra_cases (input_bfd, link_info, link_order,
! 					  reloc, data, &src_address,
! 					  &dst_address);
  	}
      }
+   
    free ((char *) reloc_vector);
    return data;
  }

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