This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: hppa-linux TLS work, extra DIR32 reloc for errno@@GLIBC_PRIVATE?
On Mon, May 30, 2005 at 02:23:30PM -0400, Daniel Jacobowitz wrote:
> On Mon, May 30, 2005 at 01:50:28PM -0400, Carlos O'Donell wrote:
> > The errno duplicate is the DIR32 and appears only at the
> > finish_dynamic_relocs phase. Writing it out trashes the first two relocs
> > you see in the example.
> >
> > Where might we have gone wrong? Any clues or insight?
>
> You didn't include any patches, or a description of what changes you've
> done, so it's hard to guess. Obviously if you are corrupting
> something, your counting relocs does not match your generating relocs.
> Why are you emitting a DIR32 relocation for a TLS symbol?
I wasn't looking for any specific comments, just maybe some insight.
Thanks for the interest Daniel.
I'm trying to track down where the DIR32 relocation is created for the
TLS symbol, but I'm relatively new to binutils.
Patch attached, please ignore the debugging fuzz, and instrumentation
code. Thanks again for your input.
c.
Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.97
diff -u -p -r1.97 bfd-in.h
--- bfd/bfd-in.h 30 Mar 2005 17:19:27 -0000 1.97
+++ bfd/bfd-in.h 30 May 2005 18:26:57 -0000
@@ -24,6 +24,21 @@
#ifndef __BFD_H_SEEN__
#define __BFD_H_SEEN__
+#define __LFF __LINE__,__FILE__,__FUNCTION__
+
+#define DEBUG_BFD_L1 0x1
+#define DEBUG_BFD_L2 0x2
+#define DEBUG_BFD 0
+/*#define DEBUG_BFD (DEBUG_BFD_L1 | DEBUG_BFD_L2)*/
+
+#if DEBUG_BFD
+#define DBG(LEVEL, ...) \
+ ((LEVEL & DEBUG_BFD) \
+ ? printk(__VA_ARGS__) : (void) 0)
+#else
+#define DBG(LEVEL, ...)
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.329
diff -u -p -r1.329 bfd-in2.h
--- bfd/bfd-in2.h 30 Mar 2005 17:19:28 -0000 1.329
+++ bfd/bfd-in2.h 30 May 2005 18:26:58 -0000
@@ -31,6 +31,22 @@
#ifndef __BFD_H_SEEN__
#define __BFD_H_SEEN__
+#define __LFF __LINE__,__FILE__,__FUNCTION__
+
+#define DEBUG_BFD_L1 0x1
+#define DEBUG_BFD_L2 0x2
+#define DEBUG_BFD 0
+/*#define DEBUG_BFD (DEBUG_BFD_L1 | DEBUG_BFD_L2)*/
+
+#if DEBUG_BFD
+#define DBG(LEVEL, ...) \
+ ((LEVEL & DEBUG_BFD) \
+ ? printk(__VA_ARGS__) : (void) 0)
+#else
+#define DBG(LEVEL, ...)
+#endif
+
+
#ifdef __cplusplus
extern "C" {
#endif
Index: bfd/elf-hppa.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-hppa.h,v
retrieving revision 1.76
diff -u -p -r1.76 elf-hppa.h
--- bfd/elf-hppa.h 21 Oct 2004 15:28:20 -0000 1.76
+++ bfd/elf-hppa.h 30 May 2005 18:26:58 -0000
@@ -387,7 +387,7 @@ static reloc_howto_type elf_hppa_howto_t
bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
{ R_PARISC_TPREL32, 0, 0, 32, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_PARISC_TPREL32", FALSE, 0, 0, FALSE },
- { R_PARISC_TPREL21L, 0, 0, 21, FALSE, 0, complain_overflow_dont,
+ { R_PARISC_TPREL21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_PARISC_TPREL21L", FALSE, 0, 0, FALSE },
{ R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -395,7 +395,7 @@ static reloc_howto_type elf_hppa_howto_t
bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
{ R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
- { R_PARISC_TPREL14R, 0, 0, 14, FALSE, 0, complain_overflow_dont,
+ { R_PARISC_TPREL14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_PARISC_TPREL14R", FALSE, 0, 0, FALSE },
{ R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -413,7 +413,7 @@ static reloc_howto_type elf_hppa_howto_t
{ R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
{ R_PARISC_LTOFF_TP14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
- bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14R", FALSE, 0, 0, FALSE },
{ R_PARISC_LTOFF_TP14F, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14F", FALSE, 0, 0, FALSE },
/* 168 */
@@ -557,6 +557,31 @@ static reloc_howto_type elf_hppa_howto_t
bfd_elf_generic_reloc, "R_PARISC_GNU_VTENTRY", FALSE, 0, 0, FALSE },
{ R_PARISC_GNU_VTINHERIT, 0, 0, 0, FALSE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_PARISC_GNU_VTINHERIT", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_GD21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_GD21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_GD14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_GD14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_GDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_GDCALL", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_LDM21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_LDM21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_LDM14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_LDM14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_LDMCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_LDMCALL", FALSE, 0, 0, FALSE },
+ /* 240 */
+ { R_PARISC_TLS_LDO21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_LDO21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_LDO14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_LDO14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_DTPMOD32, 0, 0, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_DTPMOD32", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_DTPMOD64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_DTPMOD64", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_DTPOFF32, 0, 0, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_DTPOFF32", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_DTPOFF64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_DTPOFF64", FALSE, 0, 0, FALSE },
};
#define OFFSET_14R_FROM_21L 4
@@ -838,6 +863,82 @@ elf_hppa_reloc_final_type (bfd *abfd,
}
break;
+ case R_PARISC_TLS_GD21L:
+ switch (field)
+ {
+ case e_ltsel:
+ case e_lrsel:
+ final_type = R_PARISC_TLS_GD21L;
+ break;
+ case e_rtsel:
+ case e_rrsel:
+ final_type = R_PARISC_TLS_GD14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_TLS_LDM21L:
+ switch (field)
+ {
+ case e_ltsel:
+ case e_lrsel:
+ final_type = R_PARISC_TLS_LDM21L;
+ break;
+ case e_rtsel:
+ case e_rrsel:
+ final_type = R_PARISC_TLS_LDM14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_TLS_LDO21L:
+ switch (field)
+ {
+ case e_lrsel:
+ final_type = R_PARISC_TLS_LDO21L;
+ break;
+ case e_rrsel:
+ final_type = R_PARISC_TLS_LDO14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_TLS_IE21L:
+ switch (field)
+ {
+ case e_ltsel:
+ case e_lrsel:
+ final_type = R_PARISC_TLS_IE21L;
+ break;
+ case e_rtsel:
+ case e_rrsel:
+ final_type = R_PARISC_TLS_IE14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_TLS_LE21L:
+ switch (field)
+ {
+ case e_lrsel:
+ final_type = R_PARISC_TLS_LE21L;
+ break;
+ case e_rrsel:
+ final_type = R_PARISC_TLS_LE14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
case R_PARISC_GNU_VTENTRY:
case R_PARISC_GNU_VTINHERIT:
case R_PARISC_SEGREL32:
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.277
diff -u -p -r1.277 elf.c
--- bfd/elf.c 5 Apr 2005 04:01:09 -0000 1.277
+++ bfd/elf.c 30 May 2005 18:26:59 -0000
@@ -4743,7 +4743,10 @@ _bfd_elf_assign_file_positions_for_reloc
shdrp = *shdrpp;
if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA)
&& shdrp->sh_offset == -1)
- off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
+ {
+ DBG(1,"%d: %s (%s): _bfd_elf_assign_file_position_for_section off=0x%x\n",__LFF,off);
+ off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
+ }
}
elf_tdata (abfd)->next_file_pos = off;
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.127
diff -u -p -r1.127 elf32-hppa.c
--- bfd/elf32-hppa.c 7 Mar 2005 06:01:17 -0000 1.127
+++ bfd/elf32-hppa.c 30 May 2005 18:26:59 -0000
@@ -209,6 +209,10 @@ struct elf32_hppa_link_hash_entry {
#endif
} *dyn_relocs;
+ enum {
+ GOT_UNKNOWN = -1, GOT_NORMAL=1, GOT_TLS_GD, GOT_TLS_LDM, GOT_TLS_IE
+ } tls_type;
+
/* Set if this symbol is used by a plabel reloc. */
unsigned int plabel:1;
};
@@ -277,10 +281,20 @@ struct elf32_hppa_link_hash_table {
#define hppa_link_hash_table(p) \
((struct elf32_hppa_link_hash_table *) ((p)->hash))
+#define hppa_elf_hash_entry(ent) \
+ ((struct elf32_hppa_link_hash_entry *)(ent))
+
#define hppa_stub_hash_lookup(table, string, create, copy) \
((struct elf32_hppa_stub_hash_entry *) \
bfd_hash_lookup ((table), (string), (create), (copy)))
+#define hppa_elf_local_got_tls_type(abfd) \
+ ((char *)(elf_local_got_offsets (abfd) + (elf_tdata (abfd)->symtab_hdr.sh_info * 2)))
+
+static int
+elf32_hppa_optimized_tls_reloc (struct bfd_link_info *info,
+ int r_type, int is_local);
+
/* Assorted hash table functions. */
/* Initialize an entry in the stub hash table. */
@@ -348,6 +362,7 @@ hppa_link_hash_newfunc (struct bfd_hash_
eh->stub_cache = NULL;
eh->dyn_relocs = NULL;
eh->plabel = 0;
+ eh->tls_type = GOT_UNKNOWN;
}
return entry;
@@ -690,10 +705,12 @@ hppa_build_one_stub (struct bfd_hash_ent
val = hppa_field_adjust (sym_value, 0, e_lrsel);
insn = hppa_rebuild_insn ((int) LDIL_R1, val, 21);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc);
bfd_put_32 (stub_bfd, insn, loc);
val = hppa_field_adjust (sym_value, 0, e_rrsel) >> 2;
insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+4);
bfd_put_32 (stub_bfd, insn, loc + 4);
size = 8;
@@ -710,6 +727,7 @@ hppa_build_one_stub (struct bfd_hash_ent
+ stub_sec->output_offset
+ stub_sec->output_section->vma);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc);
bfd_put_32 (stub_bfd, (bfd_vma) BL_R1, loc);
val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_lrsel);
insn = hppa_rebuild_insn ((int) ADDIL_R1, val, 21);
@@ -717,6 +735,8 @@ hppa_build_one_stub (struct bfd_hash_ent
val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_rrsel) >> 2;
insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17);
+
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+8);
bfd_put_32 (stub_bfd, insn, loc + 8);
size = 12;
break;
@@ -740,6 +760,7 @@ hppa_build_one_stub (struct bfd_hash_ent
#endif
val = hppa_field_adjust (sym_value, 0, e_lrsel),
insn = hppa_rebuild_insn ((int) insn, val, 21);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc);
bfd_put_32 (stub_bfd, insn, loc);
/* It is critical to use lrsel/rrsel here because we are using
@@ -749,26 +770,37 @@ hppa_build_one_stub (struct bfd_hash_ent
between the lsel and rsel value. */
val = hppa_field_adjust (sym_value, 0, e_rrsel);
insn = hppa_rebuild_insn ((int) LDW_R1_R21, val, 14);
+
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+4);
bfd_put_32 (stub_bfd, insn, loc + 4);
if (htab->multi_subspace)
{
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rrsel);
insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14);
+
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+8);
bfd_put_32 (stub_bfd, insn, loc + 8);
+
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+12);
bfd_put_32 (stub_bfd, (bfd_vma) LDSID_R21_R1, loc + 12);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+16);
bfd_put_32 (stub_bfd, (bfd_vma) MTSP_R1, loc + 16);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+20);
bfd_put_32 (stub_bfd, (bfd_vma) BE_SR0_R21, loc + 20);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+24);
bfd_put_32 (stub_bfd, (bfd_vma) STW_RP, loc + 24);
size = 28;
}
else
{
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+8);
bfd_put_32 (stub_bfd, (bfd_vma) BV_R0_R21, loc + 8);
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rrsel);
insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+12);
bfd_put_32 (stub_bfd, insn, loc + 12);
size = 16;
@@ -806,12 +838,19 @@ hppa_build_one_stub (struct bfd_hash_ent
insn = hppa_rebuild_insn ((int) BL_RP, val, 17);
else
insn = hppa_rebuild_insn ((int) BL22_RP, val, 22);
+
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc);
bfd_put_32 (stub_bfd, insn, loc);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+4);
bfd_put_32 (stub_bfd, (bfd_vma) NOP, loc + 4);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+8);
bfd_put_32 (stub_bfd, (bfd_vma) LDW_RP, loc + 8);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+12);
bfd_put_32 (stub_bfd, (bfd_vma) LDSID_RP_R1, loc + 12);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+16);
bfd_put_32 (stub_bfd, (bfd_vma) MTSP_R1, loc + 16);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,loc+20);
bfd_put_32 (stub_bfd, (bfd_vma) BE_SR0_RP, loc + 20);
/* Point the function symbol at the stub. */
@@ -926,6 +965,9 @@ elf32_hppa_object_p (bfd *abfd)
return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20);
case EFA_PARISC_2_0 | EF_PARISC_WIDE:
return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
+ default:
+ BFD_FAIL ();
+ return FALSE;
}
return TRUE;
}
@@ -1057,6 +1099,7 @@ elf32_hppa_check_relocs (bfd *abfd,
struct elf32_hppa_link_hash_table *htab;
asection *sreloc;
asection *stubreloc;
+ int tls_type, old_tls_type = GOT_UNKNOWN;
if (info->relocatable)
return TRUE;
@@ -1079,18 +1122,26 @@ elf32_hppa_check_relocs (bfd *abfd,
unsigned int r_symndx, r_type;
struct elf32_hppa_link_hash_entry *h;
- int need_entry;
+ int need_entry = 0;
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx < symtab_hdr->sh_info)
- h = NULL;
+ {
+ h = NULL;
+ DBG(1,"%d: %s (%s): h=%p\n",__LFF, h);
+ }
else
- h = ((struct elf32_hppa_link_hash_entry *)
- sym_hashes[r_symndx - symtab_hdr->sh_info]);
+ {
+ h = ((struct elf32_hppa_link_hash_entry *)
+ sym_hashes[r_symndx - symtab_hdr->sh_info]);
+ DBG(1,"%d: %s (%s): h=%p sym %s\n",__LFF, h, h->elf.root.root.string);
+ }
r_type = ELF32_R_TYPE (rel->r_info);
+ r_type = elf32_hppa_optimized_tls_reloc (info, r_type, h == NULL);
+
switch (r_type)
{
case R_PARISC_DLTIND14F:
@@ -1100,10 +1151,15 @@ elf32_hppa_check_relocs (bfd *abfd,
need_entry = NEED_GOT;
break;
+ case R_PARISC_PLABEL32:
+ DBG(1,"%d: %s (%s): PLABEL32\n",__LFF);
+
case R_PARISC_PLABEL14R: /* "Official" procedure labels. */
case R_PARISC_PLABEL21L:
- case R_PARISC_PLABEL32:
+ /*case R_PARISC_PLABEL32:*/
/* If the addend is non-zero, we break badly. */
+
+
if (rel->r_addend != 0)
abort ();
@@ -1211,13 +1267,55 @@ elf32_hppa_check_relocs (bfd *abfd,
return FALSE;
continue;
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDM14R:
+ need_entry = NEED_GOT;
+ break;
+
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_IE14R:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ need_entry = NEED_GOT;
+ break;
+
default:
+ DBG(1,"%d: %s (%s): Unhandled relocation = 0x%x\n",__LFF, r_type);
continue;
}
/* Now carry out our orders. */
if (need_entry & NEED_GOT)
{
+ switch (r_type)
+ {
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_GD14R:
+ tls_type = GOT_TLS_GD;
+ break;
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDM14R:
+ tls_type = GOT_TLS_LDM;
+ break;
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_IE14R:
+ tls_type = GOT_TLS_IE;
+// if (h) printf("h=%p sym %s tls_type = TLS_IE\n", h, h->elf.root.root.string);
+ break;
+ case R_PARISC_DLTIND14F:
+ case R_PARISC_DLTIND14R:
+ case R_PARISC_DLTIND21L:
+ tls_type = GOT_NORMAL;
+ break;
+ default:
+ DBG(1,"%d: %s (%s): Unhandled relocation = 0x%x (GOT_NORMAL?)\n",__LFF, r_type);
+ tls_type = GOT_UNKNOWN;
+ break;
+
+ }
+
/* Allocate space for a GOT entry, as well as a dynamic
relocation for this entry. */
if (htab->sgot == NULL)
@@ -1231,6 +1329,9 @@ elf32_hppa_check_relocs (bfd *abfd,
if (h != NULL)
{
h->elf.got.refcount += 1;
+ old_tls_type = hppa_elf_hash_entry (h)->tls_type;
+ if (old_tls_type == 0)
+ abort();
}
else
{
@@ -1248,12 +1349,45 @@ elf32_hppa_check_relocs (bfd *abfd,
pointer. */
size = symtab_hdr->sh_info;
size *= 2 * sizeof (bfd_signed_vma);
+ /* Add in space to store the local GOT TLS types. */
+ size += symtab_hdr->sh_info;
local_got_refcounts = bfd_zalloc (abfd, size);
if (local_got_refcounts == NULL)
return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
+ memset (hppa_elf_local_got_tls_type (abfd),
+ GOT_UNKNOWN, symtab_hdr->sh_info);
}
local_got_refcounts[r_symndx] += 1;
+
+ old_tls_type = hppa_elf_local_got_tls_type (abfd) [r_symndx];
+ if (old_tls_type == 0)
+ abort();
+ }
+
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
+ && (old_tls_type != GOT_TLS_GD || tls_type != GOT_TLS_IE))
+ {
+ if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
+ tls_type = GOT_TLS_IE;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and thread local symbol"),
+ abfd, h ? h->elf.root.root.string : "<local>");
+ return FALSE;
+ }
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL) {
+ hppa_elf_hash_entry (h)->tls_type = tls_type;
+// if (h) printf("sym %s refcount %d assigning tls_type = %d\n", h->elf.root.root.string, h->elf.got.refcount, tls_type);
+ } else
+ hppa_elf_local_got_tls_type (abfd) [r_symndx] = tls_type;
}
}
@@ -1294,6 +1428,8 @@ elf32_hppa_check_relocs (bfd *abfd,
plt offsets. */
size = symtab_hdr->sh_info;
size *= 2 * sizeof (bfd_signed_vma);
+ /* Add in space to store the local GOT TLS types. */
+ size += symtab_hdr->sh_info;
local_got_refcounts = bfd_zalloc (abfd, size);
if (local_got_refcounts == NULL)
return FALSE;
@@ -1470,6 +1606,7 @@ elf32_hppa_gc_mark_hook (asection *sec,
break;
default:
+ DBG(1,"%d: %s (%s): Handle cleanup?",__LFF);
switch (h->root.type)
{
case bfd_link_hash_defined:
@@ -1480,6 +1617,7 @@ elf32_hppa_gc_mark_hook (asection *sec,
return h->root.u.c.p->section;
default:
+ DBG(1,"%d: %s (%s): Unhandled section in cleanup? h->root.type = 0x%x",__LFF,h->root.type);
break;
}
}
@@ -1518,7 +1656,7 @@ elf32_hppa_gc_sweep_hook (bfd *abfd,
for (rel = relocs; rel < relend; rel++)
{
unsigned long r_symndx;
- unsigned int r_type;
+ unsigned int r_type, r_type_optimized;
struct elf_link_hash_entry *h = NULL;
r_symndx = ELF32_R_SYM (rel->r_info);
@@ -1544,11 +1682,18 @@ elf32_hppa_gc_sweep_hook (bfd *abfd,
}
r_type = ELF32_R_TYPE (rel->r_info);
- switch (r_type)
+ r_type_optimized = elf32_hppa_optimized_tls_reloc (info, r_type, h != NULL);
+ switch (r_type_optimized)
{
case R_PARISC_DLTIND14F:
case R_PARISC_DLTIND14R:
case R_PARISC_DLTIND21L:
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDM14R:
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_IE14R:
if (h != NULL)
{
if (h->got.refcount > 0)
@@ -1572,9 +1717,14 @@ elf32_hppa_gc_sweep_hook (bfd *abfd,
}
break;
+ case R_PARISC_PLABEL32:
+ DBG(1,"%d: %s (%s): PLABEL32\n",__LFF);
+
case R_PARISC_PLABEL14R:
case R_PARISC_PLABEL21L:
- case R_PARISC_PLABEL32:
+ /*case R_PARISC_PLABEL32:*/
+
+
if (h != NULL)
{
if (h->plt.refcount > 0)
@@ -1588,6 +1738,7 @@ elf32_hppa_gc_sweep_hook (bfd *abfd,
break;
default:
+ DBG(1,"%d: %s (%s): Unhandled relocation = 0x%x (r_type_optimized?)\n",__LFF, r_type);
break;
}
}
@@ -1831,6 +1982,7 @@ allocate_plt_static (struct elf_link_has
{
struct bfd_link_info *info;
struct elf32_hppa_link_hash_table *htab;
+ struct elf32_hppa_link_hash_entry *eh;
asection *s;
if (h->root.type == bfd_link_hash_indirect)
@@ -1840,6 +1992,7 @@ allocate_plt_static (struct elf_link_has
h = (struct elf_link_hash_entry *) h->root.u.i.link;
info = inf;
+ eh = (struct elf32_hppa_link_hash_entry *) h;
htab = hppa_link_hash_table (info);
if (htab->elf.dynamic_sections_created
&& h->plt.refcount > 0)
@@ -1906,9 +2059,10 @@ allocate_dynrelocs (struct elf_link_hash
info = inf;
htab = hppa_link_hash_table (info);
+ eh = hppa_elf_hash_entry (h);
if (htab->elf.dynamic_sections_created
&& h->plt.offset != (bfd_vma) -1
- && !((struct elf32_hppa_link_hash_entry *) h)->plabel)
+ && !eh->plabel)
{
/* Make an entry in the .plt section. */
s = htab->splt;
@@ -1934,19 +2088,25 @@ allocate_dynrelocs (struct elf_link_hash
s = htab->sgot;
h->got.offset = s->size;
+//printf("h=%p assigning got offset for sym %s at 0x%x tls_type %d\n", h, h->root.root.string, h->got.offset, hppa_elf_hash_entry (h)->tls_type);
s->size += GOT_ENTRY_SIZE;
+ /* R_PARISC_TLS_GD* and R_PARISC_TLS_LDM* needs two GOT entries */
+ if (eh->tls_type == GOT_TLS_GD || eh->tls_type == GOT_TLS_LDM)
+ s->size += GOT_ENTRY_SIZE;
if (htab->elf.dynamic_sections_created
&& (info->shared
|| (h->dynindx != -1
&& !h->forced_local)))
{
htab->srelgot->size += sizeof (Elf32_External_Rela);
+ if (eh->tls_type == GOT_TLS_GD
+ || eh->tls_type == GOT_TLS_LDM)
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
}
}
else
h->got.offset = (bfd_vma) -1;
- eh = (struct elf32_hppa_link_hash_entry *) h;
if (eh->dyn_relocs == NULL)
return TRUE;
@@ -2122,6 +2282,7 @@ elf32_hppa_size_dynamic_sections (bfd *o
bfd_size_type locsymcount;
Elf_Internal_Shdr *symtab_hdr;
asection *srel;
+ char *local_tls_type;
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
continue;
@@ -2160,6 +2321,7 @@ elf32_hppa_size_dynamic_sections (bfd *o
symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
locsymcount = symtab_hdr->sh_info;
end_local_got = local_got + locsymcount;
+ local_tls_type = hppa_elf_local_got_tls_type (ibfd);
s = htab->sgot;
srel = htab->srelgot;
for (; local_got < end_local_got; ++local_got)
@@ -2168,11 +2330,20 @@ elf32_hppa_size_dynamic_sections (bfd *o
{
*local_got = s->size;
s->size += GOT_ENTRY_SIZE;
- if (info->shared)
- srel->size += sizeof (Elf32_External_Rela);
+ if (*local_tls_type == GOT_TLS_GD
+ || *local_tls_type == GOT_TLS_LDM)
+ s->size += GOT_ENTRY_SIZE;
+ if (info->shared) {
+ srel->size += sizeof (Elf32_External_Rela);
+ if (*local_tls_type == GOT_TLS_GD
+ || *local_tls_type == GOT_TLS_LDM)
+ srel->size += sizeof (Elf32_External_Rela);
+ }
}
else
*local_got = (bfd_vma) -1;
+
+ ++local_tls_type;
}
local_plt = end_local_got;
@@ -3044,6 +3215,35 @@ elf32_hppa_build_stubs (struct bfd_link_
return TRUE;
}
+/* Return the base vma address which should be subtracted from the real
+ address when resolving a dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for R_PARISC_TLS_TPOFF*.. */
+
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ /* hppa TLS ABI is variant I and static TLS block start just after
+ tcbhead structure which has 2 pointer fields. */
+ return (address - htab->tls_sec->vma
+ + align_power ((bfd_vma) 8, htab->tls_sec->alignment_power));
+}
+
/* Perform a final link. */
static bfd_boolean
@@ -3113,6 +3313,12 @@ final_link_relocate (asection *input_sec
struct elf32_hppa_stub_hash_entry *stub_entry = NULL;
int val;
+
+ if(h != NULL)
+ DBG(1,"%d: %s (%s): Enter h=%p sym %s\n",__LFF, h, h->elf.root.root.string);
+ else
+ DBG(1,"%d: %s (%s): Enter h=%p\n",__LFF, h);
+
if (r_type == R_PARISC_NONE)
return bfd_reloc_ok;
@@ -3140,6 +3346,25 @@ final_link_relocate (asection *input_sec
case R_PARISC_DLTIND14F:
r_type = R_PARISC_DPREL14F;
break;
+
+ /* Other unconverted non-shared relocs */
+ case R_PARISC_DIR32:
+ case R_PARISC_DIR21L:
+ case R_PARISC_DIR14R:
+ case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL32:
+ case R_PARISC_DPREL21L:
+ case R_PARISC_DPREL14R:
+ case R_PARISC_SEGREL32:
+ case R_PARISC_PLABEL32:
+ case R_PARISC_PLABEL21L:
+ case R_PARISC_PLABEL14R:
+ DBG(1,"%d: %s (%s): Skipping r_type = 0x%x\n",__LFF, r_type);
+ break;
+
+ default:
+ DBG(1,"%d: %s (%s): Unhandled static relocation = 0x%x\n",__LFF, r_type);
+ break;
}
}
@@ -3255,6 +3480,12 @@ final_link_relocate (asection *input_sec
case R_PARISC_DLTIND21L:
case R_PARISC_DLTIND14R:
case R_PARISC_DLTIND14F:
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDM14R:
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_IE14R:
value -= elf_gp (input_section->output_section->owner);
break;
@@ -3265,12 +3496,26 @@ final_link_relocate (asection *input_sec
value -= htab->data_segment_base;
break;
+ /* Skipping these relocs */
+ case R_PARISC_DIR32:
+ case R_PARISC_DIR21L:
+ case R_PARISC_DIR14R:
+ case R_PARISC_PLABEL21L:
+ case R_PARISC_PLABEL14R:
+ case R_PARISC_PLABEL32:
+ DBG(1,"%d: %s (%s): Skipping r_type = 0x%x\n",__LFF, r_type);
+ break;
+
default:
+ DBG(1,"%d: %s (%s): Unhandled relocation = 0x%x\n",__LFF,r_type);
break;
}
switch (r_type)
{
+
+ case R_PARISC_PLABEL32:
+ DBG(1,"%d: %s (%s): PLABEL32\n",__LFF);
case R_PARISC_DIR32:
case R_PARISC_DIR14F:
case R_PARISC_DIR17F:
@@ -3278,10 +3523,13 @@ final_link_relocate (asection *input_sec
case R_PARISC_PCREL14F:
case R_PARISC_PCREL32:
case R_PARISC_DPREL14F:
- case R_PARISC_PLABEL32:
+ /*case R_PARISC_PLABEL32:*/
case R_PARISC_DLTIND14F:
case R_PARISC_SEGBASE:
case R_PARISC_SEGREL32:
+ case R_PARISC_TLS_DTPMOD32:
+ case R_PARISC_TLS_DTPOFF32:
+ case R_PARISC_TLS_TPREL32:
r_field = e_fsel;
break;
@@ -3293,6 +3541,11 @@ final_link_relocate (asection *input_sec
case R_PARISC_DIR21L:
case R_PARISC_DPREL21L:
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDO21L:
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_LE21L:
r_field = e_lrsel;
break;
@@ -3306,6 +3559,11 @@ final_link_relocate (asection *input_sec
case R_PARISC_DIR17R:
case R_PARISC_DIR14R:
case R_PARISC_DPREL14R:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_LDM14R:
+ case R_PARISC_TLS_LDO14R:
+ case R_PARISC_TLS_IE14R:
+ case R_PARISC_TLS_LE14R:
r_field = e_rrsel;
break;
@@ -3354,6 +3612,7 @@ final_link_relocate (asection *input_sec
/* Something we don't know how to handle. */
default:
+ DBG(1,"%d: %s (%s): Unhandled relocation = 0x%x\n",__LFF, r_type);
return bfd_reloc_notsupported;
}
@@ -3389,17 +3648,42 @@ final_link_relocate (asection *input_sec
val >>= 2;
break;
+ /* Skipping */
+ case R_PARISC_DIR32:
+ case R_PARISC_DIR21L:
+ case R_PARISC_DIR14R:
+ case R_PARISC_PCREL32:
+ case R_PARISC_DPREL21L:
+ case R_PARISC_DPREL14R:
+ case R_PARISC_SEGREL32:
+ case R_PARISC_PLABEL21L:
+ case R_PARISC_PLABEL14R:
+ case R_PARISC_PLABEL32:
+ DBG(1,"%d: %s (%s): Skipping r_type = 0x%x\n",__LFF, r_type);
+ break;
+
default:
+ DBG(1,"%d: %s (%s): Unhandled relocation = 0x%x\n",__LFF, r_type);
break;
}
insn = hppa_rebuild_insn (insn, val, r_format);
/* Update the instruction word. */
+
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,hit_data);
bfd_put_32 (input_bfd, (bfd_vma) insn, hit_data);
return bfd_reloc_ok;
}
+static int
+elf32_hppa_optimized_tls_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ int r_type, int is_local ATTRIBUTE_UNUSED)
+{
+ /* For now we don't support linker optimizations. */
+ return r_type;
+}
+
/* Relocate an HPPA ELF section. */
static bfd_boolean
@@ -3464,6 +3748,8 @@ elf32_hppa_relocate_section (bfd *output
sym = local_syms + r_symndx;
sym_sec = local_sections[r_symndx];
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sym_sec, rel);
+ DBG(1,"%d: %s (%s): h=%p, r_info=0x%x, r_offset=0x%x\n",
+ __LFF, h, rel->r_info, rel->r_offset);
}
else
{
@@ -3492,7 +3778,9 @@ elf32_hppa_relocate_section (bfd *output
warned_undef = TRUE;
}
}
- h = (struct elf32_hppa_link_hash_entry *) hh;
+ h = hppa_elf_hash_entry (hh);
+ DBG(1,"%d: %s (%s): h=%p sym %s, r_info=0x%x, r_offset=0x%x\n",
+ __LFF, h, h->elf.root.root.string, rel->r_info, rel->r_offset);
}
/* Do any required modifications to the relocation value, and
@@ -3529,6 +3817,7 @@ elf32_hppa_relocate_section (bfd *output
off &= ~1;
else
{
+//printf("DLTIND reloc against %s\n", h->elf.root.root.string);
h->elf.got.offset |= 1;
do_got = 1;
}
@@ -3572,11 +3861,19 @@ elf32_hppa_relocate_section (bfd *output
outrel.r_addend = relocation;
loc = s->contents;
loc += s->reloc_count++ * sizeof (Elf32_External_Rela);
+
+ DBG(1,"%d: %s (%s): bfd_elf32_swap_reloca_out (DIR32) outrel "
+ "r_info=0x%x, r_offset=0x%x, r_addend=0x%x, loc=0x%x\n",
+ __LFF, outrel.r_info, outrel.r_offset,
+ outrel.r_addend, loc);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
else
- bfd_put_32 (output_bfd, relocation,
+ {
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,htab->sgot->contents + off);
+ bfd_put_32 (output_bfd, relocation,
htab->sgot->contents + off);
+ }
}
if (off >= (bfd_vma) -2)
@@ -3596,11 +3893,17 @@ elf32_hppa_relocate_section (bfd *output
bfd_map_over_sections (output_bfd, hppa_record_segment_addr, htab);
break;
+
+ case R_PARISC_PLABEL32:
+ DBG(1,"%d: %s (%s): PLABEL32\n",__LFF);
case R_PARISC_PLABEL14R:
case R_PARISC_PLABEL21L:
- case R_PARISC_PLABEL32:
+ /*case R_PARISC_PLABEL32:*/
if (htab->elf.dynamic_sections_created)
{
+
+ DBG(1,"%d: %s (%s): PLABEL relocs and dynamic_sections_created.\n", __LFF);
+
bfd_vma off;
bfd_boolean do_plt = 0;
@@ -3663,13 +3966,18 @@ elf32_hppa_relocate_section (bfd *output
outrel.r_addend = relocation;
loc = s->contents;
loc += s->reloc_count++ * sizeof (Elf32_External_Rela);
+ DBG(1,"%d: %s (%s): bfd_elf32_swap_reloca_out (IPLT), "
+ "r_info = 0x%x, r_addend = 0x%x, r_offset = 0x%x, loc = 0x%x\n",
+ __LFF, outrel.r_info, outrel.r_addend, outrel.r_offset, loc);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
else
{
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,htab->splt->contents + off);
bfd_put_32 (output_bfd,
relocation,
htab->splt->contents + off);
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,htab->splt->contents + off + 4);
bfd_put_32 (output_bfd,
elf_gp (htab->splt->output_section->owner),
htab->splt->contents + off + 4);
@@ -3697,6 +4005,7 @@ elf32_hppa_relocate_section (bfd *output
plabel = 1;
}
/* Fall through and possibly emit a dynamic relocation. */
+ DBG(1,"%d: %s (%s): PLABEL falling through to DIR and DPREL relocs.\n", __LFF);
case R_PARISC_DIR17F:
case R_PARISC_DIR17R:
@@ -3813,11 +4122,208 @@ elf32_hppa_relocate_section (bfd *output
loc = sreloc->contents;
loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ DBG(1,"%d: %s (%s): bfd_elf32_swap_reloca_out (???) outrel "
+ "r_info=0x%x, r_offset=0x%x, r_addend=0x%x, loc=0x%x\n",
+ __LFF, outrel.r_info, outrel.r_offset, outrel.r_addend, loc);
+
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
break;
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDM14R:
+ if (htab->elf.dynamic_sections_created)
+ {
+ bfd_vma off;
+ bfd_boolean do_got = 0;
+
+ /* Relocation is to the entry for this symbol in the
+ global offset table. */
+ if (h != NULL)
+ {
+ off = h->elf.got.offset;
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+//printf("TLSGD/LD reloc against %s\n", h->elf.root.root.string);
+ h->elf.got.offset |= 1;
+ do_got = 1;
+ }
+ }
+ else
+ {
+ /* Local symbol case. */
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+
+ /* The offset must always be a multiple of 4. We use
+ the least significant bit to record whether we have
+ already generated the necessary reloc. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ local_got_offsets[r_symndx] |= 1;
+ do_got = 1;
+ }
+ }
+
+ if (do_got)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ asection *s = htab->srelgot;
+ int indx;
+
+ if (h == NULL || h->elf.dynindx == -1)
+ indx = 0;
+ else
+ indx = h->elf.dynindx;
+
+ outrel.r_offset = (off
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+
+
+ if (r_type == R_PARISC_TLS_GD21L
+ || r_type == R_PARISC_TLS_GD14R) {
+ outrel.r_info = ELF32_R_INFO (0, R_PARISC_TLS_DTPMOD32);
+ outrel.r_addend = 0;
+
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ DBG(1,"%d: %s (%s): bfd_elf32_swap_reloca_out (Output DTPMOD32), "
+ "r_info = 0x%x, r_addend = 0x%x, r_offset = 0x%x, loc = 0x%x\n",
+ __LFF, outrel.r_info, outrel.r_addend, outrel.r_offset, loc);
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ outrel.r_offset += 4;
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, R_PARISC_TLS_DTPOFF32);
+ outrel.r_addend = 0;
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ DBG(1,"%d: %s (%s): bfd_elf32_swap_reloca_out (Output DTPOFF32), "
+ "r_info = 0x%x, r_addend = 0x%x, r_offset = 0x%x, loc = 0x%x\n",
+ __LFF, outrel.r_info, outrel.r_addend, outrel.r_offset, loc);
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ /* Add the base of the GOT to the relocation value. */
+ relocation = (off
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+ }
+ break;
+
+ case R_PARISC_TLS_LDO21L:
+ case R_PARISC_TLS_LDO14R:
+ if (! info->shared)
+ relocation = tpoff (info, relocation);
+ else
+ relocation -= dtpoff_base (info);
+ break;
+
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_IE14R:
+ if (htab->elf.dynamic_sections_created)
+ {
+ bfd_vma off;
+ bfd_boolean do_got = 0;
+
+ if (h != NULL)
+ {
+ off = h->elf.got.offset;
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+//printf("TLSIE reloc against %s\n", h->elf.root.root.string);
+ h->elf.got.offset |= 1;
+ do_got = 1;
+ }
+ }
+ else
+ {
+ /* Local symbol case. */
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+
+ /* The offset must always be a multiple of 4. We use
+ the least significant bit to record whether we have
+ already generated the necessary reloc. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ local_got_offsets[r_symndx] |= 1;
+ do_got = 1;
+ }
+ }
+
+ if (do_got)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ asection *s = htab->srelgot;
+ int indx;
+
+ indx = h && h->elf.dynindx != -1 ? h->elf.dynindx : 0;
+
+ outrel.r_offset = (off
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+ outrel.r_info = ELF32_R_INFO (indx, R_PARISC_TLS_TPREL32);
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ DBG(1,"%d: %s (%s): bfd_elf32_swap_reloca_out (TPREL32), "
+ "r_info = 0x%x, r_addend = 0x%x, r_offset = 0x%x, loc = 0x%x\n",
+ __LFF, outrel.r_info, outrel.r_addend, outrel.r_offset, loc);
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ /* Add the base of the GOT to the relocation value. */
+ relocation = (off
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+ }
+ break;
+
+ case R_PARISC_TLS_LE21L:
+ case R_PARISC_TLS_LE14R:
+ {
+ relocation = tpoff (info, relocation);
+ break;
+ }
+ break;
+
+ /* Skipping this */
+ case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL32:
+ DBG(1,"%d: %s (%s): Skipping r_type = 0x%x\n",__LFF, r_type);
+ break;
+
default:
+ DBG(1,"%d: %s (%s): Unhandled relocation = 0x%x\n",__LFF, r_type);
break;
}
@@ -3884,6 +4390,9 @@ elf32_hppa_finish_dynamic_symbol (bfd *o
htab = hppa_link_hash_table (info);
+ DBG(1,"%d: %s (%s): sym %s got.offset 0x%x tls_type %d\n",
+ __LFF,h->root.root.string, h->got.offset, hppa_elf_hash_entry (h)->tls_type);
+
if (h->plt.offset != (bfd_vma) -1)
{
bfd_vma value;
@@ -3927,6 +4436,11 @@ elf32_hppa_finish_dynamic_symbol (bfd *o
loc = htab->srelplt->contents;
loc += htab->srelplt->reloc_count++ * sizeof (Elf32_External_Rela);
+ DBG(1,"%d: %s (%s): bfd_elf32_swap_reloca_out (IPLT) outrel "
+ "r_info=0x%x, r_offset=0x%x, r_addend=0x%x, loc=0x%x\n",
+ __LFF, rel.r_info, rel.r_offset,
+ rel.r_addend, loc);
+
bfd_elf32_swap_reloca_out (htab->splt->output_section->owner, &rel, loc);
if (!h->def_regular)
@@ -3937,7 +4451,9 @@ elf32_hppa_finish_dynamic_symbol (bfd *o
}
}
- if (h->got.offset != (bfd_vma) -1)
+ if (h->got.offset != (bfd_vma) -1
+ && hppa_elf_hash_entry (h)->tls_type != GOT_TLS_GD
+ && hppa_elf_hash_entry (h)->tls_type != GOT_TLS_IE)
{
/* This symbol has an entry in the global offset table. Set it
up. */
@@ -3962,15 +4478,25 @@ elf32_hppa_finish_dynamic_symbol (bfd *o
}
else
{
+ /*
if ((h->got.offset & 1) != 0)
abort ();
- bfd_put_32 (output_bfd, 0, htab->sgot->contents + h->got.offset);
+ */
+
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,htab->sgot->contents + (h->got.offset & ~1));
+ bfd_put_32 (output_bfd, 0, htab->sgot->contents + (h->got.offset & ~1));
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_DIR32);
rel.r_addend = 0;
}
loc = htab->srelgot->contents;
loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ DBG(1,"%d: %s (%s): bfd_elf32_swap_reloca_out (DIR32) outrel "
+ "r_info=0x%x, r_offset=0x%x, r_addend=0x%x, loc=0x%x\n",
+ __LFF, rel.r_info, rel.r_offset,
+ rel.r_addend, loc);
+
+
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
}
@@ -3993,6 +4519,12 @@ elf32_hppa_finish_dynamic_symbol (bfd *o
rel.r_addend = 0;
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_COPY);
loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ DBG(1,"%d: %s (%s): bfd_elf32_swap_reloca_out (COPY) outrel "
+ "r_info=0x%x, r_offset=0x%x, r_addend=0x%x, loc=0x%x\n",
+ __LFF, rel.r_info, rel.r_offset,
+ rel.r_addend, loc);
+
+
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
}
@@ -4013,6 +4545,19 @@ elf32_hppa_finish_dynamic_symbol (bfd *o
static enum elf_reloc_type_class
elf32_hppa_reloc_type_class (const Elf_Internal_Rela *rela)
{
+ /* Handle TLS relocs first; we don't want them to be marked
+ relative by the "if (ELF32_R_SYM (rela->r_info) == 0)"
+ check below. */
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_PARISC_TLS_DTPMOD32:
+ case R_PARISC_TLS_DTPOFF32:
+ case R_PARISC_TLS_TPREL32:
+ return reloc_class_normal;
+ default:
+ break;
+ }
+
if (ELF32_R_SYM (rela->r_info) == 0)
return reloc_class_relative;
@@ -4061,6 +4606,7 @@ elf32_hppa_finish_dynamic_sections (bfd
switch (dyn.d_tag)
{
default:
+ DBG(1,"%d: %s (%s): Unhandled dyanmic entry = 0x%x\n",__LFF,dyn.d_tag);
continue;
case DT_PLTGOT:
@@ -4108,6 +4654,8 @@ elf32_hppa_finish_dynamic_sections (bfd
{
/* Fill in the first entry in the global offset table.
We use it to point to our dynamic section, if we have one. */
+
+ DBG(1,"%d: %s (%s): bfd_put_32 loc=0x%x\n",__LFF,htab->sgot->contents);
bfd_put_32 (output_bfd,
sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0,
htab->sgot->contents);
Index: bfd/elfcode.h
===================================================================
RCS file: /cvs/src/src/bfd/elfcode.h,v
retrieving revision 1.64
diff -u -p -r1.64 elfcode.h
--- bfd/elfcode.h 20 Feb 2005 14:59:07 -0000 1.64
+++ bfd/elfcode.h 30 May 2005 18:26:59 -0000
@@ -71,6 +71,8 @@ Foundation, Inc., 59 Temple Place - Suit
#include "libbfd.h"
#include "elf-bfd.h"
+#define __LFF __LINE__,__FILE__,__FUNCTION__
+
/* Renaming structures, typedefs, macros and functions to be size-specific. */
#define Elf_External_Ehdr NAME(Elf,External_Ehdr)
#define Elf_External_Sym NAME(Elf,External_Sym)
@@ -884,6 +886,13 @@ elf_write_relocs (bfd *abfd, asection *s
src_rela.r_offset = ptr->address + addr_offset;
src_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
src_rela.r_addend = ptr->addend;
+ DBG(1,"%d: %s (%s): *swap_out "
+ "src_rela.r_offset=0x%x, "
+ "src_rela.r_info=0x%x, "
+ "src_rela.r_addend=0x%x, "
+ "dst_rela=0x%x\n",
+ __LFF, src_rela.r_offset, src_rela.r_info, src_rela.r_addend,
+ dst_rela);
(*swap_out) (abfd, &src_rela, dst_rela);
}
}
Index: gas/config/tc-hppa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-hppa.c,v
retrieving revision 1.115
diff -u -p -r1.115 tc-hppa.c
--- gas/config/tc-hppa.c 3 Mar 2005 11:47:50 -0000 1.115
+++ gas/config/tc-hppa.c 30 May 2005 18:27:00 -0000
@@ -1210,6 +1210,26 @@ static struct default_space_dict pa_def_
((exp).X_op == O_subtract \
&& strcmp (S_GET_NAME ((exp).X_op_symbol), "$PIC_pcrel$0") == 0)
+#define is_tls_gdidx(exp) \
+ ((exp).X_op == O_subtract \
+ && strcmp (S_GET_NAME ((exp).X_op_symbol), "$tls_gdidx$") == 0)
+
+#define is_tls_ldidx(exp) \
+ ((exp).X_op == O_subtract \
+ && strcmp (S_GET_NAME ((exp).X_op_symbol), "$tls_ldidx$") == 0)
+
+#define is_tls_dtpoff(exp) \
+ ((exp).X_op == O_subtract \
+ && strcmp (S_GET_NAME ((exp).X_op_symbol), "$tls_dtpoff$") == 0)
+
+#define is_tls_ieoff(exp) \
+ ((exp).X_op == O_subtract \
+ && strcmp (S_GET_NAME ((exp).X_op_symbol), "$tls_ieoff$") == 0)
+
+#define is_tls_leoff(exp) \
+ ((exp).X_op == O_subtract \
+ && strcmp (S_GET_NAME ((exp).X_op_symbol), "$tls_leoff$") == 0)
+
/* We need some complex handling for stabs (sym1 - sym2). Luckily, we'll
always be able to reduce the expression to a constant, so we don't
need real complex handling yet. */
@@ -1371,7 +1391,12 @@ fix_new_hppa (frag, where, size, add_sym
it now so as not to confuse write.c. Ditto for $PIC_pcrel$0. */
if (new_fix->fx_subsy
&& (strcmp (S_GET_NAME (new_fix->fx_subsy), "$global$") == 0
- || strcmp (S_GET_NAME (new_fix->fx_subsy), "$PIC_pcrel$0") == 0))
+ || strcmp (S_GET_NAME (new_fix->fx_subsy), "$PIC_pcrel$0") == 0
+ || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_gdidx$") == 0
+ || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_ldidx$") == 0
+ || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_dtpoff$") == 0
+ || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_ieoff$") == 0
+ || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_leoff$") == 0))
new_fix->fx_subsy = NULL;
}
@@ -1403,6 +1428,18 @@ cons_fix_new_hppa (frag, where, size, ex
rel_type = R_HPPA_GOTOFF;
else if (is_PC_relative (*exp))
rel_type = R_HPPA_PCREL_CALL;
+#ifdef OBJ_ELF
+ else if (is_tls_gdidx (*exp))
+ rel_type = R_PARISC_TLS_GD21L;
+ else if (is_tls_ldidx (*exp))
+ rel_type = R_PARISC_TLS_LDM21L;
+ else if (is_tls_dtpoff (*exp))
+ rel_type = R_PARISC_TLS_LDO21L;
+ else if (is_tls_ieoff (*exp))
+ rel_type = R_PARISC_TLS_IE21L;
+ else if (is_tls_leoff (*exp))
+ rel_type = R_PARISC_TLS_LE21L;
+#endif
else if (is_complex (*exp))
rel_type = R_HPPA_COMPLEX;
else
@@ -2979,6 +3016,18 @@ pa_ip (str)
the_insn.reloc = R_HPPA_GOTOFF;
else if (is_PC_relative (the_insn.exp))
the_insn.reloc = R_HPPA_PCREL_CALL;
+#ifdef OBJ_ELF
+ else if (is_tls_gdidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_GD21L;
+ else if (is_tls_ldidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDM21L;
+ else if (is_tls_dtpoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDO21L;
+ else if (is_tls_ieoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_IE21L;
+ else if (is_tls_leoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LE21L;
+#endif
else
the_insn.reloc = R_HPPA;
the_insn.format = 11;
@@ -3096,6 +3145,18 @@ pa_ip (str)
the_insn.reloc = R_HPPA_GOTOFF;
else if (is_PC_relative (the_insn.exp))
the_insn.reloc = R_HPPA_PCREL_CALL;
+#ifdef OBJ_ELF
+ else if (is_tls_gdidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_GD21L;
+ else if (is_tls_ldidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDM21L;
+ else if (is_tls_dtpoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDO21L;
+ else if (is_tls_ieoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_IE21L;
+ else if (is_tls_leoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LE21L;
+#endif
else
the_insn.reloc = R_HPPA;
the_insn.format = 14;
@@ -3126,6 +3187,18 @@ pa_ip (str)
the_insn.reloc = R_HPPA_GOTOFF;
else if (is_PC_relative (the_insn.exp))
the_insn.reloc = R_HPPA_PCREL_CALL;
+#ifdef OBJ_ELF
+ else if (is_tls_gdidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_GD21L;
+ else if (is_tls_ldidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDM21L;
+ else if (is_tls_dtpoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDO21L;
+ else if (is_tls_ieoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_IE21L;
+ else if (is_tls_leoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LE21L;
+#endif
else
the_insn.reloc = R_HPPA;
the_insn.format = 14;
@@ -3150,6 +3223,18 @@ pa_ip (str)
the_insn.reloc = R_HPPA_GOTOFF;
else if (is_PC_relative (the_insn.exp))
the_insn.reloc = R_HPPA_PCREL_CALL;
+#ifdef OBJ_ELF
+ else if (is_tls_gdidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_GD21L;
+ else if (is_tls_ldidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDM21L;
+ else if (is_tls_dtpoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDO21L;
+ else if (is_tls_ieoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_IE21L;
+ else if (is_tls_leoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LE21L;
+#endif
else
the_insn.reloc = R_HPPA;
the_insn.format = 14;
@@ -3174,6 +3259,18 @@ pa_ip (str)
the_insn.reloc = R_HPPA_GOTOFF;
else if (is_PC_relative (the_insn.exp))
the_insn.reloc = R_HPPA_PCREL_CALL;
+#ifdef OBJ_ELF
+ else if (is_tls_gdidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_GD21L;
+ else if (is_tls_ldidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDM21L;
+ else if (is_tls_dtpoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDO21L;
+ else if (is_tls_ieoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_IE21L;
+ else if (is_tls_leoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LE21L;
+#endif
else
the_insn.reloc = R_HPPA;
the_insn.format = 21;
@@ -3199,6 +3296,18 @@ pa_ip (str)
the_insn.reloc = R_HPPA_GOTOFF;
else if (is_PC_relative (the_insn.exp))
the_insn.reloc = R_HPPA_PCREL_CALL;
+#ifdef OBJ_ELF
+ else if (is_tls_gdidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_GD21L;
+ else if (is_tls_ldidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDM21L;
+ else if (is_tls_dtpoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDO21L;
+ else if (is_tls_ieoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_IE21L;
+ else if (is_tls_leoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LE21L;
+#endif
else
the_insn.reloc = R_HPPA;
the_insn.format = 14;
@@ -3225,6 +3334,18 @@ pa_ip (str)
the_insn.reloc = R_HPPA_GOTOFF;
else if (is_PC_relative (the_insn.exp))
the_insn.reloc = R_HPPA_PCREL_CALL;
+#ifdef OBJ_ELF
+ else if (is_tls_gdidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_GD21L;
+ else if (is_tls_ldidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDM21L;
+ else if (is_tls_dtpoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDO21L;
+ else if (is_tls_ieoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_IE21L;
+ else if (is_tls_leoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LE21L;
+#endif
else
the_insn.reloc = R_HPPA;
the_insn.format = 14;
@@ -3251,6 +3372,18 @@ pa_ip (str)
the_insn.reloc = R_HPPA_GOTOFF;
else if (is_PC_relative (the_insn.exp))
the_insn.reloc = R_HPPA_PCREL_CALL;
+#ifdef OBJ_ELF
+ else if (is_tls_gdidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_GD21L;
+ else if (is_tls_ldidx (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDM21L;
+ else if (is_tls_dtpoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LDO21L;
+ else if (is_tls_ieoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_IE21L;
+ else if (is_tls_leoff (the_insn.exp))
+ the_insn.reloc = R_PARISC_TLS_LE21L;
+#endif
else
the_insn.reloc = R_HPPA;
the_insn.format = 14;
@@ -4643,6 +4776,25 @@ md_apply_fix3 (fixP, valP, seg)
return;
}
+#ifdef OBJ_ELF
+ switch (fixP->fx_r_type)
+ {
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDM14R:
+ case R_PARISC_TLS_LE21L:
+ case R_PARISC_TLS_LE14R:
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_IE14R:
+ if (fixP->fx_addsy)
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
+ default:
+ break;
+ }
+#endif
+
/* Insert the relocation. */
bfd_put_32 (stdoutput, insn, buf);
}
Index: gas/config/tc-hppa.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-hppa.h,v
retrieving revision 1.27
diff -u -p -r1.27 tc-hppa.h
--- gas/config/tc-hppa.h 19 Feb 2005 08:56:08 -0000 1.27
+++ gas/config/tc-hppa.h 30 May 2005 18:27:00 -0000
@@ -179,7 +179,12 @@ int hppa_fix_adjustable PARAMS((struct f
|| (S_GET_SEGMENT (sym) == &bfd_abs_section \
&& ! S_IS_EXTERNAL (sym)) \
|| strcmp (S_GET_NAME (sym), "$global$") == 0 \
- || strcmp (S_GET_NAME (sym), "$PIC_pcrel$0") == 0) \
+ || strcmp (S_GET_NAME (sym), "$PIC_pcrel$0") == 0 \
+ || strcmp (S_GET_NAME (sym), "$tls_gdidx$") == 0 \
+ || strcmp (S_GET_NAME (sym), "$tls_ldidx$") == 0 \
+ || strcmp (S_GET_NAME (sym), "$tls_dtpoff$") == 0 \
+ || strcmp (S_GET_NAME (sym), "$tls_ieoff$") == 0 \
+ || strcmp (S_GET_NAME (sym), "$tls_leoff$") == 0) \
punt = 1; \
}
Index: include/elf/hppa.h
===================================================================
RCS file: /cvs/src/src/include/elf/hppa.h,v
retrieving revision 1.15
diff -u -p -r1.15 hppa.h
--- include/elf/hppa.h 14 Mar 2001 02:27:44 -0000 1.15
+++ include/elf/hppa.h 30 May 2005 18:27:01 -0000
@@ -481,8 +481,28 @@ RELOC_NUMBER (R_PARISC_LTOFF_TP16DF, 2
RELOC_NUMBER (R_PARISC_GNU_VTENTRY, 232)
RELOC_NUMBER (R_PARISC_GNU_VTINHERIT, 233)
+RELOC_NUMBER (R_PARISC_TLS_GD21L, 234)
+RELOC_NUMBER (R_PARISC_TLS_GD14R, 235)
+RELOC_NUMBER (R_PARISC_TLS_GDCALL, 236)
+RELOC_NUMBER (R_PARISC_TLS_LDM21L, 237)
+RELOC_NUMBER (R_PARISC_TLS_LDM14R, 238)
+RELOC_NUMBER (R_PARISC_TLS_LDMCALL, 239)
+RELOC_NUMBER (R_PARISC_TLS_LDO21L, 240)
+RELOC_NUMBER (R_PARISC_TLS_LDO14R, 241)
+RELOC_NUMBER (R_PARISC_TLS_DTPMOD32, 242)
+RELOC_NUMBER (R_PARISC_TLS_DTPMOD64, 243)
+RELOC_NUMBER (R_PARISC_TLS_DTPOFF32, 244)
+RELOC_NUMBER (R_PARISC_TLS_DTPOFF64, 245)
+
END_RELOC_NUMBERS (R_PARISC_UNIMPLEMENTED)
+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64
+
#ifndef RELOC_MACROS_GEN_FUNC
typedef enum elf_hppa_reloc_type elf_hppa_reloc_type;
#endif
Index: ld/ldwrite.c
===================================================================
RCS file: /cvs/src/src/ld/ldwrite.c,v
retrieving revision 1.19
diff -u -p -r1.19 ldwrite.c
--- ld/ldwrite.c 22 Feb 2005 13:00:25 -0000 1.19
+++ ld/ldwrite.c 30 May 2005 18:27:01 -0000
@@ -110,16 +110,19 @@ build_link_order (lang_statement_union_t
case SQUAD:
if (sizeof (bfd_vma) >= QUAD_SIZE)
{
+ DBG(1,"%d: %s (%s): bfd_putl64 value=0x%x, buffer=0x%x\n",__LFF,value,buffer);
bfd_putl64 (value, buffer);
value = bfd_getb64 (buffer);
break;
}
/* Fall through. */
case LONG:
+ DBG(1,"%d: %s (%s): bfd_putl32 value=0x%x, buffer=0x%x\n",__LFF,value,buffer);
bfd_putl32 (value, buffer);
value = bfd_getb32 (buffer);
break;
case SHORT:
+ DBG(1,"%d: %s (%s): bfd_putl16 value=0x%x, buffer=0x%x\n",__LFF,value,buffer);
bfd_putl16 (value, buffer);
value = bfd_getb16 (buffer);
break;
@@ -137,7 +140,11 @@ build_link_order (lang_statement_union_t
case QUAD:
case SQUAD:
if (sizeof (bfd_vma) >= QUAD_SIZE)
- bfd_put_64 (output_bfd, value, link_order->u.data.contents);
+ {
+
+ DBG(1,"%d: %s (%s): bfd_put_64 value=0x%x, buffer=0x%x\n",__LFF,value,link_order->u.data.contents);
+ bfd_put_64 (output_bfd, value, link_order->u.data.contents);
+ }
else
{
bfd_vma high;
@@ -148,9 +155,12 @@ build_link_order (lang_statement_union_t
high = 0;
else
high = (bfd_vma) -1;
+ DBG(1,"%d: %s (%s): bfd_put_32 value=0x%x, buffer=0x%x\n",__LFF,value,link_order->u.data.contents+(big_endian ? 0:4));
bfd_put_32 (output_bfd, high,
(link_order->u.data.contents
+ (big_endian ? 0 : 4)));
+
+ DBG(1,"%d: %s (%s): bfd_put_32 value=0x%x, buffer=0x%x\n",__LFF,value,link_order->u.data.contents+(big_endian ? 4:0));
bfd_put_32 (output_bfd, value,
(link_order->u.data.contents
+ (big_endian ? 4 : 0)));
@@ -158,14 +168,17 @@ build_link_order (lang_statement_union_t
link_order->size = QUAD_SIZE;
break;
case LONG:
+ DBG(1,"%d: %s (%s): bfd_put_32 value=0x%x, buffer=0x%x\n",__LFF,value,link_order->u.data.contents);
bfd_put_32 (output_bfd, value, link_order->u.data.contents);
link_order->size = LONG_SIZE;
break;
case SHORT:
+ DBG(1,"%d: %s (%s): bfd_put_16 value=0x%x, buffer=0x%x\n",__LFF,value,link_order->u.data.contents);
bfd_put_16 (output_bfd, value, link_order->u.data.contents);
link_order->size = SHORT_SIZE;
break;
case BYTE:
+ DBG(1,"%d: %s (%s): bfd_put_8 value=0x%x, buffer=0x%x\n",__LFF,value,link_order->u.data.contents);
bfd_put_8 (output_bfd, value, link_order->u.data.contents);
link_order->size = BYTE_SIZE;
break;
@@ -543,6 +556,7 @@ split_sections (bfd *abfd, struct bfd_li
void
ldwrite (void)
{
+ DBG(1,"%d: %s (%s): Enter\n",__LFF);
/* Reset error indicator, which can typically something like invalid
format from opening up the .o files. */
bfd_set_error (bfd_error_no_error);
@@ -562,4 +576,5 @@ ldwrite (void)
else
xexit (1);
}
+ DBG(1,"%d: %s (%s): Return\n",__LFF);
}