This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[Xtensa] fix overly conservative handling symbol differences
- From: Bob Wilson <bwilson at tensilica dot com>
- To: binutils at sources dot redhat dot com
- Date: Fri, 18 Jan 2008 11:13:13 -0800
- Subject: [Xtensa] fix overly conservative handling symbol differences
Sterling Augustine's change to GAS from 2007-11-01 disabled linker relaxation of
Xtensa code referenced in difference of symbol expressions. This was really
only needed for expressions used in sleb128 and uleb128 values, but at the time
it seemed to be OK to handle all expression symbols. My subsequent DWARF change
from 2008-01-09 causes more difference of symbol expressions for Xtensa, and we
end up with very conservative linker relaxation whenever DWARF line info is
generated.
I'm committing this patch to fix the problem. It limits the previous change to
only apply in the context of uleb128 and sleb128 values. I ran the testsuite
for an xtensa-elf target to verify it.
2008-01-18 Bob Wilson <bob.wilson@acm.org>
* config/tc-xtensa.c (xtensa_leb128): New function.
(md_pseudo_table): Use it for sleb128 and uleb128.
(is_leb128_expr): New internal flag.
(xtensa_symbol_new_hook): Check new flag.
Index: config/tc-xtensa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-xtensa.c,v
retrieving revision 1.96
diff -u -p -r1.96 tc-xtensa.c
--- config/tc-xtensa.c 20 Dec 2007 17:21:07 -0000 1.96
+++ config/tc-xtensa.c 18 Jan 2008 17:21:58 -0000
@@ -1,5 +1,5 @@
/* tc-xtensa.c -- Assemble Xtensa instructions.
- Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -442,6 +442,7 @@ static void xtensa_literal_position (int
static void xtensa_literal_pseudo (int);
static void xtensa_frequency_pseudo (int);
static void xtensa_elf_cons (int);
+static void xtensa_leb128 (int);
/* Parsing and Idiom Translation. */
@@ -1004,6 +1005,8 @@ const pseudo_typeS md_pseudo_table[] =
{ "4byte", xtensa_elf_cons, 4 },
{ "short", xtensa_elf_cons, 2 },
{ "2byte", xtensa_elf_cons, 2 },
+ { "sleb128", xtensa_leb128, 1},
+ { "uleb128", xtensa_leb128, 0},
{ "begin", xtensa_begin_directive, 0 },
{ "end", xtensa_end_directive, 0 },
{ "literal", xtensa_literal_pseudo, 0 },
@@ -1569,6 +1572,16 @@ xtensa_elf_cons (int nbytes)
demand_empty_rest_of_line ();
}
+static bfd_boolean is_leb128_expr;
+
+static void
+xtensa_leb128 (int sign)
+{
+ is_leb128_expr = TRUE;
+ s_leb128 (sign);
+ is_leb128_expr = FALSE;
+}
+
/* Parsing and Idiom Translation. */
@@ -5635,7 +5648,7 @@ symbolS *expr_symbols = NULL;
void
xtensa_symbol_new_hook (symbolS *sym)
{
- if (S_GET_SEGMENT (sym) == expr_section)
+ if (is_leb128_expr && S_GET_SEGMENT (sym) == expr_section)
{
symbol_get_tc (sym)->next_expr_symbol = expr_symbols;
expr_symbols = sym;
@@ -7256,10 +7269,11 @@ xtensa_mark_zcl_first_insns (void)
}
-/* Some difference-of-symbols expressions make it out to the linker. Some
- don't. If one does, then the linker can optimize between the two labels.
- If it doesn't, then the linker shouldn't. */
-
+/* When a difference-of-symbols expression is encoded as a uleb128 or
+ sleb128 value, the linker is unable to adjust that value to account for
+ link-time relaxation. Mark all the code between such symbols so that
+ its size cannot be changed by linker relaxation. */
+
static void
xtensa_mark_difference_of_two_symbols (void)
{