mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-28 23:39:35 +08:00
hppa-linux TLS relocs
This patch fixes various problems with TLS relocations. 1) Report an error if a symbol has both TLS and normal GOT entries. 2) The GOT entry size calculation was obscure and made use of the fact that a symbol shouldn't have both normal and TLS GOT entries. 3) The second word of a GD GOT entry sometimes omitted a dynamic reloc, which was fine except that doing so makes it impossible for ld.so to differentiate GD and LD entries. Also, a NONE reloc was emitted. 4) Unnecessary relocs were emitted for GOT entries. 5) GOT relocs didn't take note of UNDEFWEAK_NO_DYNAMIC_RELOC. * elf32-hppa.c (enum _tls_type): Move. (struct elf32_hppa_link_hash_entry): Make tls_type a bitfield. (elf32_hppa_check_relocs): Set DF_STATIC_TLS only for shared libraries. Tidy tls_type handling. Set symbol tls_type for GOT_TLS_LDM too. (got_entries_needed, got_relocs_needed): New functions. (allocate_dynrelocs): Use them. (elf32_hppa_size_dynamic_sections): Likewise. (elf32_hppa_relocate_section): Delete bogus FIXME. Formatting. Correct code emitting relocs on GD/IE got entries. Report an error when a symbol has both normal and TLS GOT relocs.
This commit is contained in:
@ -1,3 +1,16 @@
|
|||||||
|
2017-11-04 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elf32-hppa.c (enum _tls_type): Move.
|
||||||
|
(struct elf32_hppa_link_hash_entry): Make tls_type a bitfield.
|
||||||
|
(elf32_hppa_check_relocs): Set DF_STATIC_TLS only for shared libraries.
|
||||||
|
Tidy tls_type handling. Set symbol tls_type for GOT_TLS_LDM too.
|
||||||
|
(got_entries_needed, got_relocs_needed): New functions.
|
||||||
|
(allocate_dynrelocs): Use them.
|
||||||
|
(elf32_hppa_size_dynamic_sections): Likewise.
|
||||||
|
(elf32_hppa_relocate_section): Delete bogus FIXME. Formatting.
|
||||||
|
Correct code emitting relocs on GD/IE got entries. Report an
|
||||||
|
error when a symbol has both normal and TLS GOT relocs.
|
||||||
|
|
||||||
2017-11-04 Alan Modra <amodra@gmail.com>
|
2017-11-04 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
PR 22394
|
PR 22394
|
||||||
|
268
bfd/elf32-hppa.c
268
bfd/elf32-hppa.c
@ -206,6 +206,15 @@ struct elf32_hppa_stub_hash_entry
|
|||||||
asection *id_sec;
|
asection *id_sec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum _tls_type
|
||||||
|
{
|
||||||
|
GOT_UNKNOWN = 0,
|
||||||
|
GOT_NORMAL = 1,
|
||||||
|
GOT_TLS_GD = 2,
|
||||||
|
GOT_TLS_LDM = 4,
|
||||||
|
GOT_TLS_IE = 8
|
||||||
|
};
|
||||||
|
|
||||||
struct elf32_hppa_link_hash_entry
|
struct elf32_hppa_link_hash_entry
|
||||||
{
|
{
|
||||||
struct elf_link_hash_entry eh;
|
struct elf_link_hash_entry eh;
|
||||||
@ -233,10 +242,7 @@ struct elf32_hppa_link_hash_entry
|
|||||||
#endif
|
#endif
|
||||||
} *dyn_relocs;
|
} *dyn_relocs;
|
||||||
|
|
||||||
enum
|
ENUM_BITFIELD (_tls_type) tls_type : 8;
|
||||||
{
|
|
||||||
GOT_UNKNOWN = 0, GOT_NORMAL = 1, GOT_TLS_GD = 2, GOT_TLS_LDM = 4, GOT_TLS_IE = 8
|
|
||||||
} tls_type;
|
|
||||||
|
|
||||||
/* Set if this symbol is used by a plabel reloc. */
|
/* Set if this symbol is used by a plabel reloc. */
|
||||||
unsigned int plabel:1;
|
unsigned int plabel:1;
|
||||||
@ -1132,7 +1138,6 @@ elf32_hppa_check_relocs (bfd *abfd,
|
|||||||
const Elf_Internal_Rela *rela_end;
|
const Elf_Internal_Rela *rela_end;
|
||||||
struct elf32_hppa_link_hash_table *htab;
|
struct elf32_hppa_link_hash_table *htab;
|
||||||
asection *sreloc;
|
asection *sreloc;
|
||||||
int tls_type = GOT_UNKNOWN, old_tls_type = GOT_UNKNOWN;
|
|
||||||
|
|
||||||
if (bfd_link_relocatable (info))
|
if (bfd_link_relocatable (info))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -1312,7 +1317,7 @@ elf32_hppa_check_relocs (bfd *abfd,
|
|||||||
|
|
||||||
case R_PARISC_TLS_IE21L:
|
case R_PARISC_TLS_IE21L:
|
||||||
case R_PARISC_TLS_IE14R:
|
case R_PARISC_TLS_IE14R:
|
||||||
if (bfd_link_pic (info))
|
if (bfd_link_dll (info))
|
||||||
info->flags |= DF_STATIC_TLS;
|
info->flags |= DF_STATIC_TLS;
|
||||||
need_entry = NEED_GOT;
|
need_entry = NEED_GOT;
|
||||||
break;
|
break;
|
||||||
@ -1324,22 +1329,23 @@ elf32_hppa_check_relocs (bfd *abfd,
|
|||||||
/* Now carry out our orders. */
|
/* Now carry out our orders. */
|
||||||
if (need_entry & NEED_GOT)
|
if (need_entry & NEED_GOT)
|
||||||
{
|
{
|
||||||
|
int tls_type = GOT_NORMAL;
|
||||||
|
|
||||||
switch (r_type)
|
switch (r_type)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
tls_type = GOT_NORMAL;
|
|
||||||
break;
|
break;
|
||||||
case R_PARISC_TLS_GD21L:
|
case R_PARISC_TLS_GD21L:
|
||||||
case R_PARISC_TLS_GD14R:
|
case R_PARISC_TLS_GD14R:
|
||||||
tls_type |= GOT_TLS_GD;
|
tls_type = GOT_TLS_GD;
|
||||||
break;
|
break;
|
||||||
case R_PARISC_TLS_LDM21L:
|
case R_PARISC_TLS_LDM21L:
|
||||||
case R_PARISC_TLS_LDM14R:
|
case R_PARISC_TLS_LDM14R:
|
||||||
tls_type |= GOT_TLS_LDM;
|
tls_type = GOT_TLS_LDM;
|
||||||
break;
|
break;
|
||||||
case R_PARISC_TLS_IE21L:
|
case R_PARISC_TLS_IE21L:
|
||||||
case R_PARISC_TLS_IE14R:
|
case R_PARISC_TLS_IE14R:
|
||||||
tls_type |= GOT_TLS_IE;
|
tls_type = GOT_TLS_IE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1351,39 +1357,28 @@ elf32_hppa_check_relocs (bfd *abfd,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r_type == R_PARISC_TLS_LDM21L
|
if (hh != NULL)
|
||||||
|| r_type == R_PARISC_TLS_LDM14R)
|
{
|
||||||
htab->tls_ldm_got.refcount += 1;
|
if (tls_type == GOT_TLS_LDM)
|
||||||
|
htab->tls_ldm_got.refcount += 1;
|
||||||
|
else
|
||||||
|
hh->eh.got.refcount += 1;
|
||||||
|
hh->tls_type |= tls_type;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (hh != NULL)
|
bfd_signed_vma *local_got_refcounts;
|
||||||
{
|
|
||||||
hh->eh.got.refcount += 1;
|
/* This is a global offset table entry for a local symbol. */
|
||||||
old_tls_type = hh->tls_type;
|
local_got_refcounts = hppa32_elf_local_refcounts (abfd);
|
||||||
}
|
if (local_got_refcounts == NULL)
|
||||||
|
return FALSE;
|
||||||
|
if (tls_type == GOT_TLS_LDM)
|
||||||
|
htab->tls_ldm_got.refcount += 1;
|
||||||
else
|
else
|
||||||
{
|
local_got_refcounts[r_symndx] += 1;
|
||||||
bfd_signed_vma *local_got_refcounts;
|
|
||||||
|
|
||||||
/* This is a global offset table entry for a local symbol. */
|
|
||||||
local_got_refcounts = hppa32_elf_local_refcounts (abfd);
|
|
||||||
if (local_got_refcounts == NULL)
|
|
||||||
return FALSE;
|
|
||||||
local_got_refcounts[r_symndx] += 1;
|
|
||||||
|
|
||||||
old_tls_type = hppa_elf_local_got_tls_type (abfd) [r_symndx];
|
|
||||||
}
|
|
||||||
|
|
||||||
tls_type |= old_tls_type;
|
|
||||||
|
|
||||||
if (old_tls_type != tls_type)
|
|
||||||
{
|
|
||||||
if (hh != NULL)
|
|
||||||
hh->tls_type = tls_type;
|
|
||||||
else
|
|
||||||
hppa_elf_local_got_tls_type (abfd) [r_symndx] = tls_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
hppa_elf_local_got_tls_type (abfd) [r_symndx] |= tls_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1916,6 +1911,39 @@ allocate_plt_static (struct elf_link_hash_entry *eh, void *inf)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate size of GOT entries for symbol given its TLS_TYPE. */
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
got_entries_needed (int tls_type)
|
||||||
|
{
|
||||||
|
unsigned int need = 0;
|
||||||
|
|
||||||
|
if ((tls_type & GOT_NORMAL) != 0)
|
||||||
|
need += GOT_ENTRY_SIZE;
|
||||||
|
if ((tls_type & GOT_TLS_GD) != 0)
|
||||||
|
need += GOT_ENTRY_SIZE * 2;
|
||||||
|
if ((tls_type & GOT_TLS_IE) != 0)
|
||||||
|
need += GOT_ENTRY_SIZE;
|
||||||
|
return need;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate size of relocs needed for symbol given its TLS_TYPE and
|
||||||
|
NEEDed GOT entries. KNOWN says a TPREL offset can be calculated
|
||||||
|
at link time. */
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
got_relocs_needed (int tls_type, unsigned int need, bfd_boolean known)
|
||||||
|
{
|
||||||
|
/* All the entries we allocated need relocs.
|
||||||
|
Except IE in executable with a local symbol. We could also omit
|
||||||
|
the DTPOFF reloc on the second word of a GD entry under the same
|
||||||
|
condition as that for IE, but ld.so might want to differentiate
|
||||||
|
LD and GD entries at some stage. */
|
||||||
|
if ((tls_type & GOT_TLS_IE) != 0 && known)
|
||||||
|
need -= GOT_ENTRY_SIZE;
|
||||||
|
return need * sizeof (Elf32_External_Rela) / GOT_ENTRY_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate space in .plt, .got and associated reloc sections for
|
/* Allocate space in .plt, .got and associated reloc sections for
|
||||||
global syms. */
|
global syms. */
|
||||||
|
|
||||||
@ -1955,28 +1983,25 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
|
|||||||
|
|
||||||
if (eh->got.refcount > 0)
|
if (eh->got.refcount > 0)
|
||||||
{
|
{
|
||||||
|
unsigned int need;
|
||||||
|
|
||||||
if (!ensure_undef_dynamic (info, eh))
|
if (!ensure_undef_dynamic (info, eh))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
sec = htab->etab.sgot;
|
sec = htab->etab.sgot;
|
||||||
eh->got.offset = sec->size;
|
eh->got.offset = sec->size;
|
||||||
sec->size += GOT_ENTRY_SIZE;
|
need = got_entries_needed (hh->tls_type);
|
||||||
/* R_PARISC_TLS_GD* needs two GOT entries */
|
sec->size += need;
|
||||||
if ((hh->tls_type & (GOT_TLS_GD | GOT_TLS_IE)) == (GOT_TLS_GD | GOT_TLS_IE))
|
|
||||||
sec->size += GOT_ENTRY_SIZE * 2;
|
|
||||||
else if ((hh->tls_type & GOT_TLS_GD) == GOT_TLS_GD)
|
|
||||||
sec->size += GOT_ENTRY_SIZE;
|
|
||||||
if (htab->etab.dynamic_sections_created
|
if (htab->etab.dynamic_sections_created
|
||||||
&& (bfd_link_pic (info)
|
&& (bfd_link_pic (info)
|
||||||
|| (eh->dynindx != -1
|
|| (eh->dynindx != -1
|
||||||
&& !SYMBOL_REFERENCES_LOCAL (info, eh)))
|
&& !SYMBOL_REFERENCES_LOCAL (info, eh)))
|
||||||
&& !UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh))
|
&& !UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh))
|
||||||
{
|
{
|
||||||
htab->etab.srelgot->size += sizeof (Elf32_External_Rela);
|
bfd_boolean tprel_known = (bfd_link_executable (info)
|
||||||
if ((hh->tls_type & (GOT_TLS_GD | GOT_TLS_IE)) == (GOT_TLS_GD | GOT_TLS_IE))
|
&& SYMBOL_REFERENCES_LOCAL (info, eh));
|
||||||
htab->etab.srelgot->size += 2 * sizeof (Elf32_External_Rela);
|
htab->etab.srelgot->size
|
||||||
else if ((hh->tls_type & GOT_TLS_GD) == GOT_TLS_GD)
|
+= got_relocs_needed (hh->tls_type, need, tprel_known);
|
||||||
htab->etab.srelgot->size += sizeof (Elf32_External_Rela);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2195,20 +2220,17 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|||||||
{
|
{
|
||||||
if (*local_got > 0)
|
if (*local_got > 0)
|
||||||
{
|
{
|
||||||
|
unsigned int need;
|
||||||
|
|
||||||
*local_got = sec->size;
|
*local_got = sec->size;
|
||||||
sec->size += GOT_ENTRY_SIZE;
|
need = got_entries_needed (*local_tls_type);
|
||||||
if ((*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)) == (GOT_TLS_GD | GOT_TLS_IE))
|
sec->size += need;
|
||||||
sec->size += 2 * GOT_ENTRY_SIZE;
|
|
||||||
else if ((*local_tls_type & GOT_TLS_GD) == GOT_TLS_GD)
|
|
||||||
sec->size += GOT_ENTRY_SIZE;
|
|
||||||
if (bfd_link_pic (info))
|
if (bfd_link_pic (info))
|
||||||
{
|
{
|
||||||
srel->size += sizeof (Elf32_External_Rela);
|
bfd_boolean tprel_known = bfd_link_executable (info);
|
||||||
if ((*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)) == (GOT_TLS_GD | GOT_TLS_IE))
|
htab->etab.srelgot->size
|
||||||
srel->size += 2 * sizeof (Elf32_External_Rela);
|
+= got_relocs_needed (*local_tls_type, need, tprel_known);
|
||||||
else if ((*local_tls_type & GOT_TLS_GD) == GOT_TLS_GD)
|
}
|
||||||
srel->size += sizeof (Elf32_External_Rela);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*local_got = (bfd_vma) -1;
|
*local_got = (bfd_vma) -1;
|
||||||
@ -4025,17 +4047,17 @@ elf32_hppa_relocate_section (bfd *output_bfd,
|
|||||||
indx = 0;
|
indx = 0;
|
||||||
if (hh != NULL)
|
if (hh != NULL)
|
||||||
{
|
{
|
||||||
bfd_boolean dyn;
|
if (!htab->etab.dynamic_sections_created
|
||||||
dyn = htab->etab.dynamic_sections_created;
|
|| hh->eh.dynindx == -1
|
||||||
|
|| SYMBOL_REFERENCES_LOCAL (info, &hh->eh)
|
||||||
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
|
|| UNDEFWEAK_NO_DYNAMIC_RELOC (info, &hh->eh))
|
||||||
bfd_link_pic (info),
|
/* This is actually a static link, or it is a
|
||||||
&hh->eh)
|
-Bsymbolic link and the symbol is defined
|
||||||
&& (!bfd_link_pic (info)
|
locally, or the symbol was forced to be local
|
||||||
|| !SYMBOL_REFERENCES_LOCAL (info, &hh->eh)))
|
because of a version file. */
|
||||||
{
|
;
|
||||||
indx = hh->eh.dynindx;
|
else
|
||||||
}
|
indx = hh->eh.dynindx;
|
||||||
off = hh->eh.got.offset;
|
off = hh->eh.got.offset;
|
||||||
tls_type = hh->tls_type;
|
tls_type = hh->tls_type;
|
||||||
}
|
}
|
||||||
@ -4061,44 +4083,41 @@ elf32_hppa_relocate_section (bfd *output_bfd,
|
|||||||
now, and emit any relocations. If both an IE GOT and a
|
now, and emit any relocations. If both an IE GOT and a
|
||||||
GD GOT are necessary, we emit the GD first. */
|
GD GOT are necessary, we emit the GD first. */
|
||||||
|
|
||||||
if ((bfd_link_pic (info) || indx != 0)
|
if (indx != 0
|
||||||
&& (hh == NULL
|
|| (bfd_link_pic (info)
|
||||||
|| ELF_ST_VISIBILITY (hh->eh.other) == STV_DEFAULT
|
&& (hh == NULL
|
||||||
|| hh->eh.root.type != bfd_link_hash_undefweak))
|
|| !UNDEFWEAK_NO_DYNAMIC_RELOC (info, &hh->eh))))
|
||||||
{
|
{
|
||||||
need_relocs = TRUE;
|
need_relocs = TRUE;
|
||||||
loc = htab->etab.srelgot->contents;
|
loc = htab->etab.srelgot->contents;
|
||||||
/* FIXME (CAO): Should this be reloc_count++ ? */
|
loc += (htab->etab.srelgot->reloc_count
|
||||||
loc += htab->etab.srelgot->reloc_count * sizeof (Elf32_External_Rela);
|
* sizeof (Elf32_External_Rela));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tls_type & GOT_TLS_GD)
|
if (tls_type & GOT_TLS_GD)
|
||||||
{
|
{
|
||||||
if (need_relocs)
|
if (need_relocs)
|
||||||
{
|
{
|
||||||
outrel.r_offset = (cur_off
|
outrel.r_offset
|
||||||
+ htab->etab.sgot->output_section->vma
|
= (cur_off
|
||||||
+ htab->etab.sgot->output_offset);
|
+ htab->etab.sgot->output_section->vma
|
||||||
outrel.r_info = ELF32_R_INFO (indx,R_PARISC_TLS_DTPMOD32);
|
+ htab->etab.sgot->output_offset);
|
||||||
|
outrel.r_info
|
||||||
|
= ELF32_R_INFO (indx, R_PARISC_TLS_DTPMOD32);
|
||||||
outrel.r_addend = 0;
|
outrel.r_addend = 0;
|
||||||
bfd_put_32 (output_bfd, 0, htab->etab.sgot->contents + cur_off);
|
|
||||||
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
||||||
htab->etab.srelgot->reloc_count++;
|
htab->etab.srelgot->reloc_count++;
|
||||||
loc += sizeof (Elf32_External_Rela);
|
loc += sizeof (Elf32_External_Rela);
|
||||||
|
outrel.r_info
|
||||||
if (indx == 0)
|
= ELF32_R_INFO (indx, R_PARISC_TLS_DTPOFF32);
|
||||||
bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
|
outrel.r_offset += 4;
|
||||||
htab->etab.sgot->contents + cur_off + 4);
|
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
||||||
else
|
htab->etab.srelgot->reloc_count++;
|
||||||
{
|
loc += sizeof (Elf32_External_Rela);
|
||||||
bfd_put_32 (output_bfd, 0,
|
bfd_put_32 (output_bfd, 0,
|
||||||
htab->etab.sgot->contents + cur_off + 4);
|
htab->etab.sgot->contents + cur_off);
|
||||||
outrel.r_info = ELF32_R_INFO (indx, R_PARISC_TLS_DTPOFF32);
|
bfd_put_32 (output_bfd, 0,
|
||||||
outrel.r_offset += 4;
|
htab->etab.sgot->contents + cur_off + 4);
|
||||||
bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
|
|
||||||
htab->etab.srelgot->reloc_count++;
|
|
||||||
loc += sizeof (Elf32_External_Rela);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4109,28 +4128,28 @@ elf32_hppa_relocate_section (bfd *output_bfd,
|
|||||||
to module 1, the executable. */
|
to module 1, the executable. */
|
||||||
bfd_put_32 (output_bfd, 1,
|
bfd_put_32 (output_bfd, 1,
|
||||||
htab->etab.sgot->contents + cur_off);
|
htab->etab.sgot->contents + cur_off);
|
||||||
bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
|
bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
|
||||||
htab->etab.sgot->contents + cur_off + 4);
|
htab->etab.sgot->contents + cur_off + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cur_off += 8;
|
cur_off += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tls_type & GOT_TLS_IE)
|
if (tls_type & GOT_TLS_IE)
|
||||||
{
|
{
|
||||||
if (need_relocs)
|
if (need_relocs
|
||||||
|
&& !(bfd_link_executable (info)
|
||||||
|
&& SYMBOL_REFERENCES_LOCAL (info, &hh->eh)))
|
||||||
{
|
{
|
||||||
outrel.r_offset = (cur_off
|
outrel.r_offset
|
||||||
+ htab->etab.sgot->output_section->vma
|
= (cur_off
|
||||||
+ htab->etab.sgot->output_offset);
|
+ htab->etab.sgot->output_section->vma
|
||||||
outrel.r_info = ELF32_R_INFO (indx, R_PARISC_TLS_TPREL32);
|
+ htab->etab.sgot->output_offset);
|
||||||
|
outrel.r_info = ELF32_R_INFO (indx,
|
||||||
|
R_PARISC_TLS_TPREL32);
|
||||||
if (indx == 0)
|
if (indx == 0)
|
||||||
outrel.r_addend = relocation - dtpoff_base (info);
|
outrel.r_addend = relocation - dtpoff_base (info);
|
||||||
else
|
else
|
||||||
outrel.r_addend = 0;
|
outrel.r_addend = 0;
|
||||||
|
|
||||||
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
||||||
htab->etab.srelgot->reloc_count++;
|
htab->etab.srelgot->reloc_count++;
|
||||||
loc += sizeof (Elf32_External_Rela);
|
loc += sizeof (Elf32_External_Rela);
|
||||||
@ -4138,7 +4157,6 @@ elf32_hppa_relocate_section (bfd *output_bfd,
|
|||||||
else
|
else
|
||||||
bfd_put_32 (output_bfd, tpoff (info, relocation),
|
bfd_put_32 (output_bfd, tpoff (info, relocation),
|
||||||
htab->etab.sgot->contents + cur_off);
|
htab->etab.sgot->contents + cur_off);
|
||||||
|
|
||||||
cur_off += 4;
|
cur_off += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4148,6 +4166,35 @@ elf32_hppa_relocate_section (bfd *output_bfd,
|
|||||||
local_got_offsets[r_symndx] |= 1;
|
local_got_offsets[r_symndx] |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((tls_type & GOT_NORMAL) != 0
|
||||||
|
&& (tls_type & (GOT_TLS_GD | GOT_TLS_LDM | GOT_TLS_IE)) != 0)
|
||||||
|
{
|
||||||
|
if (hh != NULL)
|
||||||
|
_bfd_error_handler (_("%s has both normal and TLS relocs"),
|
||||||
|
hh_name (hh));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Elf_Internal_Sym *isym
|
||||||
|
= bfd_sym_from_r_symndx (&htab->sym_cache,
|
||||||
|
input_bfd, r_symndx);
|
||||||
|
if (isym == NULL)
|
||||||
|
return FALSE;
|
||||||
|
sym_name
|
||||||
|
= bfd_elf_string_from_elf_section (input_bfd,
|
||||||
|
symtab_hdr->sh_link,
|
||||||
|
isym->st_name);
|
||||||
|
if (sym_name == NULL)
|
||||||
|
return FALSE;
|
||||||
|
if (*sym_name == '\0')
|
||||||
|
sym_name = bfd_section_name (input_bfd, sym_sec);
|
||||||
|
_bfd_error_handler
|
||||||
|
(_("%B:%s has both normal and TLS relocs"),
|
||||||
|
input_bfd, sym_name);
|
||||||
|
}
|
||||||
|
bfd_set_error (bfd_error_bad_value);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((tls_type & GOT_TLS_GD)
|
if ((tls_type & GOT_TLS_GD)
|
||||||
&& r_type != R_PARISC_TLS_GD21L
|
&& r_type != R_PARISC_TLS_GD21L
|
||||||
&& r_type != R_PARISC_TLS_GD14R)
|
&& r_type != R_PARISC_TLS_GD14R)
|
||||||
@ -4290,8 +4337,7 @@ elf32_hppa_finish_dynamic_symbol (bfd *output_bfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (eh->got.offset != (bfd_vma) -1
|
if (eh->got.offset != (bfd_vma) -1
|
||||||
&& (hppa_elf_hash_entry (eh)->tls_type & GOT_TLS_GD) == 0
|
&& (hppa_elf_hash_entry (eh)->tls_type & GOT_NORMAL) != 0
|
||||||
&& (hppa_elf_hash_entry (eh)->tls_type & GOT_TLS_IE) == 0
|
|
||||||
&& !UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh))
|
&& !UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh))
|
||||||
{
|
{
|
||||||
bfd_boolean is_dyn = (eh->dynindx != -1
|
bfd_boolean is_dyn = (eh->dynindx != -1
|
||||||
|
Reference in New Issue
Block a user