aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/tc-hppa.c32
2 files changed, 35 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index b9269cf..459697b 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+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.
+
2009-10-29 Sebastian Pop <sebastian.pop@amd.com>
* config/tc-i386.c (build_modrm_byte): Do not swap REG and
diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c
index 371f9f0..8823db2 100644
--- a/gas/config/tc-hppa.c
+++ b/gas/config/tc-hppa.c
@@ -5961,13 +5961,41 @@ pa_build_unwind_subspace (struct call_info *call_info)
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_info *call_info)
/* 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);