aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-mn10300.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2008-02-18 10:03:06 +0000
committerNick Clifton <nickc@redhat.com>2008-02-18 10:03:06 +0000
commitca75ed2d8fd6fd97f7536ceb9fb0f3e2b99f6211 (patch)
treecb16519c553697e753392e3f3988acee3cb03561 /gas/config/tc-mn10300.c
parent192dc9c6fdb23ca962c3be3053dda8753dc0b065 (diff)
downloadgdb-ca75ed2d8fd6fd97f7536ceb9fb0f3e2b99f6211.zip
gdb-ca75ed2d8fd6fd97f7536ceb9fb0f3e2b99f6211.tar.gz
gdb-ca75ed2d8fd6fd97f7536ceb9fb0f3e2b99f6211.tar.bz2
* config/tc-mn10300.c (has_known_symbol_location): New function.
Do not regard weak symbols as having a known location. (md_estimate_size_before_relax): Use new function. (md_pcrel_from): Do not compute a pcrel against a weak symbol.
Diffstat (limited to 'gas/config/tc-mn10300.c')
-rw-r--r--gas/config/tc-mn10300.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c
index 5d21cb5..5068904 100644
--- a/gas/config/tc-mn10300.c
+++ b/gas/config/tc-mn10300.c
@@ -675,6 +675,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
else if (fragP->fr_subtype == 6)
{
int offset = fragP->fr_fix;
+
fragP->fr_literal[offset] = 0xcd;
fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
@@ -684,6 +685,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
else if (fragP->fr_subtype == 7)
{
int offset = fragP->fr_fix;
+
fragP->fr_literal[offset] = 0xdd;
fragP->fr_literal[offset + 5] = fragP->fr_literal[offset + 3];
fragP->fr_literal[offset + 6] = fragP->fr_literal[offset + 4];
@@ -696,6 +698,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
else if (fragP->fr_subtype == 8)
{
int offset = fragP->fr_fix;
+
fragP->fr_literal[offset] = 0xfa;
fragP->fr_literal[offset + 1] = 0xff;
fix_new (fragP, fragP->fr_fix + 2, 2, fragP->fr_symbol,
@@ -706,6 +709,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
else if (fragP->fr_subtype == 9)
{
int offset = fragP->fr_fix;
+
fragP->fr_literal[offset] = 0xfc;
fragP->fr_literal[offset + 1] = 0xff;
@@ -725,6 +729,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
else if (fragP->fr_subtype == 11)
{
int offset = fragP->fr_fix;
+
fragP->fr_literal[offset] = 0xcc;
fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
@@ -735,6 +740,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
else if (fragP->fr_subtype == 12)
{
int offset = fragP->fr_fix;
+
fragP->fr_literal[offset] = 0xdc;
fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
@@ -2262,24 +2268,36 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
return relocs;
}
+/* Returns true iff the symbol attached to the frag is at a known location
+ in the given section, (and hence the relocation to it can be relaxed by
+ the assembler). */
+static inline bfd_boolean
+has_known_symbol_location (fragS * fragp, asection * sec)
+{
+ symbolS * sym = fragp->fr_symbol;
+
+ return sym != NULL
+ && S_IS_DEFINED (sym)
+ && ! S_IS_WEAK (sym)
+ && S_GET_SEGMENT (sym) == sec;
+}
+
int
md_estimate_size_before_relax (fragS *fragp, asection *seg)
{
if (fragp->fr_subtype == 6
- && (!S_IS_DEFINED (fragp->fr_symbol)
- || seg != S_GET_SEGMENT (fragp->fr_symbol)))
+ && ! has_known_symbol_location (fragp, seg))
fragp->fr_subtype = 7;
else if (fragp->fr_subtype == 8
- && (!S_IS_DEFINED (fragp->fr_symbol)
- || seg != S_GET_SEGMENT (fragp->fr_symbol)))
+ && ! has_known_symbol_location (fragp, seg))
fragp->fr_subtype = 9;
else if (fragp->fr_subtype == 10
- && (!S_IS_DEFINED (fragp->fr_symbol)
- || seg != S_GET_SEGMENT (fragp->fr_symbol)))
+ && ! has_known_symbol_location (fragp, seg))
fragp->fr_subtype = 12;
if (fragp->fr_subtype == 13)
return 3;
+
if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
abort ();
@@ -2289,11 +2307,11 @@ md_estimate_size_before_relax (fragS *fragp, asection *seg)
long
md_pcrel_from (fixS *fixp)
{
- if (fixp->fx_addsy != NULL && !S_IS_DEFINED (fixp->fx_addsy))
- {
- /* The symbol is undefined. Let the linker figure it out. */
- return 0;
- }
+ if (fixp->fx_addsy != (symbolS *) NULL
+ && (!S_IS_DEFINED (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)))
+ /* The symbol is undefined or weak. Let the linker figure it out. */
+ return 0;
+
return fixp->fx_frag->fr_address + fixp->fx_where;
}