This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
fix missing Xtensa literal table entries
- From: Bob Wilson <bwilson at tensilica dot com>
- To: binutils at sources dot redhat dot com
- Date: Fri, 19 Mar 2004 14:43:33 -0800
- Subject: fix missing Xtensa literal table entries
- Organization: Tensilica, Inc.
Xtensa ELF files contain a special ".xt.lit" section to record the position of
literals. The literals for the .init and .fini sections, which are placed in
.init.literal and .fini.literal respectively, were not being included in the
table. This problem was discovered because one effect of this bug is that the
DT_TEXTREL flag is incorrectly set for glibc. (There's also a serious design
problem with setting DT_TEXTREL for Xtensa; more on that later....)
I've tested the patch by running the GAS testsuite with an xtensa-linux-gnu
target and by building glibc and booting a board with it. Committed on the
mainline and 2.15 branch.
2004-03-19 Bob Wilson <bob.wilson@acm.org>
* config/tc-xtensa.c (mark_literal_frags): New function.
(xtensa_move_literals): Call mark_literal_frags for all literal
segments, including init and fini literal segments.
(xtensa_post_relax_hook): Swap use of xt_insn_sec and xt_literal_sec.
Index: config/tc-xtensa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-xtensa.c,v
retrieving revision 1.7
diff -u -p -r1.7 tc-xtensa.c
--- config/tc-xtensa.c 19 Nov 2003 23:55:06 -0000 1.7
+++ config/tc-xtensa.c 19 Mar 2004 17:46:57 -0000
@@ -638,6 +638,8 @@ static void xtensa_move_seg_list_to_begi
PARAMS ((seg_list *));
static void xtensa_move_literals
PARAMS ((void));
+static void mark_literal_frags
+ PARAMS ((seg_list *));
static void xtensa_reorder_seg_list
PARAMS ((seg_list *, segT));
static void xtensa_reorder_segments
@@ -7485,21 +7487,9 @@ xtensa_move_literals ()
fixS *fix, *next_fix, **fix_splice;
sym_list *lit;
- /* As clunky as this is, we can't rely on frag_var
- and frag_variant to get called in all situations. */
-
- segment = literal_head->next;
- while (segment)
- {
- frchain_from = seg_info (segment->seg)->frchainP;
- search_frag = frchain_from->frch_root;
- while (search_frag)
- {
- search_frag->tc_frag_data.is_literal = TRUE;
- search_frag = search_frag->fr_next;
- }
- segment = segment->next;
- }
+ mark_literal_frags (literal_head->next);
+ mark_literal_frags (init_literal_head->next);
+ mark_literal_frags (fini_literal_head->next);
if (use_literal_section)
return;
@@ -7603,6 +7593,31 @@ xtensa_move_literals ()
}
+/* Walk over all the frags for segments in a list and mark them as
+ containing literals. As clunky as this is, we can't rely on frag_var
+ and frag_variant to get called in all situations. */
+
+static void
+mark_literal_frags (segment)
+ seg_list *segment;
+{
+ frchainS *frchain_from;
+ fragS *search_frag;
+
+ while (segment)
+ {
+ frchain_from = seg_info (segment->seg)->frchainP;
+ search_frag = frchain_from->frch_root;
+ while (search_frag)
+ {
+ search_frag->tc_frag_data.is_literal = TRUE;
+ search_frag = search_frag->fr_next;
+ }
+ segment = segment->next;
+ }
+}
+
+
static void
xtensa_reorder_seg_list (head, after)
seg_list *head;
@@ -7872,11 +7887,11 @@ xtensa_post_relax_hook ()
xtensa_create_property_segments (get_frag_is_insn,
XTENSA_INSN_SEC_NAME,
- xt_literal_sec);
+ xt_insn_sec);
if (use_literal_section)
xtensa_create_property_segments (get_frag_is_literal,
XTENSA_LIT_SEC_NAME,
- xt_insn_sec);
+ xt_literal_sec);
}