diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 29 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 10 | ||||
-rw-r--r-- | bfd/coff-rs6000.c | 217 | ||||
-rw-r--r-- | bfd/coff64-rs6000.c | 109 | ||||
-rw-r--r-- | bfd/coffcode.h | 67 | ||||
-rw-r--r-- | bfd/coffswap.h | 11 | ||||
-rw-r--r-- | bfd/libbfd.h | 10 | ||||
-rw-r--r-- | bfd/libxcoff.h | 1 | ||||
-rw-r--r-- | bfd/reloc.c | 20 | ||||
-rw-r--r-- | bfd/xcofflink.c | 18 |
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 |