aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog12
-rw-r--r--gas/config/tc-mn10300.c58
-rw-r--r--gas/config/tc-mn10300.h4
-rw-r--r--gas/testsuite/ChangeLog4
-rw-r--r--gas/testsuite/gas/all/gas.exp7
5 files changed, 69 insertions, 16 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index a8295a2..867ff02 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,17 @@
2007-10-30 Nick Clifton <nickc@redhat.com>
+ * config/tc-mn10300.c (tc_gen_reloc): Fix test that decides when
+ sym_diff relocs should be generated.
+ (md_apply_fix): Skip R_MN10300_ALIGN relocs.
+ (mn10300_fix_adjustable): Do not adjust R_MN10300_ALIGN relocs.
+ (mn10300_handle_align): New function. Generate R_MN10300_ALIGN
+ relocs to record alignment requests.
+ * config/tc-mn10300.h (TC_FORCE_RELOCATION_SUB_SAME): Also force
+ R_MN10300_ALIGN relocs.
+ (HANDLE_ALIGN): Define. Call mn10300_handle_align.
+
+2007-10-30 Nick Clifton <nickc@redhat.com>
+
* doc/as.texinfo (Section): Replace "subsegment" with
"subsection".
diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c
index 5ec58bb..e16a764 100644
--- a/gas/config/tc-mn10300.c
+++ b/gas/config/tc-mn10300.c
@@ -2181,13 +2181,18 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
if (fixp->fx_addsy && fixp->fx_subsy)
{
+ asection *asec, *ssec;
+
+ asec = S_GET_SEGMENT (fixp->fx_addsy);
+ ssec = S_GET_SEGMENT (fixp->fx_subsy);
+
reloc->sym_ptr_ptr = NULL;
/* If we have a difference between two (non-absolute) symbols we must
generate two relocs (one for each symbol) and allow the linker to
resolve them - relaxation may change the distances between symbols,
- even local symbols defined in the same segment. */
- if (S_GET_SEGMENT (fixp->fx_subsy) == seg)
+ even local symbols defined in the same section. */
+ if (ssec != absolute_section || asec != absolute_section)
{
arelent * reloc2 = xmalloc (sizeof * reloc);
@@ -2201,7 +2206,7 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
*reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
reloc->addend = fixp->fx_offset;
- if (S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
+ if (asec == absolute_section)
reloc->addend += S_GET_VALUE (fixp->fx_addsy);
reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
@@ -2211,13 +2216,6 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
fixp->fx_done = 1;
return relocs;
}
-
- if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
- || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
- {
- as_bad_where (fixp->fx_file, fixp->fx_line,
- "Difference of symbols in different sections is not supported");
- }
else
{
char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
@@ -2248,12 +2246,12 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
= (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
return relocs;
}
- }
- if (reloc->sym_ptr_ptr)
- free (reloc->sym_ptr_ptr);
- free (reloc);
- return & no_relocs;
+ if (reloc->sym_ptr_ptr)
+ free (reloc->sym_ptr_ptr);
+ free (reloc);
+ return & no_relocs;
+ }
}
else
{
@@ -2357,6 +2355,10 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
fixP->fx_done = 0;
return;
+ case BFD_RELOC_MN10300_ALIGN:
+ fixP->fx_done = 1;
+ return;
+
case BFD_RELOC_NONE:
default:
as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -2562,3 +2564,29 @@ mn10300_allow_local_subtract (expressionS * left, expressionS * right, segT sect
return result;
}
+
+/* When relaxing, we need to output a reloc for any .align directive
+ that requests alignment to a two byte boundary or larger. */
+
+void
+mn10300_handle_align (fragS *frag)
+{
+ if (! linkrelax)
+ return;
+
+ if ((frag->fr_type == rs_align
+ || frag->fr_type == rs_align_code)
+ && frag->fr_address + frag->fr_fix > 0
+ && frag->fr_offset > 1
+ && now_seg != bss_section
+ /* Do not create relocs for the merging sections - such
+ relocs will prevent the contents from being merged. */
+ && (bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE) == 0)
+ /* Create a new fixup to record the alignment request. The symbol is
+ irrelevent but must be present so we use the absolute section symbol.
+ The offset from the symbol is used to record the power-of-two alignment
+ value. The size is set to 0 because the frag may already be aligned,
+ thus causing cvt_frag_to_fill to reduce the size of the frag to zero. */
+ fix_new (frag, frag->fr_fix, 0, & abs_symbol, frag->fr_offset, FALSE,
+ BFD_RELOC_MN10300_ALIGN);
+}
diff --git a/gas/config/tc-mn10300.h b/gas/config/tc-mn10300.h
index af7a6e6..8a2e457 100644
--- a/gas/config/tc-mn10300.h
+++ b/gas/config/tc-mn10300.h
@@ -66,6 +66,7 @@ void mn10300_cons_fix_new PARAMS ((fragS *, int, int, expressionS *));
#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC) \
(((SEC)->flags & SEC_CODE) != 0 \
|| ! SEG_NORMAL (SEC) \
+ || (FIX)->fx_r_type == BFD_RELOC_MN10300_ALIGN \
|| TC_FORCE_RELOCATION (FIX))
/* We validate subtract arguments within tc_gen_reloc(), so don't
@@ -116,3 +117,6 @@ extern bfd_boolean mn10300_allow_local_subtract (expressionS *, expressionS *, s
#define MAX_RELOC_EXPANSION 2
#define TC_FRAG_TYPE bfd_boolean
+
+#define HANDLE_ALIGN(frag) mn10300_handle_align (frag)
+extern void mn10300_handle_align (fragS *);
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 8616469..8e2a12d 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2007-10-30 Nick Clifton <nickc@redhat.com>
+
+ * gas/all/gas.exp: Do not run diff1.s test for mn10300.
+
2007-10-27 H.J. Lu <hongjiu.lu@intel.com>
PR gas/5221
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 119eeb0..0a3135a 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -34,7 +34,12 @@ if { ![istarget cris-*-*] && ![istarget crisv32-*-*]
# This test is meaningless for the PA; the difference of two undefined
# symbols is something that is (and must be) supported on the PA.
-if ![istarget hppa*-*-*] then {
+#
+# The MN10300 port supports link time relaxation which in turn allows
+# for link time resolution of the differneces of two symbols which are
+# undefined at assembly time. Hence this test will not pass for the
+# MN10300.
+if { ![istarget hppa*-*-*] && ![istarget mn10300-*-*] && ![istarget am3*-*-*] } then {
gas_test_error "diff1.s" "" "difference of two undefined symbols"
}