This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[19/20] MIPS GOT: Tidy TLS fields
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: binutils at sourceware dot org
- Date: Mon, 11 Feb 2013 18:17:53 +0000
- Subject: [19/20] MIPS GOT: Tidy TLS fields
- References: <87fw1222fy.fsf@talisman.default>
Now that all TLS GOT information is tracked by mips_got_entries, and now
that there's only one TLS type per GOT entry, we can convert the original
tls_type bitmask into a simple enum and separate fields. I've used
unsigned chars for now, because there's still a 2 byte hole, but we
could easily switch to bitfields in future.
Also, the two callers of mips_tls_got_index are now in code that
returns the got index whatever happens, so they might as well call
mips_elf_initialize_tls_slots directly.
Richard
bfd/
* elfxx-mips.c (mips_got_tls_type): New enum.
(mips_got_entry): Add tls_initialized.
(mips_elf_got_entry_hash, mips_elf_got_entry_eq, mips_tls_got_relocs)
(mips_elf_count_got_entry, mips_elf_initialize_tls_index): Remove
GOT_TLS_TYPE masks.
(mips_elf_reloc_tls_type, mips_tls_got_entries)
(mips_elf_record_global_got_symbol, mips_elf_initialize_tls_index)
(_bfd_mips_elf_finish_dynamic_symbol): Use GOT_TLS_NONE rather
than GOT_NORMAL.
(mips_elf_initialize_tls_slots): Replace got_offset and tls_type_p
arguments with a GOT entry. Remove GOT_TLS_TYPE masks. Use
tls_initialized rather than GOT_TLS_DONE.
(mips_tls_got_index): Delete.
(mips_elf_local_got_index, mips_elf_global_got_index): Use
mips_elf_initialize_tls_slots rather than mips_tls_got_index.
(mips_elf_record_got_entry): Initialize tls_initialized.
Index: bfd/elfxx-mips.c
===================================================================
--- bfd/elfxx-mips.c 2013-02-11 16:52:37.543791937 +0000
+++ bfd/elfxx-mips.c 2013-02-11 16:52:45.144836467 +0000
@@ -47,6 +47,14 @@
#include "hashtab.h"
+/* Types of TLS GOT entry. */
+enum mips_got_tls_type {
+ GOT_TLS_NONE,
+ GOT_TLS_GD,
+ GOT_TLS_LDM,
+ GOT_TLS_IE
+};
+
/* This structure is used to hold information about one GOT entry.
There are four types of entry:
@@ -86,17 +94,14 @@ struct mips_got_entry
struct mips_elf_link_hash_entry *h;
} d;
- /* The TLS type of this GOT entry: GOT_NORMAL, GOT_TLS_IE, GOT_TLS_GD
- or GOT_TLS_LDM. An LDM GOT entry will be a local symbol entry with
- r_symndx == 0. */
-#define GOT_NORMAL 0
-#define GOT_TLS_GD 1
-#define GOT_TLS_LDM 2
-#define GOT_TLS_IE 4
-#define GOT_TLS_TYPE 7
-#define GOT_TLS_DONE 0x80
+ /* The TLS type of this GOT entry. An LDM GOT entry will be a local
+ symbol entry with r_symndx == 0. */
unsigned char tls_type;
+ /* True if we have filled in the GOT contents for a TLS entry,
+ and created the associated relocations. */
+ unsigned char tls_initialized;
+
/* The offset from the beginning of the .got section to the entry
corresponding to this symbol+addend. If it's a global symbol
whose offset is yet to be decided, it's going to be -1. */
@@ -2742,8 +2747,8 @@ mips_elf_got_entry_hash (const void *ent
const struct mips_got_entry *entry = (struct mips_got_entry *)entry_;
return (entry->symndx
- + (((entry->tls_type & GOT_TLS_TYPE) == GOT_TLS_LDM) << 18)
- + ((entry->tls_type & GOT_TLS_TYPE) == GOT_TLS_LDM ? 0
+ + ((entry->tls_type == GOT_TLS_LDM) << 18)
+ + (entry->tls_type == GOT_TLS_LDM ? 0
: !entry->abfd ? mips_elf_hash_bfd_vma (entry->d.address)
: entry->symndx >= 0 ? (entry->abfd->id
+ mips_elf_hash_bfd_vma (entry->d.addend))
@@ -2757,8 +2762,8 @@ mips_elf_got_entry_eq (const void *entry
const struct mips_got_entry *e2 = (struct mips_got_entry *)entry2;
return (e1->symndx == e2->symndx
- && (e1->tls_type & GOT_TLS_TYPE) == (e2->tls_type & GOT_TLS_TYPE)
- && ((e1->tls_type & GOT_TLS_TYPE) == GOT_TLS_LDM ? TRUE
+ && e1->tls_type == e2->tls_type
+ && (e1->tls_type == GOT_TLS_LDM ? TRUE
: !e1->abfd ? !e2->abfd && e1->d.address == e2->d.address
: e1->symndx >= 0 ? (e1->abfd == e2->abfd
&& e1->d.addend == e2->d.addend)
@@ -2889,7 +2894,7 @@ mips_elf_reloc_tls_type (unsigned int r_
if (tls_gottprel_reloc_p (r_type))
return GOT_TLS_IE;
- return GOT_NORMAL;
+ return GOT_TLS_NONE;
}
/* Return the number of GOT slots needed for GOT TLS type TYPE. */
@@ -2906,7 +2911,7 @@ mips_tls_got_entries (unsigned int type)
case GOT_TLS_IE:
return 1;
- case GOT_NORMAL:
+ case GOT_TLS_NONE:
return 0;
}
abort ();
@@ -2937,7 +2942,7 @@ mips_tls_got_relocs (struct bfd_link_inf
if (!need_relocs)
return 0;
- switch (tls_type & GOT_TLS_TYPE)
+ switch (tls_type)
{
case GOT_TLS_GD:
return indx != 0 ? 2 : 1;
@@ -2961,13 +2966,10 @@ mips_elf_count_got_entry (struct bfd_lin
struct mips_got_info *g,
struct mips_got_entry *entry)
{
- unsigned char tls_type;
-
- tls_type = entry->tls_type & GOT_TLS_TYPE;
- if (tls_type)
+ if (entry->tls_type)
{
- g->tls_gotno += mips_tls_got_entries (tls_type);
- g->relocs += mips_tls_got_relocs (info, tls_type,
+ g->tls_gotno += mips_tls_got_entries (entry->tls_type);
+ g->relocs += mips_tls_got_relocs (info, entry->tls_type,
entry->symndx < 0
? &entry->d.h->root : NULL);
}
@@ -3028,16 +3030,15 @@ mips_elf_output_dynamic_relocation (bfd
/* Initialize a set of TLS GOT entries for one symbol. */
static void
-mips_elf_initialize_tls_slots (bfd *abfd, bfd_vma got_offset,
- unsigned char *tls_type_p,
- struct bfd_link_info *info,
+mips_elf_initialize_tls_slots (bfd *abfd, struct bfd_link_info *info,
+ struct mips_got_entry *entry,
struct mips_elf_link_hash_entry *h,
bfd_vma value)
{
struct mips_elf_link_hash_table *htab;
int indx;
asection *sreloc, *sgot;
- bfd_vma got_offset2;
+ bfd_vma got_offset, got_offset2;
bfd_boolean need_relocs = FALSE;
htab = mips_elf_hash_table (info);
@@ -3056,7 +3057,7 @@ mips_elf_initialize_tls_slots (bfd *abfd
indx = h->root.dynindx;
}
- if (*tls_type_p & GOT_TLS_DONE)
+ if (entry->tls_initialized)
return;
if ((info->shared || indx != 0)
@@ -3073,8 +3074,9 @@ mips_elf_initialize_tls_slots (bfd *abfd
/* Emit necessary relocations. */
sreloc = mips_elf_rel_dyn_section (info, FALSE);
+ got_offset = entry->gotidx;
- switch (*tls_type_p & GOT_TLS_TYPE)
+ switch (entry->tls_type)
{
case GOT_TLS_GD:
/* General Dynamic. */
@@ -3147,21 +3149,7 @@ mips_elf_initialize_tls_slots (bfd *abfd
abort ();
}
- *tls_type_p |= GOT_TLS_DONE;
-}
-
-/* Return the GOT index to use for a relocation against H using the
- TLS model in *TLS_TYPE. The GOT entries for this symbol/model
- combination start at GOT_INDEX into ABFD's GOT. This function
- initializes the GOT entries and corresponding relocations. */
-
-static bfd_vma
-mips_tls_got_index (bfd *abfd, bfd_vma got_index, unsigned char *tls_type,
- struct bfd_link_info *info,
- struct mips_elf_link_hash_entry *h, bfd_vma symbol)
-{
- mips_elf_initialize_tls_slots (abfd, got_index, tls_type, info, h, symbol);
- return got_index;
+ entry->tls_initialized = TRUE;
}
/* Return the offset from _GLOBAL_OFFSET_TABLE_ of the .got.plt entry
@@ -3222,10 +3210,8 @@ mips_elf_local_got_index (bfd *abfd, bfd
return MINUS_ONE;
if (entry->tls_type)
- return mips_tls_got_index (abfd, entry->gotidx, &entry->tls_type,
- info, h, value);
- else
- return entry->gotidx;
+ mips_elf_initialize_tls_slots (abfd, info, entry, h, value);
+ return entry->gotidx;
}
/* Return the GOT index of global symbol H in the primary GOT. */
@@ -3301,8 +3287,7 @@ mips_elf_global_got_index (bfd *obfd, st
+ h->root.u.def.section->output_offset
+ h->root.u.def.section->output_section->vma);
- return mips_tls_got_index (obfd, gotidx, &entry->tls_type,
- info, lookup.d.h, value);
+ mips_elf_initialize_tls_slots (obfd, info, entry, lookup.d.h, value);
}
return gotidx;
}
@@ -3632,6 +3617,7 @@ mips_elf_record_got_entry (struct bfd_li
if (!entry)
return FALSE;
+ lookup->tls_initialized = FALSE;
lookup->gotidx = -1;
*entry = *lookup;
*loc = entry;
@@ -3688,7 +3674,7 @@ mips_elf_record_global_got_symbol (struc
}
tls_type = mips_elf_reloc_tls_type (r_type);
- if (tls_type == GOT_NORMAL && hmips->global_got_area > GGA_NORMAL)
+ if (tls_type == GOT_TLS_NONE && hmips->global_got_area > GGA_NORMAL)
hmips->global_got_area = GGA_NORMAL;
entry.abfd = abfd;
@@ -4239,12 +4225,10 @@ mips_elf_initialize_tls_index (void **en
{
struct mips_got_entry *entry;
struct mips_elf_traverse_got_arg *arg;
- unsigned char tls_type;
/* We're only interested in TLS symbols. */
entry = (struct mips_got_entry *) *entryp;
- tls_type = (entry->tls_type & GOT_TLS_TYPE);
- if (tls_type == 0)
+ if (entry->tls_type == GOT_TLS_NONE)
return 1;
arg = (struct mips_elf_traverse_got_arg *) data;
@@ -4255,7 +4239,7 @@ mips_elf_initialize_tls_index (void **en
}
/* Account for the entries we've just allocated. */
- arg->g->tls_assigned_gotno += mips_tls_got_entries (tls_type);
+ arg->g->tls_assigned_gotno += mips_tls_got_entries (entry->tls_type);
return 1;
}
@@ -9854,7 +9838,7 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
e.abfd = output_bfd;
e.symndx = -1;
e.d.h = hmips;
- e.tls_type = 0;
+ e.tls_type = GOT_TLS_NONE;
for (g = g->next; g->next != gg; g = g->next)
{