This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: [Fwd: more on h8300-rtems/coff core dump]
- To: joel dot sherrill at OARcorp dot com
- Subject: Re: [Fwd: more on h8300-rtems/coff core dump]
- From: Nick Clifton <nickc at redhat dot com>
- Date: Wed, 1 Nov 2000 13:11:28 -0800
- CC: alan at linuxcare dot com dot au, binutils at sources dot redhat dot com
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;
}