This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Proposal to change tc_fix_adjustable API
- From: "Jafa" <jafa at silicondust dot com>
- To: <binutils at sources dot redhat dot com>
- Date: Thu, 19 Dec 2002 18:00:22 -0800
- Subject: Re: Proposal to change tc_fix_adjustable API
- References: <redirect-4870145@silicondust.com>
- Reply-to: "Jafa" <jafa at silicondust dot com>
Recant. Sorry. Just figured out how to fix the problem in the linker and do
a much better job of it.
Nick
----- Original Message -----
From: "Nick Kelsey" <nickk@ubicom.com>
To: <jafa@silicondust.com>
Sent: Thursday, December 19, 2002 4:16 PM
Subject: Proposal to change tc_fix_adjustable API
*This message was transferred with a trial version of CommuniGate(tm) Pro*
Hi all,
I would like to add a new paramter to the tc_fix_adjustable API:
Current definition:
extern int xxx_fix_adjustable PARAMS ((struct fix *));
New definition:
extern int xxx_fix_adjustable PARAMS ((struct fix *, asection *));
Justification:
The ip2k port uses linker relaxation and stabs for debugging. It is also
common to use ffunction-sections.
If the relocation information is stored in sect+offs form for a call and the
call is to a different section then the linker relaxation will produce
incorrect results as it does not visibility to adjust this relocation.
If the relocation information is left symbolic for the linker it *really*
screws up gdb... it thinks that local jump targets such as .L6 are new
functions and gets even more confised as these labels exist in multiple
files. For example, setting a breakpoint in main.c at a given line will
result in a breakpoint being set in libgcc.
Solution: The linker relaxation can detect a call to the same section,
assume sect+offs and adjust it. Likewise it can detect that a call is to a
different section and know not to adjust it. The trick is getting gas not to
resolve the relocation information to sect+offs for call targets that cross
section boundarys.
Hense:
int
ip2k_fix_adjustable (fix, sec)
fixS *fix;
asection *sec;
{
switch (fix->fx_cgen.opinfo)
{
case BFD_RELOC_IP2K_ADDR16CJP:
case BFD_RELOC_IP2K_PAGE3:
case BFD_RELOC_IP2K_LO8DATA:
case BFD_RELOC_IP2K_HI8DATA:
case BFD_RELOC_IP2K_EX8DATA:
case BFD_RELOC_IP2K_LO8INSN:
case BFD_RELOC_IP2K_HI8INSN:
if ((fix->fx_addsy) && (S_GET_SEGMENT (fix->fx_addsy) != sec))
/* Let the linker resolve these so the linker can relax correctly. */
return 0;
else
return 1;
default:
return 1;
}
}
Thoughts?
Nick