aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog29
-rw-r--r--bfd/bfd-in2.h10
-rw-r--r--bfd/coff-rs6000.c217
-rw-r--r--bfd/coff64-rs6000.c109
-rw-r--r--bfd/coffcode.h67
-rw-r--r--bfd/coffswap.h11
-rw-r--r--bfd/libbfd.h10
-rw-r--r--bfd/libxcoff.h1
-rw-r--r--bfd/reloc.c20
-rw-r--r--bfd/xcofflink.c18
10 files changed, 456 insertions, 36 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d955f78..6d61abe 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,34 @@
2021-03-12 Clément Chigot <clement.chigot@atos.net>
+ * reloc.c (BFD_RELOC_PPC_TLS_LE, BFD_RELOC_PPC_TLS_IE,
+ BFD_RELOC_PPC_TLS_M, BFD_RELOC_PPC_TLS_ML, BFD_RELOC_PPC64_TLS_GD,
+ BFD_RELOC_PPC64_TLS_LD, BFD_RELOC_PPC64_TLS_LE,
+ BFD_RELOC_PPC64_TLS_IE, BFD_RELOC_PPC64_TLS_M,
+ BFD_RELOC_PPC64_TLS_ML): New relocations.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * coff-rs6000.c (xcoff_calculate_relocation): Call
+ xcoff_reloc_type_tls for TLS relocations.
+ (xcoff_howto_table): Implement TLS relocations.
+ (_bfd_xcoff_reloc_type_lookup): Add cases TLS relocations.
+ (xcoff_reloc_type_tls): New function.
+ * coff64-rs6000.c (xcoff_calculate_relocation): Likewise.
+ (xcoff_howto_table): Likewise.
+ (_bfd_xcoff_reloc_type_lookup): Likewise.
+ * coffcode.h (sec_to_styp_flags): Handle TLS sections.
+ (styp_to_sec_flags): Likewise.
+ (coff_compute_section_file_positions): Avoid file offset
+ optimisation for .data when the previous section is .tdata.
+ (coff_write_object_contents): Handle TLS sections.
+ * coffswap.h (coff_swap_aouthdr_out): Add support for
+ new fields in aouthdr.
+ * libxcoff.h (xcoff_reloc_type_tls): Add prototype.
+ * xcofflink.c (xcoff_link_add_symbols): Handle XMC_UL.
+ (xcoff_need_ldrel_p): Add cases for TLS relocations.
+ (xcoff_create_ldrel): Add l_symndx for TLS sections.
+
+2021-03-12 Clément Chigot <clement.chigot@atos.net>
+
* reloc.c (BFD_RELOC_PPC_TOC16_HI, BFD_RELOC_PPC_TOC16_LO):
New relocations.
* bfd-in2.h: Regenerate.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 9bd61b1..54c1c9a 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -3003,6 +3003,10 @@ instruction. */
BFD_RELOC_PPC_TLS,
BFD_RELOC_PPC_TLSGD,
BFD_RELOC_PPC_TLSLD,
+ BFD_RELOC_PPC_TLSLE,
+ BFD_RELOC_PPC_TLSIE,
+ BFD_RELOC_PPC_TLSM,
+ BFD_RELOC_PPC_TLSML,
BFD_RELOC_PPC_DTPMOD,
BFD_RELOC_PPC_TPREL16,
BFD_RELOC_PPC_TPREL16_LO,
@@ -3030,6 +3034,12 @@ instruction. */
BFD_RELOC_PPC_GOT_DTPREL16_LO,
BFD_RELOC_PPC_GOT_DTPREL16_HI,
BFD_RELOC_PPC_GOT_DTPREL16_HA,
+ BFD_RELOC_PPC64_TLSGD,
+ BFD_RELOC_PPC64_TLSLD,
+ BFD_RELOC_PPC64_TLSLE,
+ BFD_RELOC_PPC64_TLSIE,
+ BFD_RELOC_PPC64_TLSM,
+ BFD_RELOC_PPC64_TLSML,
BFD_RELOC_PPC64_TPREL16_DS,
BFD_RELOC_PPC64_TPREL16_LO_DS,
BFD_RELOC_PPC64_TPREL16_HIGH,
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index b77ff0c..a29cf5b 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -190,12 +190,12 @@ xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] =
xcoff_reloc_type_fail, /* (0x1d) */
xcoff_reloc_type_fail, /* (0x1e) */
xcoff_reloc_type_fail, /* (0x1f) */
- xcoff_reloc_type_fail, /* R_TLS (0x20) */
- xcoff_reloc_type_fail, /* R_TLS_IE (0x21) */
- xcoff_reloc_type_fail, /* R_TLS_LD (0x22) */
- xcoff_reloc_type_fail, /* R_TLS_LE (0x23) */
- xcoff_reloc_type_fail, /* R_TLSM (0x24) */
- xcoff_reloc_type_fail, /* R_TLSML (0x25) */
+ xcoff_reloc_type_tls, /* R_TLS (0x20) */
+ xcoff_reloc_type_tls, /* R_TLS_IE (0x21) */
+ xcoff_reloc_type_tls, /* R_TLS_LD (0x22) */
+ xcoff_reloc_type_tls, /* R_TLS_LE (0x23) */
+ xcoff_reloc_type_tls, /* R_TLSM (0x24) */
+ xcoff_reloc_type_tls, /* R_TLSML (0x25) */
xcoff_reloc_type_fail, /* (0x26) */
xcoff_reloc_type_fail, /* (0x27) */
xcoff_reloc_type_fail, /* (0x28) */
@@ -1064,22 +1064,95 @@ reloc_howto_type xcoff_howto_table[] =
EMPTY_HOWTO (0x1f),
/* 0x20: General-dynamic TLS relocation. */
- EMPTY_HOWTO (R_TLS),
+ HOWTO (R_TLS, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLS", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
/* 0x21: Initial-exec TLS relocation. */
- EMPTY_HOWTO (R_TLS_IE),
+ HOWTO (R_TLS_IE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLS_IE", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
/* 0x22: Local-dynamic TLS relocation. */
- EMPTY_HOWTO (R_TLS_LD),
+ HOWTO (R_TLS_LD, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLS_LD", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
/* 0x23: Local-exec TLS relocation. */
- EMPTY_HOWTO (R_TLS_LE),
+ HOWTO (R_TLS_LE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLS_LE", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
/* 0x24: TLS relocation. */
- EMPTY_HOWTO(R_TLSM),
+ HOWTO (R_TLSM, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLSM", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
/* 0x25: TLS module relocation. */
- EMPTY_HOWTO(R_TLSML),
+ HOWTO (R_TLSML, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLSM", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
EMPTY_HOWTO(0x26),
EMPTY_HOWTO(0x27),
@@ -1180,6 +1253,18 @@ _bfd_xcoff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return &xcoff_howto_table[0];
case BFD_RELOC_NONE:
return &xcoff_howto_table[0xf];
+ case BFD_RELOC_PPC_TLSGD:
+ return &xcoff_howto_table[0x20];
+ case BFD_RELOC_PPC_TLSIE:
+ return &xcoff_howto_table[0x21];
+ case BFD_RELOC_PPC_TLSLD:
+ return &xcoff_howto_table[0x22];
+ case BFD_RELOC_PPC_TLSLE:
+ return &xcoff_howto_table[0x23];
+ case BFD_RELOC_PPC_TLSM:
+ return &xcoff_howto_table[0x24];
+ case BFD_RELOC_PPC_TLSML:
+ return &xcoff_howto_table[0x25];
default:
return NULL;
}
@@ -3127,6 +3212,88 @@ xcoff_reloc_type_crel (bfd *input_bfd ATTRIBUTE_UNUSED,
return TRUE;
}
+bfd_boolean
+xcoff_reloc_type_tls (bfd *input_bfd ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *howto,
+ bfd_vma val,
+ bfd_vma addend,
+ bfd_vma *relocation,
+ bfd_byte *contents ATTRIBUTE_UNUSED)
+{
+ struct xcoff_link_hash_entry *h;
+
+ if (0 > rel->r_symndx)
+ return FALSE;
+
+ h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
+
+ /* FIXME: R_TLSML is targeting a internal TOC symbol, which will
+ make the following checks failing. It should be moved with
+ R_TLSM bellow once it works. */
+ if (howto->type == R_TLSML)
+ {
+ *relocation = 0;
+ return TRUE;
+ }
+
+ /* FIXME: h is sometimes null, if the TLS symbol is not exported. */
+ if (!h)
+ {
+ _bfd_error_handler
+ (_("%pB: TLS relocation at (0x%" BFD_VMA_FMT "x) over "
+ "internal symbols (C_HIDEXT) not yet possible\n"),
+ input_bfd, rel->r_vaddr);
+ return FALSE;
+ }
+
+
+ /* TLS relocations must target a TLS symbol. */
+ if (h->smclas != XMC_TL && h->smclas != XMC_UL)
+ {
+ _bfd_error_handler
+ (_("%pB: TLS relocation at (0x%" BFD_VMA_FMT "x) over "
+ "non-TLS symbol %s (0x%x)\n"),
+ input_bfd, rel->r_vaddr, h->root.root.string, h->smclas);
+ return FALSE;
+ }
+
+ /* Local TLS relocations must target a local symbol, ie
+ non-imported. */
+ if ((rel->r_type == R_TLS_LD || rel->r_type == R_TLS_LE)
+ && (((h->flags & XCOFF_DEF_REGULAR) == 0
+ && (h->flags & XCOFF_DEF_DYNAMIC) != 0)
+ || (h->flags & XCOFF_IMPORT) != 0))
+ {
+ _bfd_error_handler
+ (_("%pB: TLS local relocation at (0x%" BFD_VMA_FMT "x) over "
+ "imported symbol %s\n"),
+ input_bfd, rel->r_vaddr, h->root.root.string);
+ return FALSE;
+ }
+
+ /* R_TLSM and R_TLSML are relocations used by the loader.
+ The value must be 0.
+ FIXME: move R_TLSML here. */
+ if (howto->type == R_TLSM)
+ {
+ *relocation = 0;
+ return TRUE;
+ }
+
+ /* Other TLS relocations aims to put offsets from TLS pointers
+ starting at -0x7c00 (or -0x7800 in XCOFF64). It becomes a
+ simple R_POS relocation as long as .tdata and .tbss addresses
+ start at the same value. This is done in aix ld scripts.
+ TODO: implement optimization when tls size is < 62K. */
+ *relocation = val + addend;
+
+ return TRUE;
+}
+
static bfd_boolean
xcoff_complain_overflow_dont_func (bfd *input_bfd ATTRIBUTE_UNUSED,
bfd_vma val ATTRIBUTE_UNUSED,
@@ -3335,13 +3502,6 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd,
quite figure out when this is useful. These relocs are
not defined by the PowerOpen ABI.
- R_TLS
- R_TLS_IE
- R_TLS_LD
- R_TLSLE
-
- Not yet implemented.
-
Supported r_type's
R_POS:
@@ -3437,6 +3597,25 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd,
fixed address which may be modified to a relative branch.
The PowerOpen ABI does not define this relocation type.
+ R_TLS:
+ Thread-local storage relocation using general-dynamic
+ model.
+
+ R_TLS_IE:
+ Thread-local storage relocation using initial-exec model.
+
+ R_TLS_LD:
+ Thread-local storage relocation using local-dynamic model.
+
+ R_TLS_LE:
+ Thread-local storage relocation using local-exec model.
+
+ R_TLS:
+ Tread-local storage relocation used by the loader.
+
+ R_TLSM:
+ Tread-local storage relocation used by the loader.
+
R_TOCU:
Upper TOC relative relocation. The value is the
high-order 16 bit of a TOC relative relocation.
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 55a6821..f8e6849 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -212,12 +212,12 @@ xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] =
xcoff_reloc_type_fail, /* (0x1d) */
xcoff_reloc_type_fail, /* (0x1e) */
xcoff_reloc_type_fail, /* (0x1f) */
- xcoff_reloc_type_fail, /* R_TLS (0x20) */
- xcoff_reloc_type_fail, /* R_TLS_IE (0x21) */
- xcoff_reloc_type_fail, /* R_TLS_LD (0x22) */
- xcoff_reloc_type_fail, /* R_TLS_LE (0x23) */
- xcoff_reloc_type_fail, /* R_TLSM (0x24) */
- xcoff_reloc_type_fail, /* R_TLSML (0x25) */
+ xcoff_reloc_type_tls, /* R_TLS (0x20) */
+ xcoff_reloc_type_tls, /* R_TLS_IE (0x21) */
+ xcoff_reloc_type_tls, /* R_TLS_LD (0x22) */
+ xcoff_reloc_type_tls, /* R_TLS_LE (0x23) */
+ xcoff_reloc_type_tls, /* R_TLSM (0x24) */
+ xcoff_reloc_type_tls, /* R_TLSML (0x25) */
xcoff_reloc_type_fail, /* (0x26) */
xcoff_reloc_type_fail, /* (0x27) */
xcoff_reloc_type_fail, /* (0x28) */
@@ -1230,24 +1230,95 @@ reloc_howto_type xcoff64_howto_table[] =
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
-
/* 0x20: General-dynamic TLS relocation. */
- EMPTY_HOWTO (R_TLS),
+ HOWTO (R_TLS, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLS", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
/* 0x21: Initial-exec TLS relocation. */
- EMPTY_HOWTO (R_TLS_IE),
+ HOWTO (R_TLS_IE, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLS_IE", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
/* 0x22: Local-dynamic TLS relocation. */
- EMPTY_HOWTO (R_TLS_LD),
+ HOWTO (R_TLS_LD, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLS_LD", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
/* 0x23: Local-exec TLS relocation. */
- EMPTY_HOWTO (R_TLS_LE),
+ HOWTO (R_TLS_LE, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLS_LE", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
/* 0x24: TLS relocation. */
- EMPTY_HOWTO(R_TLSM),
+ HOWTO (R_TLSM, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLSM", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
/* 0x25: TLS module relocation. */
- EMPTY_HOWTO(R_TLSML),
+ HOWTO (R_TLSML, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TLSM", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
EMPTY_HOWTO(0x26),
EMPTY_HOWTO(0x27),
@@ -1355,6 +1426,18 @@ xcoff64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return &xcoff64_howto_table[0];
case BFD_RELOC_NONE:
return &xcoff64_howto_table[0xf];
+ case BFD_RELOC_PPC64_TLSGD:
+ return &xcoff64_howto_table[0x20];
+ case BFD_RELOC_PPC64_TLSIE:
+ return &xcoff64_howto_table[0x21];
+ case BFD_RELOC_PPC64_TLSLD:
+ return &xcoff64_howto_table[0x22];
+ case BFD_RELOC_PPC64_TLSLE:
+ return &xcoff64_howto_table[0x23];
+ case BFD_RELOC_PPC64_TLSM:
+ return &xcoff64_howto_table[0x24];
+ case BFD_RELOC_PPC64_TLSML:
+ return &xcoff64_howto_table[0x25];
default:
return NULL;
}
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index b0ca266..bcd34d4 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -548,6 +548,14 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags)
}
#endif
#ifdef RS6000COFF_C
+ else if (!strcmp (sec_name, _TDATA))
+ {
+ styp_flags = STYP_TDATA;
+ }
+ else if (!strcmp (sec_name, _TBSS))
+ {
+ styp_flags = STYP_TBSS;
+ }
else if (!strcmp (sec_name, _PAD))
{
styp_flags = STYP_PAD;
@@ -787,6 +795,22 @@ styp_to_sec_flags (bfd *abfd,
else if (styp_flags & STYP_PAD)
sec_flags = 0;
#ifdef RS6000COFF_C
+ else if (styp_flags & STYP_TDATA)
+ {
+ if (sec_flags & SEC_NEVER_LOAD)
+ sec_flags |= SEC_DATA | SEC_THREAD_LOCAL | SEC_COFF_SHARED_LIBRARY;
+ else
+ sec_flags |= SEC_DATA | SEC_THREAD_LOCAL | SEC_LOAD | SEC_ALLOC;
+ }
+ else if (styp_flags & STYP_TBSS)
+ {
+#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY
+ if (sec_flags & SEC_NEVER_LOAD)
+ sec_flags |= SEC_ALLOC | SEC_THREAD_LOCAL | SEC_COFF_SHARED_LIBRARY;
+ else
+#endif
+ sec_flags |= SEC_ALLOC | SEC_THREAD_LOCAL;
+ }
else if (styp_flags & STYP_EXCEPT)
sec_flags |= SEC_LOAD;
else if (styp_flags & STYP_LOADER)
@@ -3168,10 +3192,15 @@ coff_compute_section_file_positions (bfd * abfd)
0 .text 000054cc 10000128 10000128 00000128 2**5
CONTENTS, ALLOC, LOAD, CODE
+
+ Don't perform the above tweak if the previous one is .tdata,
+ as it will increase the memory allocated for every threads
+ created and not just improve performances with gdb.
*/
- if (!strcmp (current->name, _TEXT)
- || !strcmp (current->name, _DATA))
+ if ((!strcmp (current->name, _TEXT)
+ || !strcmp (current->name, _DATA))
+ && (previous == NULL || strcmp(previous->name, _TDATA)))
{
bfd_vma align = 4096;
bfd_vma sofar_off = sofar % align;
@@ -3381,6 +3410,10 @@ coff_write_object_contents (bfd * abfd)
asection *text_sec = NULL;
asection *data_sec = NULL;
asection *bss_sec = NULL;
+#ifdef RS6000COFF_C
+ asection *tdata_sec = NULL;
+ asection *tbss_sec = NULL;
+#endif
struct internal_filehdr internal_f;
struct internal_aouthdr internal_a;
#ifdef COFF_LONG_SECTION_NAMES
@@ -3603,6 +3636,13 @@ coff_write_object_contents (bfd * abfd)
data_sec = current;
else if (!strcmp (current->name, _BSS))
bss_sec = current;
+#ifdef RS6000COFF_C
+ else if (!strcmp (current->name, _TDATA))
+ tdata_sec = current;
+ else if (!strcmp (current->name, _TBSS))
+ tbss_sec = current;
+#endif
+
#ifdef COFF_ENCODE_ALIGNMENT
COFF_ENCODE_ALIGNMENT(section, current->alignment_power);
@@ -4041,6 +4081,29 @@ coff_write_object_contents (bfd * abfd)
else
internal_a.o_snbss = 0;
+ if (tdata_sec != NULL)
+ {
+ internal_a.o_sntdata = tdata_sec->target_index;
+ /* TODO: o_flags should be set to RS6K_AOUTHDR_TLS_LE
+ if there is at least one R_TLS_LE relocations. */
+ internal_a.o_flags = 0;
+#ifdef XCOFF64
+ internal_a.o_x64flags = 0;
+#endif
+ }
+ else
+ {
+ internal_a.o_sntdata = 0;
+ internal_a.o_flags = 0;
+#ifdef XCOFF64
+ internal_a.o_x64flags = 0;
+#endif
+ }
+ if (tbss_sec != NULL)
+ internal_a.o_sntbss = tbss_sec->target_index;
+ else
+ internal_a.o_sntbss = 0;
+
toc = xcoff_data (abfd)->toc;
internal_a.o_toc = toc;
internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
diff --git a/bfd/coffswap.h b/bfd/coffswap.h
index b97b66c..63a0026 100644
--- a/bfd/coffswap.h
+++ b/bfd/coffswap.h
@@ -695,9 +695,16 @@ coff_swap_aouthdr_out (bfd * abfd, void * in, void * out)
H_PUT_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
H_PUT_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
#endif
- memset (aouthdr_out->o_resv2, 0, sizeof aouthdr_out->o_resv2);
+ /* TODO: set o_*psize dynamically */
+ H_PUT_8 (abfd, 0, aouthdr_out->o_textpsize);
+ H_PUT_8 (abfd, 0, aouthdr_out->o_datapsize);
+ H_PUT_8 (abfd, 0, aouthdr_out->o_stackpsize);
+ H_PUT_8 (abfd, aouthdr_in->o_flags, aouthdr_out->o_flags);
+ H_PUT_16 (abfd, aouthdr_in->o_sntdata, aouthdr_out->o_sntdata);
+ H_PUT_16 (abfd, aouthdr_in->o_sntbss, aouthdr_out->o_sntbss);
+ H_PUT_32 (abfd, 0, aouthdr_out->o_debugger);
#ifdef XCOFF64
- memset (aouthdr_out->o_debugger, 0, sizeof aouthdr_out->o_debugger);
+ H_PUT_16 (abfd, aouthdr_in->o_x64flags, aouthdr_out->o_x64flags);
memset (aouthdr_out->o_resv3, 0, sizeof aouthdr_out->o_resv3);
#endif
#endif
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 62b6bf8..9cb079e 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1564,6 +1564,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_PPC_TLS",
"BFD_RELOC_PPC_TLSGD",
"BFD_RELOC_PPC_TLSLD",
+ "BFD_RELOC_PPC_TLSLE",
+ "BFD_RELOC_PPC_TLSIE",
+ "BFD_RELOC_PPC_TLSM",
+ "BFD_RELOC_PPC_TLSML",
"BFD_RELOC_PPC_DTPMOD",
"BFD_RELOC_PPC_TPREL16",
"BFD_RELOC_PPC_TPREL16_LO",
@@ -1591,6 +1595,12 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_PPC_GOT_DTPREL16_LO",
"BFD_RELOC_PPC_GOT_DTPREL16_HI",
"BFD_RELOC_PPC_GOT_DTPREL16_HA",
+ "BFD_RELOC_PPC64_TLSGD",
+ "BFD_RELOC_PPC64_TLSLD",
+ "BFD_RELOC_PPC64_TLSLE",
+ "BFD_RELOC_PPC64_TLSIE",
+ "BFD_RELOC_PPC64_TLSM",
+ "BFD_RELOC_PPC64_TLSML",
"BFD_RELOC_PPC64_TPREL16_DS",
"BFD_RELOC_PPC64_TPREL16_LO_DS",
"BFD_RELOC_PPC64_TPREL16_HIGH",
diff --git a/bfd/libxcoff.h b/bfd/libxcoff.h
index 229e47c..bffdee2 100644
--- a/bfd/libxcoff.h
+++ b/bfd/libxcoff.h
@@ -234,6 +234,7 @@ extern xcoff_reloc_function xcoff_reloc_type_rel;
extern xcoff_reloc_function xcoff_reloc_type_toc;
extern xcoff_reloc_function xcoff_reloc_type_ba;
extern xcoff_reloc_function xcoff_reloc_type_crel;
+extern xcoff_reloc_function xcoff_reloc_type_tls;
/* Structure to describe dwarf sections.
Useful to convert from XCOFF section name to flag and vice-versa.
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 6864521..6fae177 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2944,6 +2944,14 @@ ENUMX
ENUMX
BFD_RELOC_PPC_TLSLD
ENUMX
+ BFD_RELOC_PPC_TLSLE
+ENUMX
+ BFD_RELOC_PPC_TLSIE
+ENUMX
+ BFD_RELOC_PPC_TLSM
+ENUMX
+ BFD_RELOC_PPC_TLSML
+ENUMX
BFD_RELOC_PPC_DTPMOD
ENUMX
BFD_RELOC_PPC_TPREL16
@@ -2998,6 +3006,18 @@ ENUMX
ENUMX
BFD_RELOC_PPC_GOT_DTPREL16_HA
ENUMX
+ BFD_RELOC_PPC64_TLSGD
+ENUMX
+ BFD_RELOC_PPC64_TLSLD
+ENUMX
+ BFD_RELOC_PPC64_TLSLE
+ENUMX
+ BFD_RELOC_PPC64_TLSIE
+ENUMX
+ BFD_RELOC_PPC64_TLSM
+ENUMX
+ BFD_RELOC_PPC64_TLSML
+ENUMX
BFD_RELOC_PPC64_TPREL16_DS
ENUMX
BFD_RELOC_PPC64_TPREL16_LO_DS
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index f0d6c8d..f0dd0e9 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -1814,6 +1814,12 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
csect = bfd_make_section_anyway_with_flags (abfd, ".td",
SEC_ALLOC);
}
+ else if (aux.x_csect.x_smclas == XMC_UL)
+ {
+ /* This is a thread-local unitialized csect. */
+ csect = bfd_make_section_anyway_with_flags (abfd, ".tbss",
+ SEC_ALLOC | SEC_THREAD_LOCAL);
+ }
else
csect = bfd_make_section_anyway_with_flags (abfd, ".bss",
SEC_ALLOC);
@@ -2697,6 +2703,14 @@ xcoff_need_ldrel_p (struct bfd_link_info *info, struct internal_reloc *rel,
return FALSE;
}
return TRUE;
+
+ case R_TLS:
+ case R_TLS_LE:
+ case R_TLS_IE:
+ case R_TLS_LD:
+ case R_TLSM:
+ case R_TLSML:
+ return TRUE;
}
}
@@ -4060,6 +4074,10 @@ xcoff_create_ldrel (bfd *output_bfd, struct xcoff_final_link_info *flinfo,
ldrel.l_symndx = 1;
else if (strcmp (secname, ".bss") == 0)
ldrel.l_symndx = 2;
+ else if (strcmp (secname, ".tdata") == 0)
+ ldrel.l_symndx = -1;
+ else if (strcmp (secname, ".tbss") == 0)
+ ldrel.l_symndx = -2;
else
{
_bfd_error_handler