This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[committed] Fix parisc unwind start offset
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: binutils at sourceware dot org
- Date: Fri, 30 Oct 2009 13:19:48 -0400 (EDT)
- Subject: [committed] Fix parisc unwind start offset
This patch fixes a problem with incorrect ranges in the parisc unwind
data. When the function symbol is used as the start offset in the unwind
entry, there is a problem with starting offset for weak/overloaded functions.
The fix is to replace the function symbol with a local symbol which reduces
to a section offset.
The problem was noticed in the linux kernel. The patch was tested on
hppa-unknown-linux-gnu. Committed to trunk.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
2009-10-30 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* config/tc-hppa.c (pa_build_unwind_subspace): Replace start symbol
with local symbol.
Index: config/tc-hppa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-hppa.c,v
retrieving revision 1.145
diff -u -3 -p -r1.145 tc-hppa.c
--- config/tc-hppa.c 24 Jul 2009 11:45:00 -0000 1.145
+++ config/tc-hppa.c 29 Oct 2009 18:37:39 -0000
@@ -5961,13 +5961,41 @@ pa_build_unwind_subspace (struct call_in
subsegT save_subseg;
unsigned int unwind;
int reloc;
- char *p;
+ char *name, *p;
+ symbolS *symbolP;
if ((bfd_get_section_flags (stdoutput, now_seg)
& (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
!= (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
return;
+ /* Replace the start symbol with a local symbol that will be reduced
+ to a section offset. This avoids problems with weak functions with
+ multiple definitions, etc. */
+ name = xmalloc (strlen ("L$\001start_")
+ + strlen (S_GET_NAME (call_info->start_symbol))
+ + 1);
+ strcpy (name, "L$\001start_");
+ strcat (name, S_GET_NAME (call_info->start_symbol));
+
+ /* If we have a .procend preceded by a .exit, then the symbol will have
+ already been defined. In that case, we don't want another unwind
+ entry. */
+ symbolP = symbol_find (name);
+ if (symbolP)
+ {
+ xfree (name);
+ return;
+ }
+ else
+ {
+ symbolP = symbol_new (name, now_seg,
+ S_GET_VALUE (call_info->start_symbol), frag_now);
+ gas_assert (symbolP);
+ S_CLEAR_EXTERNAL (symbolP);
+ symbol_table_insert (symbolP);
+ }
+
reloc = R_PARISC_SEGREL32;
save_seg = now_seg;
save_subseg = now_subseg;
@@ -5993,7 +6021,7 @@ pa_build_unwind_subspace (struct call_in
/* Relocation info. for start offset of the function. */
md_number_to_chars (p, 0, 4);
fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
- call_info->start_symbol, (offsetT) 0,
+ symbolP, (offsetT) 0,
(expressionS *) NULL, 0, reloc,
e_fsel, 32, 0, 0);