* write.c (fixup_segment): Do not assume we know the section a
defined weak symbol is in. * config/tc-arm.c (relax_adr, relax_branch, md_apply_fix): Treat weak symbols as not known to be in the same section, even if they are defined. * gas/arm/weakdef-1.s: New. * gas/arm/weakdef-1.d: New. * gas/arm/weakdef-2.s: New. * gas/arm/weakdef-2.d: New. * gas/arm/weakdef-2.l: New.
This commit is contained in:
parent
c0643a5132
commit
77db8e2e96
9 changed files with 110 additions and 32 deletions
|
@ -1,3 +1,11 @@
|
|||
2010-04-29 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* write.c (fixup_segment): Do not assume we know the section a
|
||||
defined weak symbol is in.
|
||||
* config/tc-arm.c (relax_adr, relax_branch, md_apply_fix): Treat
|
||||
weak symbols as not known to be in the same section, even if they
|
||||
are defined.
|
||||
|
||||
2010-04-27 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* config/tc-tic6x.h (tic6x_label_list): New.
|
||||
|
|
|
@ -18530,7 +18530,8 @@ relax_adr (fragS *fragp, asection *sec, long stretch)
|
|||
/* Assume worst case for symbols not known to be in the same section. */
|
||||
if (fragp->fr_symbol == NULL
|
||||
|| !S_IS_DEFINED (fragp->fr_symbol)
|
||||
|| sec != S_GET_SEGMENT (fragp->fr_symbol))
|
||||
|| sec != S_GET_SEGMENT (fragp->fr_symbol)
|
||||
|| S_IS_WEAK (fragp->fr_symbol))
|
||||
return 4;
|
||||
|
||||
val = relaxed_symbol_addr (fragp, stretch);
|
||||
|
@ -18573,7 +18574,8 @@ relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
|
|||
|
||||
/* Assume worst case for symbols not known to be in the same section. */
|
||||
if (!S_IS_DEFINED (fragp->fr_symbol)
|
||||
|| sec != S_GET_SEGMENT (fragp->fr_symbol))
|
||||
|| sec != S_GET_SEGMENT (fragp->fr_symbol)
|
||||
|| S_IS_WEAK (fragp->fr_symbol))
|
||||
return 4;
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
|
@ -19784,22 +19786,23 @@ md_apply_fix (fixS * fixP,
|
|||
not have a reloc for it, so tc_gen_reloc will reject it. */
|
||||
fixP->fx_done = 1;
|
||||
|
||||
if (fixP->fx_addsy
|
||||
&& ! S_IS_DEFINED (fixP->fx_addsy))
|
||||
if (fixP->fx_addsy)
|
||||
{
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
_("undefined symbol %s used as an immediate value"),
|
||||
S_GET_NAME (fixP->fx_addsy));
|
||||
break;
|
||||
}
|
||||
const char *msg = 0;
|
||||
|
||||
if (fixP->fx_addsy
|
||||
&& S_GET_SEGMENT (fixP->fx_addsy) != seg)
|
||||
{
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
_("symbol %s is in a different section"),
|
||||
S_GET_NAME (fixP->fx_addsy));
|
||||
break;
|
||||
if (! S_IS_DEFINED (fixP->fx_addsy))
|
||||
msg = _("undefined symbol %s used as an immediate value");
|
||||
else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
|
||||
msg = _("symbol %s is in a different section");
|
||||
else if (S_IS_WEAK (fixP->fx_addsy))
|
||||
msg = _("symbol %s is weak and may be overridden later");
|
||||
|
||||
if (msg)
|
||||
{
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
msg, S_GET_NAME (fixP->fx_addsy));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
newimm = encode_arm_immediate (value);
|
||||
|
@ -19825,24 +19828,25 @@ md_apply_fix (fixS * fixP,
|
|||
unsigned int highpart = 0;
|
||||
unsigned int newinsn = 0xe1a00000; /* nop. */
|
||||
|
||||
if (fixP->fx_addsy
|
||||
&& ! S_IS_DEFINED (fixP->fx_addsy))
|
||||
if (fixP->fx_addsy)
|
||||
{
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
_("undefined symbol %s used as an immediate value"),
|
||||
S_GET_NAME (fixP->fx_addsy));
|
||||
break;
|
||||
}
|
||||
const char *msg = 0;
|
||||
|
||||
if (fixP->fx_addsy
|
||||
&& S_GET_SEGMENT (fixP->fx_addsy) != seg)
|
||||
{
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
_("symbol %s is in a different section"),
|
||||
S_GET_NAME (fixP->fx_addsy));
|
||||
break;
|
||||
}
|
||||
if (! S_IS_DEFINED (fixP->fx_addsy))
|
||||
msg = _("undefined symbol %s used as an immediate value");
|
||||
else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
|
||||
msg = _("symbol %s is in a different section");
|
||||
else if (S_IS_WEAK (fixP->fx_addsy))
|
||||
msg = _("symbol %s is weak and may be overridden later");
|
||||
|
||||
if (msg)
|
||||
{
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
msg, S_GET_NAME (fixP->fx_addsy));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
newimm = encode_arm_immediate (value);
|
||||
temp = md_chars_to_number (buf, INSN_SIZE);
|
||||
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2010-04-29 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* gas/arm/weakdef-1.s: New.
|
||||
* gas/arm/weakdef-1.d: New.
|
||||
* gas/arm/weakdef-2.s: New.
|
||||
* gas/arm/weakdef-2.d: New.
|
||||
* gas/arm/weakdef-2.l: New.
|
||||
|
||||
2010-04-27 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* gas/tic6x/align-1-be.d, gas/tic6x/align-1.d,
|
||||
|
|
20
gas/testsuite/gas/arm/weakdef-1.d
Normal file
20
gas/testsuite/gas/arm/weakdef-1.d
Normal file
|
@ -0,0 +1,20 @@
|
|||
# name: Thumb branch to weak
|
||||
# as:
|
||||
# objdump: -dr
|
||||
# This test is only valid on ELF based ports.
|
||||
#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
||||
|
||||
.*: +file format .*arm.*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+000 <Weak>:
|
||||
0: e7fe b.n 2 <Strong>
|
||||
0: R_ARM_THM_JUMP11 Strong
|
||||
|
||||
0+002 <Strong>:
|
||||
2: f7ff bffe b.w 0 <Random>
|
||||
2: R_ARM_THM_JUMP24 Random
|
||||
6: f7ff bffe b.w 0 <Weak>
|
||||
6: R_ARM_THM_JUMP24 Weak
|
18
gas/testsuite/gas/arm/weakdef-1.s
Normal file
18
gas/testsuite/gas/arm/weakdef-1.s
Normal file
|
@ -0,0 +1,18 @@
|
|||
.syntax unified
|
||||
.text
|
||||
.thumb
|
||||
|
||||
.globl Weak
|
||||
.weak Weak
|
||||
.thumb_func
|
||||
.type Weak, %function
|
||||
Weak:
|
||||
b Strong
|
||||
.size Weak, .-Weak
|
||||
|
||||
.globl Strong
|
||||
.type Strong, %function
|
||||
Strong:
|
||||
b Random
|
||||
b Weak
|
||||
.size Strong, .-Strong
|
5
gas/testsuite/gas/arm/weakdef-2.d
Normal file
5
gas/testsuite/gas/arm/weakdef-2.d
Normal file
|
@ -0,0 +1,5 @@
|
|||
# name: adr of weak
|
||||
# as:
|
||||
# error-output: weakdef-2.l
|
||||
# This test is only valid on ELF based ports.
|
||||
#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
3
gas/testsuite/gas/arm/weakdef-2.l
Normal file
3
gas/testsuite/gas/arm/weakdef-2.l
Normal file
|
@ -0,0 +1,3 @@
|
|||
[^:]*: Assembler messages:
|
||||
[^:]*:9: Error: symbol Weak is weak and may be overridden later
|
||||
[^:]*:10: Error: symbol Weak is weak and may be overridden later
|
10
gas/testsuite/gas/arm/weakdef-2.s
Normal file
10
gas/testsuite/gas/arm/weakdef-2.s
Normal file
|
@ -0,0 +1,10 @@
|
|||
.syntax unified
|
||||
.text
|
||||
.globl Strong
|
||||
Strong:
|
||||
adrl r0,Strong
|
||||
adr r0,Strong
|
||||
.globl Weak
|
||||
.weak Weak
|
||||
Weak: adrl r0,Weak
|
||||
adr r0,Weak
|
|
@ -992,7 +992,9 @@ fixup_segment (fixS *fixP, segT this_segment)
|
|||
|
||||
if (fixP->fx_addsy)
|
||||
{
|
||||
if (add_symbol_segment == this_segment
|
||||
if (S_IS_WEAK (fixP->fx_addsy))
|
||||
; // even if it is defined, it might be overridden later
|
||||
else if (add_symbol_segment == this_segment
|
||||
&& !TC_FORCE_RELOCATION_LOCAL (fixP))
|
||||
{
|
||||
/* This fixup was made when the symbol's segment was
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue