* 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:
Nick Clifton 2010-04-29 14:44:15 +00:00
parent c0643a5132
commit 77db8e2e96
9 changed files with 110 additions and 32 deletions

View file

@ -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.

View file

@ -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);

View file

@ -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,

View 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

View 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

View 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*

View 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

View 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

View file

@ -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