* 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>
|
2010-04-27 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* config/tc-tic6x.h (tic6x_label_list): New.
|
* 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. */
|
/* Assume worst case for symbols not known to be in the same section. */
|
||||||
if (fragp->fr_symbol == NULL
|
if (fragp->fr_symbol == NULL
|
||||||
|| !S_IS_DEFINED (fragp->fr_symbol)
|
|| !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;
|
return 4;
|
||||||
|
|
||||||
val = relaxed_symbol_addr (fragp, stretch);
|
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. */
|
/* Assume worst case for symbols not known to be in the same section. */
|
||||||
if (!S_IS_DEFINED (fragp->fr_symbol)
|
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;
|
return 4;
|
||||||
|
|
||||||
#ifdef OBJ_ELF
|
#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. */
|
not have a reloc for it, so tc_gen_reloc will reject it. */
|
||||||
fixP->fx_done = 1;
|
fixP->fx_done = 1;
|
||||||
|
|
||||||
if (fixP->fx_addsy
|
if (fixP->fx_addsy)
|
||||||
&& ! S_IS_DEFINED (fixP->fx_addsy))
|
|
||||||
{
|
{
|
||||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
const char *msg = 0;
|
||||||
_("undefined symbol %s used as an immediate value"),
|
|
||||||
S_GET_NAME (fixP->fx_addsy));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fixP->fx_addsy
|
if (! S_IS_DEFINED (fixP->fx_addsy))
|
||||||
&& S_GET_SEGMENT (fixP->fx_addsy) != seg)
|
msg = _("undefined symbol %s used as an immediate value");
|
||||||
{
|
else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
|
||||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
msg = _("symbol %s is in a different section");
|
||||||
_("symbol %s is in a different section"),
|
else if (S_IS_WEAK (fixP->fx_addsy))
|
||||||
S_GET_NAME (fixP->fx_addsy));
|
msg = _("symbol %s is weak and may be overridden later");
|
||||||
break;
|
|
||||||
|
if (msg)
|
||||||
|
{
|
||||||
|
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||||
|
msg, S_GET_NAME (fixP->fx_addsy));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newimm = encode_arm_immediate (value);
|
newimm = encode_arm_immediate (value);
|
||||||
|
@ -19825,24 +19828,25 @@ md_apply_fix (fixS * fixP,
|
||||||
unsigned int highpart = 0;
|
unsigned int highpart = 0;
|
||||||
unsigned int newinsn = 0xe1a00000; /* nop. */
|
unsigned int newinsn = 0xe1a00000; /* nop. */
|
||||||
|
|
||||||
if (fixP->fx_addsy
|
if (fixP->fx_addsy)
|
||||||
&& ! S_IS_DEFINED (fixP->fx_addsy))
|
|
||||||
{
|
{
|
||||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
const char *msg = 0;
|
||||||
_("undefined symbol %s used as an immediate value"),
|
|
||||||
S_GET_NAME (fixP->fx_addsy));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fixP->fx_addsy
|
if (! S_IS_DEFINED (fixP->fx_addsy))
|
||||||
&& S_GET_SEGMENT (fixP->fx_addsy) != seg)
|
msg = _("undefined symbol %s used as an immediate value");
|
||||||
{
|
else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
|
||||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
msg = _("symbol %s is in a different section");
|
||||||
_("symbol %s is in a different section"),
|
else if (S_IS_WEAK (fixP->fx_addsy))
|
||||||
S_GET_NAME (fixP->fx_addsy));
|
msg = _("symbol %s is weak and may be overridden later");
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (msg)
|
||||||
|
{
|
||||||
|
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||||
|
msg, S_GET_NAME (fixP->fx_addsy));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newimm = encode_arm_immediate (value);
|
newimm = encode_arm_immediate (value);
|
||||||
temp = md_chars_to_number (buf, INSN_SIZE);
|
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>
|
2010-04-27 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* gas/tic6x/align-1-be.d, gas/tic6x/align-1.d,
|
* 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 (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))
|
&& !TC_FORCE_RELOCATION_LOCAL (fixP))
|
||||||
{
|
{
|
||||||
/* This fixup was made when the symbol's segment was
|
/* This fixup was made when the symbol's segment was
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue