diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 119 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 54 | ||||
-rw-r--r-- | bfd/elf32-tilepro.c | 550 | ||||
-rw-r--r-- | bfd/elfxx-tilegx.c | 843 | ||||
-rw-r--r-- | bfd/libbfd.h | 54 | ||||
-rw-r--r-- | bfd/reloc.c | 96 |
6 files changed, 1339 insertions, 377 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 2af9699..982c9a2 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,4 +1,123 @@ 2012-02-25 Walter Lee <walt@tilera.com> + * reloc.c: Add BFD_RELOC_TILEPRO_TLS_GD_CALL, + BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD, + BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD, + BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD, + BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD, + BFD_RELOC_TILEPRO_TLS_IE_LOAD, BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE, + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE, + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO, + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO, + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI, + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI, + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA, + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA, + BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE, + BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE, + BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE, + BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE, + BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE, + BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE, + BFD_RELOC_TILEGX_TLS_GD_CALL, BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD, + BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD, + BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD, + BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD, BFD_RELOC_TILEGX_TLS_IE_LOAD, + BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD, + BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD, + BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD, BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD. + Delete BFD_RELOC_TILEGX_IMM16_X0_HW1_GOT, + BFD_RELOC_TILEGX_IMM16_X1_HW1_GOT, + BFD_RELOC_TILEGX_IMM16_X0_HW2_GOT, + BFD_RELOC_TILEGX_IMM16_X1_HW2_GOT, + BFD_RELOC_TILEGX_IMM16_X0_HW3_GOT, + BFD_RELOC_TILEGX_IMM16_X1_HW3_GOT, + BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_GOT, + BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_GOT, + BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD, + BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD, + BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD, + BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD, + BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD, + BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD, + BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD, + BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD, + BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE, + BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE, + BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE, + BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE, + BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE, + BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE, + BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE, + BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE. + * elf32-tilepro.c (tilepro_elf_howto_table): Update tilepro + relocations. + (tilepro_reloc_map): Ditto. + (tilepro_info_to_howto_rela): Ditto. + (reloc_to_create_func): Ditto. + (tilepro_tls_translate_to_le): New. + (tilepro_tls_translate_to_ie): New. + (tilepro_elf_tls_transition): New. + (tilepro_elf_check_relocs): Handle new tls relocations. + (tilepro_elf_gc_sweep_hook): Ditto. + (allocate_dynrelocs): Ditto. + (tilepro_elf_relocate_section): Ditto. + (tilepro_replace_insn): New. + (insn_mask_X1): New. + (insn_mask_X0_no_dest_no_srca): New + (insn_mask_X1_no_dest_no_srca): New + (insn_mask_Y0_no_dest_no_srca): New + (insn_mask_Y1_no_dest_no_srca): New + (srca_mask_X0): New + (srca_mask_X1): New + (insn_tls_le_move_X1): New + (insn_tls_le_move_zero_X0X1): New + (insn_tls_ie_lw_X1): New + (insn_tls_ie_add_X0X1): New + (insn_tls_ie_add_Y0Y1): New + (insn_tls_gd_add_X0X1): New + (insn_tls_gd_add_Y0Y1): New + * elfxx-tilegx.c (tilegx_elf_howto_table): Update tilegx + relocations. + (tilegx_reloc_map): Ditto. + (tilegx_info_to_howto_rela): Ditto. + (reloc_to_create_func): Ditto. + (tilegx_elf_link_hash_table): New field disable_le_transition. + (tilegx_tls_translate_to_le): New. + (tilegx_tls_translate_to_ie): New. + (tilegx_elf_tls_transition): New. + (tilegx_elf_check_relocs): Handle new tls relocations. + (tilegx_elf_gc_sweep_hook): Ditto. + (allocate_dynrelocs): Ditto. + (tilegx_elf_relocate_section): Ditto. + (tilegx_copy_bits): New. + (tilegx_replace_insn): New. + (insn_mask_X1): New. + (insn_mask_X0_no_dest_no_srca): New. + (insn_mask_X1_no_dest_no_srca): New. + (insn_mask_Y0_no_dest_no_srca): New. + (insn_mask_Y1_no_dest_no_srca): New. + (insn_mask_X0_no_operand): New. + (insn_mask_X1_no_operand): New. + (insn_mask_Y0_no_operand): New. + (insn_mask_Y1_no_operand): New. + (insn_tls_ie_ld_X1): New. + (insn_tls_ie_ld4s_X1): New. + (insn_tls_ie_add_X0X1): New. + (insn_tls_ie_add_Y0Y1): New. + (insn_tls_ie_addx_X0X1): New. + (insn_tls_ie_addx_Y0Y1): New. + (insn_tls_gd_add_X0X1): New. + (insn_tls_gd_add_Y0Y1): New. + (insn_move_X0X1): New. + (insn_move_Y0Y1): New. + (insn_add_X0X1): New. + (insn_add_Y0Y1): New. + (insn_addx_X0X1): New. + (insn_addx_Y0Y1): New. + * libbfd.h: Regenerate. + * bfd-in2.h: Regenerate. + +2012-02-25 Walter Lee <walt@tilera.com> * config.bfd (tilegx-*-*): rename little endian vector; add big endian vector. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 4a92e47..9c77fed 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -4959,6 +4959,12 @@ the dynamic object into the runtime process image. */ BFD_RELOC_TILEPRO_SHAMT_X1, BFD_RELOC_TILEPRO_SHAMT_Y0, BFD_RELOC_TILEPRO_SHAMT_Y1, + BFD_RELOC_TILEPRO_TLS_GD_CALL, + BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD, + BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD, + BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD, + BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD, + BFD_RELOC_TILEPRO_TLS_IE_LOAD, BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD, BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD, BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO, @@ -4978,6 +4984,14 @@ the dynamic object into the runtime process image. */ BFD_RELOC_TILEPRO_TLS_DTPMOD32, BFD_RELOC_TILEPRO_TLS_DTPOFF32, BFD_RELOC_TILEPRO_TLS_TPOFF32, + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE, + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE, + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO, + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO, + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI, + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI, + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA, + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA, /* Tilera TILE-Gx Relocations. */ BFD_RELOC_TILEGX_HW0, @@ -5037,52 +5051,44 @@ the dynamic object into the runtime process image. */ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL, BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT, BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW1_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW1_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW2_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW2_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW3_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW3_GOT, BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT, BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT, BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT, BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_GOT, BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD, BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD, + BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE, + BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE, + BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE, + BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE, + BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE, + BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE, BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD, BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD, BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD, BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD, BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE, BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE, BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE, BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE, BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE, BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE, BFD_RELOC_TILEGX_TLS_DTPMOD64, BFD_RELOC_TILEGX_TLS_DTPOFF64, BFD_RELOC_TILEGX_TLS_TPOFF64, BFD_RELOC_TILEGX_TLS_DTPMOD32, BFD_RELOC_TILEGX_TLS_DTPOFF32, BFD_RELOC_TILEGX_TLS_TPOFF32, + BFD_RELOC_TILEGX_TLS_GD_CALL, + BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD, + BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD, + BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD, + BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD, + BFD_RELOC_TILEGX_TLS_IE_LOAD, + BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD, + BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD, + BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD, + BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD, /* Adapteva EPIPHANY - 8 bit signed pc-relative displacement */ BFD_RELOC_EPIPHANY_SIMM8, diff --git a/bfd/elf32-tilepro.c b/bfd/elf32-tilepro.c index 7b08aff..48a99aa 100644 --- a/bfd/elf32-tilepro.c +++ b/bfd/elf32-tilepro.c @@ -380,12 +380,26 @@ static reloc_howto_type tilepro_elf_howto_table [] = EMPTY_HOWTO (57), EMPTY_HOWTO (58), EMPTY_HOWTO (59), - EMPTY_HOWTO (60), - EMPTY_HOWTO (61), - EMPTY_HOWTO (62), - EMPTY_HOWTO (63), - EMPTY_HOWTO (64), - EMPTY_HOWTO (65), + + HOWTO (R_TILEPRO_TLS_GD_CALL, /* type */ + TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 29, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_TILEPRO_TLS_GD_CALL", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + -1, /* dst_mask */ + TRUE), /* pcrel_offset */ + + TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_X0_TLS_GD_ADD, 0, 8), + TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_X1_TLS_GD_ADD, 0, 8), + TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_Y0_TLS_GD_ADD, 0, 8), + TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_Y1_TLS_GD_ADD, 0, 8), + TILEPRO_IMM_HOWTO(R_TILEPRO_TLS_IE_LOAD, 0, 8), /* Offsets into the GOT of TLS Descriptors. */ @@ -454,17 +468,12 @@ static reloc_howto_type tilepro_elf_howto_table [] = -1, /* dst_mask */ TRUE), /* pcrel_offset */ -#define TILEPRO_IMM16_HOWTO_TLS_IE(name, rshift) \ - HOWTO (name, rshift, 1, 16, FALSE, 0, \ - complain_overflow_dont, bfd_elf_generic_reloc, \ - #name, FALSE, 0, 0xffff, TRUE) - - TILEPRO_IMM16_HOWTO_TLS_IE (R_TILEPRO_IMM16_X0_TLS_IE_LO, 0), - TILEPRO_IMM16_HOWTO_TLS_IE (R_TILEPRO_IMM16_X1_TLS_IE_LO, 0), - TILEPRO_IMM16_HOWTO_TLS_IE (R_TILEPRO_IMM16_X0_TLS_IE_HI, 16), - TILEPRO_IMM16_HOWTO_TLS_IE (R_TILEPRO_IMM16_X1_TLS_IE_HI, 16), - TILEPRO_IMM16_HOWTO_TLS_IE (R_TILEPRO_IMM16_X0_TLS_IE_HA, 16), - TILEPRO_IMM16_HOWTO_TLS_IE (R_TILEPRO_IMM16_X1_TLS_IE_HA, 16), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_IE_LO, 0), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_IE_LO, 0), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_IE_HI, 16), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_IE_HI, 16), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_IE_HA, 16), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_IE_HA, 16), /* These are common with the Solaris TLS implementation. */ HOWTO(R_TILEPRO_TLS_DTPMOD32, 0, 0, 0, FALSE, 0, complain_overflow_dont, @@ -475,8 +484,42 @@ static reloc_howto_type tilepro_elf_howto_table [] = FALSE, 0, 0xFFFFFFFF, TRUE), HOWTO(R_TILEPRO_TLS_TPOFF32, 0, 0, 0, FALSE, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_TILEPRO_TLS_TPOFF32", - FALSE, 0, 0, TRUE) + FALSE, 0, 0, TRUE), + HOWTO (R_TILEPRO_IMM16_X0_TLS_LE,/* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_TILEPRO_IMM16_X0_TLS_LE",/* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + -1, /* dst_mask */ + TRUE), /* pcrel_offset */ + + HOWTO (R_TILEPRO_IMM16_X1_TLS_LE,/* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_TILEPRO_IMM16_X1_TLS_LE",/* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + -1, /* dst_mask */ + TRUE), /* pcrel_offset */ + + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_LE_LO, 0), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_LE_LO, 0), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_LE_HI, 16), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_LE_HI, 16), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_LE_HA, 16), + TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_LE_HA, 16), }; static reloc_howto_type tilepro_elf_howto_table2 [] = @@ -590,6 +633,13 @@ static const reloc_map tilepro_reloc_map [] = TH_REMAP (BFD_RELOC_TILEPRO_SHAMT_Y0, R_TILEPRO_SHAMT_Y0) TH_REMAP (BFD_RELOC_TILEPRO_SHAMT_Y1, R_TILEPRO_SHAMT_Y1) + TH_REMAP (BFD_RELOC_TILEPRO_TLS_GD_CALL, R_TILEPRO_TLS_GD_CALL) + TH_REMAP (BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD, R_TILEPRO_IMM8_X0_TLS_GD_ADD) + TH_REMAP (BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD, R_TILEPRO_IMM8_X1_TLS_GD_ADD) + TH_REMAP (BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD, R_TILEPRO_IMM8_Y0_TLS_GD_ADD) + TH_REMAP (BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD, R_TILEPRO_IMM8_Y1_TLS_GD_ADD) + TH_REMAP (BFD_RELOC_TILEPRO_TLS_IE_LOAD, R_TILEPRO_TLS_IE_LOAD) + TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD, R_TILEPRO_IMM16_X0_TLS_GD) TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD, R_TILEPRO_IMM16_X1_TLS_GD) TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO, R_TILEPRO_IMM16_X0_TLS_GD_LO) @@ -612,6 +662,15 @@ static const reloc_map tilepro_reloc_map [] = TH_REMAP (BFD_RELOC_TILEPRO_TLS_DTPOFF32, R_TILEPRO_TLS_DTPOFF32) TH_REMAP (BFD_RELOC_TILEPRO_TLS_TPOFF32, R_TILEPRO_TLS_TPOFF32) + TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE, R_TILEPRO_IMM16_X0_TLS_LE) + TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE, R_TILEPRO_IMM16_X1_TLS_LE) + TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO, R_TILEPRO_IMM16_X0_TLS_LE_LO) + TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO, R_TILEPRO_IMM16_X1_TLS_LE_LO) + TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI, R_TILEPRO_IMM16_X0_TLS_LE_HI) + TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI, R_TILEPRO_IMM16_X1_TLS_LE_HI) + TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA, R_TILEPRO_IMM16_X0_TLS_LE_HA) + TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA, R_TILEPRO_IMM16_X1_TLS_LE_HA) + #undef TH_REMAP { BFD_RELOC_VTABLE_INHERIT, R_TILEPRO_GNU_VTINHERIT, tilepro_elf_howto_table2 }, @@ -745,7 +804,7 @@ tilepro_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED, { unsigned int r_type = ELF32_R_TYPE (dst->r_info); - if (r_type <= (unsigned int) R_TILEPRO_TLS_TPOFF32) + if (r_type <= (unsigned int) R_TILEPRO_IMM16_X1_TLS_LE_HA) cache_ptr->howto = &tilepro_elf_howto_table [r_type]; else if (r_type - R_TILEPRO_GNU_VTINHERIT <= (unsigned int) R_TILEPRO_GNU_VTENTRY) @@ -845,7 +904,20 @@ static const tilepro_create_func reloc_to_create_func[] = create_Imm16_X0, create_Imm16_X1, create_Imm16_X0, - create_Imm16_X1 + create_Imm16_X1, + + NULL, + NULL, + NULL, + + create_Imm16_X0, + create_Imm16_X1, + create_Imm16_X0, + create_Imm16_X1, + create_Imm16_X0, + create_Imm16_X1, + create_Imm16_X0, + create_Imm16_X1, }; #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0]))) @@ -1288,6 +1360,99 @@ tilepro_elf_copy_indirect_symbol (struct bfd_link_info *info, _bfd_elf_link_hash_copy_indirect (info, dir, ind); } +static int +tilepro_tls_translate_to_le (int r_type) +{ + switch (r_type) + { + case R_TILEPRO_IMM16_X0_TLS_GD: + case R_TILEPRO_IMM16_X0_TLS_IE: + return R_TILEPRO_IMM16_X0_TLS_LE; + + case R_TILEPRO_IMM16_X1_TLS_GD: + case R_TILEPRO_IMM16_X1_TLS_IE: + return R_TILEPRO_IMM16_X1_TLS_LE; + + case R_TILEPRO_IMM16_X0_TLS_GD_LO: + case R_TILEPRO_IMM16_X0_TLS_IE_LO: + return R_TILEPRO_IMM16_X0_TLS_LE_LO; + + case R_TILEPRO_IMM16_X1_TLS_GD_LO: + case R_TILEPRO_IMM16_X1_TLS_IE_LO: + return R_TILEPRO_IMM16_X1_TLS_LE_LO; + + case R_TILEPRO_IMM16_X0_TLS_GD_HI: + case R_TILEPRO_IMM16_X0_TLS_IE_HI: + return R_TILEPRO_IMM16_X0_TLS_LE_HI; + + case R_TILEPRO_IMM16_X1_TLS_GD_HI: + case R_TILEPRO_IMM16_X1_TLS_IE_HI: + return R_TILEPRO_IMM16_X1_TLS_LE_HI; + + case R_TILEPRO_IMM16_X0_TLS_GD_HA: + case R_TILEPRO_IMM16_X0_TLS_IE_HA: + return R_TILEPRO_IMM16_X0_TLS_LE_HA; + + case R_TILEPRO_IMM16_X1_TLS_GD_HA: + case R_TILEPRO_IMM16_X1_TLS_IE_HA: + return R_TILEPRO_IMM16_X1_TLS_LE_HA; + } + return r_type; +} + +static int +tilepro_tls_translate_to_ie (int r_type) +{ + switch (r_type) + { + case R_TILEPRO_IMM16_X0_TLS_GD: + case R_TILEPRO_IMM16_X0_TLS_IE: + return R_TILEPRO_IMM16_X0_TLS_IE; + + case R_TILEPRO_IMM16_X1_TLS_GD: + case R_TILEPRO_IMM16_X1_TLS_IE: + return R_TILEPRO_IMM16_X1_TLS_IE; + + case R_TILEPRO_IMM16_X0_TLS_GD_LO: + case R_TILEPRO_IMM16_X0_TLS_IE_LO: + return R_TILEPRO_IMM16_X0_TLS_IE_LO; + + case R_TILEPRO_IMM16_X1_TLS_GD_LO: + case R_TILEPRO_IMM16_X1_TLS_IE_LO: + return R_TILEPRO_IMM16_X1_TLS_IE_LO; + + case R_TILEPRO_IMM16_X0_TLS_GD_HI: + case R_TILEPRO_IMM16_X0_TLS_IE_HI: + return R_TILEPRO_IMM16_X0_TLS_IE_HI; + + case R_TILEPRO_IMM16_X1_TLS_GD_HI: + case R_TILEPRO_IMM16_X1_TLS_IE_HI: + return R_TILEPRO_IMM16_X1_TLS_IE_HI; + + case R_TILEPRO_IMM16_X0_TLS_GD_HA: + case R_TILEPRO_IMM16_X0_TLS_IE_HA: + return R_TILEPRO_IMM16_X0_TLS_IE_HA; + + case R_TILEPRO_IMM16_X1_TLS_GD_HA: + case R_TILEPRO_IMM16_X1_TLS_IE_HA: + return R_TILEPRO_IMM16_X1_TLS_IE_HA; + } + return r_type; +} + +static int +tilepro_elf_tls_transition (struct bfd_link_info *info, int r_type, + int is_local) +{ + if (info->shared) + return r_type; + + if (is_local) + return tilepro_tls_translate_to_le (r_type); + else + return tilepro_tls_translate_to_ie (r_type); +} + /* Look through the relocs for a section during the first phase, and allocate space in the global offset table or procedure linkage table. */ @@ -1348,8 +1513,21 @@ tilepro_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, h = (struct elf_link_hash_entry *) h->root.u.i.link; } + r_type = tilepro_elf_tls_transition (info, r_type, h == NULL); switch (r_type) { + case R_TILEPRO_IMM16_X0_TLS_LE: + case R_TILEPRO_IMM16_X1_TLS_LE: + case R_TILEPRO_IMM16_X0_TLS_LE_LO: + case R_TILEPRO_IMM16_X1_TLS_LE_LO: + case R_TILEPRO_IMM16_X0_TLS_LE_HI: + case R_TILEPRO_IMM16_X1_TLS_LE_HI: + case R_TILEPRO_IMM16_X0_TLS_LE_HA: + case R_TILEPRO_IMM16_X1_TLS_LE_HA: + if (info->shared) + goto r_tilepro_plt32; + break; + case R_TILEPRO_IMM16_X0_TLS_GD: case R_TILEPRO_IMM16_X1_TLS_GD: case R_TILEPRO_IMM16_X0_TLS_GD_LO: @@ -1358,7 +1536,8 @@ tilepro_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_TILEPRO_IMM16_X1_TLS_GD_HI: case R_TILEPRO_IMM16_X0_TLS_GD_HA: case R_TILEPRO_IMM16_X1_TLS_GD_HA: - tls_type = GOT_TLS_GD; + BFD_ASSERT (info->shared); + tls_type = GOT_TLS_GD; goto have_got_reference; case R_TILEPRO_IMM16_X0_TLS_IE: @@ -1454,6 +1633,24 @@ tilepro_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, } break; + case R_TILEPRO_TLS_GD_CALL: + if (info->shared) + { + /* These are basically R_TILEPRO_JOFFLONG_X1_PLT relocs + against __tls_get_addr. */ + struct bfd_link_hash_entry *bh = NULL; + if (! _bfd_generic_link_add_one_symbol (info, abfd, + "__tls_get_addr", 0, + bfd_und_section_ptr, 0, + NULL, FALSE, FALSE, + &bh)) + return FALSE; + h = (struct elf_link_hash_entry *) bh; + } + else + break; + /* Fall through */ + case R_TILEPRO_JOFFLONG_X1_PLT: /* This symbol requires a procedure linkage table entry. We actually build the entry in adjust_dynamic_symbol, @@ -1523,15 +1720,14 @@ tilepro_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_TILEPRO_SHAMT_Y0: case R_TILEPRO_SHAMT_Y1: if (h != NULL) - { h->non_got_ref = 1; - if (!info->shared) - { - /* We may need a .plt entry if the function this reloc - refers to is in a shared lib. */ - h->plt.refcount += 1; - } + r_tilepro_plt32: + if (h != NULL && !info->shared) + { + /* We may need a .plt entry if the function this reloc + refers to is in a shared lib. */ + h->plt.refcount += 1; } /* If we are creating a shared library, and this is a reloc @@ -1725,6 +1921,7 @@ tilepro_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, } r_type = ELF32_R_TYPE (rel->r_info); + r_type = tilepro_elf_tls_transition (info, r_type, h != NULL); switch (r_type) { case R_TILEPRO_IMM16_X0_GOT: @@ -1758,7 +1955,8 @@ tilepro_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, } else { - if (local_got_refcounts[r_symndx] > 0) + if (local_got_refcounts && + local_got_refcounts[r_symndx] > 0) local_got_refcounts[r_symndx]--; } break; @@ -2040,7 +2238,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) h->needs_plt = 0; } - if (h->got.refcount > 0) + /* If a TLS_IE symbol is now local to the binary, make it a TLS_LE + requiring no TLS entry. */ + if (h->got.refcount > 0 + && !info->shared + && h->dynindx == -1 + && tilepro_elf_hash_entry(h)->tls_type == GOT_TLS_IE) + h->got.offset = (bfd_vma) -1; + else if (h->got.refcount > 0) { asection *s; bfd_boolean dyn; @@ -2467,6 +2672,87 @@ tpoff (struct bfd_link_info *info, bfd_vma address) return (address - htab->tls_sec->vma); } +/* Replace the MASK bits in ADDR with those in INSN, for the next + TILEPRO_BUNDLE_SIZE_IN_BYTES bytes. */ + +static void +tilepro_replace_insn (bfd_byte *addr, const bfd_byte *mask, + const bfd_byte *insn) +{ + int i; + for (i = 0; i < TILEPRO_BUNDLE_SIZE_IN_BYTES; i++) + { + addr[i] = (addr[i] & ~mask[i]) | (insn[i] & mask[i]); + } +} + +/* Mask to extract the bits corresponding to an instruction in a + specific pipe of a bundle. */ +static const bfd_byte insn_mask_X1[] = { + 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x7f +}; + +/* Mask to extract the bits corresponding to an instruction in a + specific pipe of a bundle, minus the destination operand and the + first source operand. */ +static const bfd_byte insn_mask_X0_no_dest_no_srca[] = { + 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00 +}; + +static const bfd_byte insn_mask_X1_no_dest_no_srca[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f +}; + +static const bfd_byte insn_mask_Y0_no_dest_no_srca[] = { + 0x00, 0xf0, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00 +}; + +static const bfd_byte insn_mask_Y1_no_dest_no_srca[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x78 +}; + +/* Mask to extract the first source operand of an instruction. */ +static const bfd_byte srca_mask_X0[] = { + 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const bfd_byte srca_mask_X1[] = { + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00 +}; + +/* Various instructions synthesized to support tls references. */ + +/* move r0, r0 in the X1 pipe, used for tls le. */ +static const bfd_byte insn_tls_le_move_X1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x33, 0x08 +}; + +/* move r0, zero in the X0 and X1 pipe, used for tls le. */ +static const bfd_byte insn_tls_le_move_zero_X0X1[] = { + 0xc0, 0xff, 0xcf, 0x00, 0xe0, 0xff, 0x33, 0x08 +}; + +/* lw r0, r0 in the X1 pipe, used for tls ie. */ +static const bfd_byte insn_tls_ie_lw_X1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0b, 0x40 +}; + +/* add r0, r0, tp in various pipes, used for tls ie. */ +static const bfd_byte insn_tls_ie_add_X0X1[] = { + 0x00, 0x50, 0x0f, 0x00, 0x00, 0xa8, 0x07, 0x08 +}; +static const bfd_byte insn_tls_ie_add_Y0Y1[] = { + 0x00, 0x50, 0x03, 0x08, 0x00, 0xa8, 0x01, 0x8c +}; + +/* move r0, r0 in various pipes, used for tls gd. */ +static const bfd_byte insn_tls_gd_add_X0X1[] = { + 0x00, 0xf0, 0xcf, 0x00, 0x00, 0xf8, 0x33, 0x08 +}; +static const bfd_byte insn_tls_gd_add_Y0Y1[] = { + 0x00, 0xf0, 0x0b, 0x18, 0x00, 0xf8, 0x05, 0x9c +}; + /* Relocate an TILEPRO ELF section. The RELOCATE_SECTION function is called by the new ELF backend linker @@ -2531,6 +2817,7 @@ tilepro_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, for (; rel < relend; rel++) { int r_type, tls_type; + bfd_boolean is_tls_iele, is_tls_le; reloc_howto_type *howto; unsigned long r_symndx; struct elf_link_hash_entry *h; @@ -2613,6 +2900,118 @@ tilepro_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, switch (r_type) { + case R_TILEPRO_TLS_GD_CALL: + case R_TILEPRO_IMM8_X0_TLS_GD_ADD: + case R_TILEPRO_IMM8_Y0_TLS_GD_ADD: + case R_TILEPRO_IMM8_X1_TLS_GD_ADD: + case R_TILEPRO_IMM8_Y1_TLS_GD_ADD: + case R_TILEPRO_IMM16_X0_TLS_GD_HA: + case R_TILEPRO_IMM16_X1_TLS_GD_HA: + case R_TILEPRO_IMM16_X0_TLS_IE_HA: + case R_TILEPRO_IMM16_X1_TLS_IE_HA: + tls_type = GOT_UNKNOWN; + if (h == NULL && local_got_offsets) + tls_type = + _bfd_tilepro_elf_local_got_tls_type (input_bfd) [r_symndx]; + else if (h != NULL) + tls_type = tilepro_elf_hash_entry(h)->tls_type; + + is_tls_iele = (! info->shared || tls_type == GOT_TLS_IE); + is_tls_le = is_tls_iele && (!info->shared + && (h == NULL || h->dynindx == -1)); + + if (r_type == R_TILEPRO_TLS_GD_CALL) + { + if (is_tls_le) + { + /* GD -> LE */ + tilepro_replace_insn (contents + rel->r_offset, + insn_mask_X1, insn_tls_le_move_X1); + continue; + } + else if (is_tls_iele) + { + /* GD -> IE */ + tilepro_replace_insn (contents + rel->r_offset, + insn_mask_X1, insn_tls_ie_lw_X1); + continue; + } + + /* GD -> GD */ + h = (struct elf_link_hash_entry *) + bfd_link_hash_lookup (info->hash, "__tls_get_addr", FALSE, + FALSE, TRUE); + BFD_ASSERT (h != NULL); + r_type = R_TILEPRO_JOFFLONG_X1_PLT; + howto = tilepro_elf_howto_table + r_type; + } + else if (r_type == R_TILEPRO_IMM16_X0_TLS_GD_HA + || r_type == R_TILEPRO_IMM16_X0_TLS_IE_HA) + { + if (is_tls_le) + tilepro_replace_insn (contents + rel->r_offset, srca_mask_X0, + insn_tls_le_move_zero_X0X1); + } + else if (r_type == R_TILEPRO_IMM16_X1_TLS_GD_HA + || r_type == R_TILEPRO_IMM16_X1_TLS_IE_HA) + { + if (is_tls_le) + tilepro_replace_insn (contents + rel->r_offset, srca_mask_X1, + insn_tls_le_move_zero_X0X1); + } + else + { + const bfd_byte *mask = NULL; + const bfd_byte *add_insn = NULL; + + switch (r_type) + { + case R_TILEPRO_IMM8_X0_TLS_GD_ADD: + add_insn = is_tls_iele ? insn_tls_ie_add_X0X1 + : insn_tls_gd_add_X0X1; + mask = insn_mask_X0_no_dest_no_srca; + break; + case R_TILEPRO_IMM8_X1_TLS_GD_ADD: + add_insn = is_tls_iele ? insn_tls_ie_add_X0X1 + : insn_tls_gd_add_X0X1; + mask = insn_mask_X1_no_dest_no_srca; + break; + case R_TILEPRO_IMM8_Y0_TLS_GD_ADD: + add_insn = is_tls_iele ? insn_tls_ie_add_Y0Y1 + : insn_tls_gd_add_Y0Y1; + mask = insn_mask_Y0_no_dest_no_srca; + break; + case R_TILEPRO_IMM8_Y1_TLS_GD_ADD: + add_insn = is_tls_iele ? insn_tls_ie_add_Y0Y1 + : insn_tls_gd_add_Y0Y1; + mask = insn_mask_Y1_no_dest_no_srca; + break; + } + + tilepro_replace_insn (contents + rel->r_offset, mask, add_insn); + + continue; + } + break; + case R_TILEPRO_TLS_IE_LOAD: + if (!info->shared && (h == NULL || h->dynindx == -1)) + /* IE -> LE */ + tilepro_replace_insn (contents + rel->r_offset, + insn_mask_X1_no_dest_no_srca, + insn_tls_le_move_X1); + else + /* IE -> IE */ + tilepro_replace_insn (contents + rel->r_offset, + insn_mask_X1_no_dest_no_srca, + insn_tls_ie_lw_X1); + continue; + break; + default: + break; + } + + switch (r_type) + { case R_TILEPRO_IMM16_X0_GOT: case R_TILEPRO_IMM16_X1_GOT: case R_TILEPRO_IMM16_X0_GOT_LO: @@ -2908,6 +3307,45 @@ tilepro_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } break; + case R_TILEPRO_IMM16_X0_TLS_LE: + case R_TILEPRO_IMM16_X1_TLS_LE: + case R_TILEPRO_IMM16_X0_TLS_LE_LO: + case R_TILEPRO_IMM16_X1_TLS_LE_LO: + case R_TILEPRO_IMM16_X0_TLS_LE_HI: + case R_TILEPRO_IMM16_X1_TLS_LE_HI: + case R_TILEPRO_IMM16_X0_TLS_LE_HA: + case R_TILEPRO_IMM16_X1_TLS_LE_HA: + if (info->shared) + { + Elf_Internal_Rela outrel; + bfd_boolean skip; + + BFD_ASSERT (sreloc != NULL); + skip = FALSE; + outrel.r_offset = + _bfd_elf_section_offset (output_bfd, info, input_section, + rel->r_offset); + if (outrel.r_offset == (bfd_vma) -1) + skip = TRUE; + else if (outrel.r_offset == (bfd_vma) -2) + skip = TRUE; + outrel.r_offset += (input_section->output_section->vma + + input_section->output_offset); + if (skip) + memset (&outrel, 0, sizeof outrel); + else + { + outrel.r_info = ELF32_R_INFO (0, r_type); + outrel.r_addend = relocation - dtpoff_base (info) + + rel->r_addend; + } + + tilepro_elf_append_rela_32 (output_bfd, sreloc, &outrel); + continue; + } + relocation = tpoff (info, relocation); + break; + case R_TILEPRO_IMM16_X0_TLS_GD: case R_TILEPRO_IMM16_X1_TLS_GD: case R_TILEPRO_IMM16_X0_TLS_GD_LO: @@ -2916,9 +3354,6 @@ tilepro_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, case R_TILEPRO_IMM16_X1_TLS_GD_HI: case R_TILEPRO_IMM16_X0_TLS_GD_HA: case R_TILEPRO_IMM16_X1_TLS_GD_HA: - tls_type = GOT_TLS_GD; - goto have_tls_reference; - case R_TILEPRO_IMM16_X0_TLS_IE: case R_TILEPRO_IMM16_X1_TLS_IE: case R_TILEPRO_IMM16_X0_TLS_IE_LO: @@ -2927,45 +3362,32 @@ tilepro_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, case R_TILEPRO_IMM16_X1_TLS_IE_HI: case R_TILEPRO_IMM16_X0_TLS_IE_HA: case R_TILEPRO_IMM16_X1_TLS_IE_HA: - tls_type = GOT_TLS_IE; - /* Fall through. */ - - have_tls_reference: + r_type = tilepro_elf_tls_transition (info, r_type, h == NULL); + tls_type = GOT_UNKNOWN; if (h == NULL && local_got_offsets) tls_type = _bfd_tilepro_elf_local_got_tls_type (input_bfd) [r_symndx]; else if (h != NULL) { tls_type = tilepro_elf_hash_entry(h)->tls_type; + if (!info->shared && h->dynindx == -1 && tls_type == GOT_TLS_IE) + r_type = tilepro_tls_translate_to_le (r_type); } if (tls_type == GOT_TLS_IE) - switch (r_type) - { - case R_TILEPRO_IMM16_X0_TLS_GD: - r_type = R_TILEPRO_IMM16_X0_TLS_IE; - break; - case R_TILEPRO_IMM16_X1_TLS_GD: - r_type = R_TILEPRO_IMM16_X1_TLS_IE; - break; - case R_TILEPRO_IMM16_X0_TLS_GD_LO: - r_type = R_TILEPRO_IMM16_X0_TLS_IE_LO; - break; - case R_TILEPRO_IMM16_X1_TLS_GD_LO: - r_type = R_TILEPRO_IMM16_X1_TLS_IE_LO; - break; - case R_TILEPRO_IMM16_X0_TLS_GD_HI: - r_type = R_TILEPRO_IMM16_X0_TLS_IE_HI; - break; - case R_TILEPRO_IMM16_X1_TLS_GD_HI: - r_type = R_TILEPRO_IMM16_X1_TLS_IE_HI; - break; - case R_TILEPRO_IMM16_X0_TLS_GD_HA: - r_type = R_TILEPRO_IMM16_X0_TLS_IE_HA; - break; - case R_TILEPRO_IMM16_X1_TLS_GD_HA: - r_type = R_TILEPRO_IMM16_X1_TLS_IE_HA; - break; - } + r_type = tilepro_tls_translate_to_ie (r_type); + + if (r_type == R_TILEPRO_IMM16_X0_TLS_LE + || r_type == R_TILEPRO_IMM16_X1_TLS_LE + || r_type == R_TILEPRO_IMM16_X0_TLS_LE_LO + || r_type == R_TILEPRO_IMM16_X1_TLS_LE_LO + || r_type == R_TILEPRO_IMM16_X0_TLS_LE_HI + || r_type == R_TILEPRO_IMM16_X1_TLS_LE_HI + || r_type == R_TILEPRO_IMM16_X0_TLS_LE_HA + || r_type == R_TILEPRO_IMM16_X1_TLS_LE_HA) + { + relocation = tpoff (info, relocation); + break; + } if (h != NULL) { diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c index 2aaa3d3..27e5179 100644 --- a/bfd/elfxx-tilegx.c +++ b/bfd/elfxx-tilegx.c @@ -490,35 +490,38 @@ static reloc_howto_type tilegx_elf_howto_table [] = TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_GOT, 0), TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_GOT, 0), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW1_GOT, 16), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW1_GOT, 16), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW2_GOT, 32), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW2_GOT, 32), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW3_GOT, 48), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW3_GOT, 48), + /* These relocs are currently not defined. */ + EMPTY_HOWTO (66), + EMPTY_HOWTO (67), + EMPTY_HOWTO (68), + EMPTY_HOWTO (69), + EMPTY_HOWTO (70), + EMPTY_HOWTO (71), TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST_GOT, 0), TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST_GOT, 0), TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST_GOT, 16), TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST_GOT, 16), - TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW2_LAST_GOT, 32), - TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW2_LAST_GOT, 32), + /* These relocs are currently not defined. */ + EMPTY_HOWTO (76), + EMPTY_HOWTO (77), TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_TLS_GD, 0), TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_TLS_GD, 0), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW1_TLS_GD, 16), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW1_TLS_GD, 16), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW2_TLS_GD, 32), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW2_TLS_GD, 32), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW3_TLS_GD, 48), - TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW3_TLS_GD, 48), + + TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_TLS_LE, 0), + TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_TLS_LE, 0), + TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE, 0), + TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE, 0), + TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE, 16), + TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE, 16), TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD, 0), TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD, 0), TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD, 16), TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD, 16), - TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW2_LAST_TLS_GD, 32), - TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW2_LAST_TLS_GD, 32), + EMPTY_HOWTO (90), + EMPTY_HOWTO (91), #define TILEGX_IMM16_HOWTO_TLS_IE(name, rshift) \ HOWTO (name, rshift, 1, 16, FALSE, 0, \ @@ -527,12 +530,12 @@ static reloc_howto_type tilegx_elf_howto_table [] = TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X0_HW0_TLS_IE, 0), TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X1_HW0_TLS_IE, 0), - TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X0_HW1_TLS_IE, 16), - TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X1_HW1_TLS_IE, 16), - TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X0_HW2_TLS_IE, 32), - TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X1_HW2_TLS_IE, 32), - TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X0_HW3_TLS_IE, 48), - TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X1_HW3_TLS_IE, 48), + EMPTY_HOWTO (94), + EMPTY_HOWTO (95), + EMPTY_HOWTO (96), + EMPTY_HOWTO (97), + EMPTY_HOWTO (98), + EMPTY_HOWTO (99), #define TILEGX_IMM16_HOWTO_LAST_TLS_IE(name, rshift) \ HOWTO (name, rshift, 1, 16, FALSE, 0, \ @@ -543,8 +546,8 @@ static reloc_howto_type tilegx_elf_howto_table [] = TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE, 0), TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE, 16), TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE, 16), - TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X0_HW2_LAST_TLS_IE, 32), - TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X1_HW2_LAST_TLS_IE, 32), + EMPTY_HOWTO (104), + EMPTY_HOWTO (105), HOWTO(R_TILEGX_TLS_DTPMOD64, 0, 0, 0, FALSE, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_TILEGX_TLS_DTPMOD64", @@ -564,7 +567,31 @@ static reloc_howto_type tilegx_elf_howto_table [] = FALSE, 0, -1, TRUE), HOWTO(R_TILEGX_TLS_TPOFF32, 0, 0, 0, FALSE, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_TILEGX_TLS_TPOFF32", - FALSE, 0, 0, TRUE) + FALSE, 0, 0, TRUE), + + HOWTO (R_TILEGX_TLS_GD_CALL, /* type */ + TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 27, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_TILEGX_TLS_GD_CALL", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + -1, /* dst_mask */ + TRUE), /* pcrel_offset */ + + TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X0_TLS_GD_ADD, 0, 8), + TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X1_TLS_GD_ADD, 0, 8), + TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y0_TLS_GD_ADD, 0, 8), + TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y1_TLS_GD_ADD, 0, 8), + TILEGX_IMM_HOWTO(R_TILEGX_TLS_IE_LOAD, 0, 8), + TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X0_TLS_ADD, 0, 8), + TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X1_TLS_ADD, 0, 8), + TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y0_TLS_ADD, 0, 8), + TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y1_TLS_ADD, 0, 8), }; static reloc_howto_type tilegx_elf_howto_table2 [] = @@ -686,46 +713,28 @@ static const reloc_map tilegx_reloc_map [] = SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST_PCREL) SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_GOT) SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_GOT) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_GOT) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_GOT) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_GOT) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_GOT) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW3_GOT) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW3_GOT) SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_GOT) SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_GOT) SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_GOT) SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_GOT) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_LAST_GOT) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST_GOT) SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_GD) SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_GD) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_TLS_GD) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_TLS_GD) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_TLS_GD) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_TLS_GD) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW3_TLS_GD) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW3_TLS_GD) + SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_LE) + SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_LE) + SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_TLS_LE) + SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_TLS_LE) + SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_TLS_LE) + SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_TLS_LE) SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_TLS_GD) SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_TLS_GD) SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_TLS_GD) SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_TLS_GD) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_LAST_TLS_GD) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST_TLS_GD) SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_IE) SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_IE) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_TLS_IE) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_TLS_IE) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_TLS_IE) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_TLS_IE) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW3_TLS_IE) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW3_TLS_IE) SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_TLS_IE) SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_TLS_IE) SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_TLS_IE) SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_TLS_IE) - SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_LAST_TLS_IE) - SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST_TLS_IE) SIMPLE_REMAP (TILEGX_TLS_DTPMOD64) SIMPLE_REMAP (TILEGX_TLS_DTPOFF64) @@ -735,6 +744,17 @@ static const reloc_map tilegx_reloc_map [] = SIMPLE_REMAP (TILEGX_TLS_DTPOFF32) SIMPLE_REMAP (TILEGX_TLS_TPOFF32) + SIMPLE_REMAP (TILEGX_TLS_GD_CALL) + SIMPLE_REMAP (TILEGX_IMM8_X0_TLS_GD_ADD) + SIMPLE_REMAP (TILEGX_IMM8_X1_TLS_GD_ADD) + SIMPLE_REMAP (TILEGX_IMM8_Y0_TLS_GD_ADD) + SIMPLE_REMAP (TILEGX_IMM8_Y1_TLS_GD_ADD) + SIMPLE_REMAP (TILEGX_TLS_IE_LOAD) + SIMPLE_REMAP (TILEGX_IMM8_X0_TLS_ADD) + SIMPLE_REMAP (TILEGX_IMM8_X1_TLS_ADD) + SIMPLE_REMAP (TILEGX_IMM8_Y0_TLS_ADD) + SIMPLE_REMAP (TILEGX_IMM8_Y1_TLS_ADD) + #undef SIMPLE_REMAP #undef TH_REMAP @@ -824,6 +844,10 @@ struct tilegx_elf_link_hash_table asection *sdynbss; asection *srelbss; + /* Whether LE transition has been disabled for some of the + sections. */ + bfd_boolean disable_le_transition; + /* Small local sym to section mapping cache. */ struct sym_cache sym_cache; }; @@ -920,7 +944,7 @@ tilegx_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, { unsigned int r_type = TILEGX_ELF_R_TYPE (dst->r_info); - if (r_type <= (unsigned int) R_TILEGX_TLS_TPOFF32) + if (r_type <= (unsigned int) R_TILEGX_IMM8_Y1_TLS_ADD) cache_ptr->howto = &tilegx_elf_howto_table [r_type]; else if (r_type - R_TILEGX_GNU_VTINHERIT <= (unsigned int) R_TILEGX_GNU_VTENTRY) @@ -1003,10 +1027,18 @@ static const tilegx_create_func reloc_to_create_func[] = create_Imm16_X1, create_Imm16_X0, create_Imm16_X1, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, create_Imm16_X0, create_Imm16_X1, create_Imm16_X0, create_Imm16_X1, + NULL, + NULL, create_Imm16_X0, create_Imm16_X1, create_Imm16_X0, @@ -1019,30 +1051,20 @@ static const tilegx_create_func reloc_to_create_func[] = create_Imm16_X1, create_Imm16_X0, create_Imm16_X1, + NULL, + NULL, create_Imm16_X0, create_Imm16_X1, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, create_Imm16_X0, create_Imm16_X1, create_Imm16_X0, create_Imm16_X1, - create_Imm16_X0, - create_Imm16_X1, - create_Imm16_X0, - create_Imm16_X1, - create_Imm16_X0, - create_Imm16_X1, - create_Imm16_X0, - create_Imm16_X1, - create_Imm16_X0, - create_Imm16_X1, - create_Imm16_X0, - create_Imm16_X1, - create_Imm16_X0, - create_Imm16_X1, - create_Imm16_X0, - create_Imm16_X1, - create_Imm16_X0, - create_Imm16_X1 }; static void @@ -1538,6 +1560,83 @@ tilegx_elf_copy_indirect_symbol (struct bfd_link_info *info, _bfd_elf_link_hash_copy_indirect (info, dir, ind); } +static int +tilegx_tls_translate_to_le (int r_type) +{ + switch (r_type) + { + case R_TILEGX_IMM16_X0_HW0_TLS_GD: + case R_TILEGX_IMM16_X0_HW0_TLS_IE: + return R_TILEGX_IMM16_X0_HW0_TLS_LE; + + case R_TILEGX_IMM16_X1_HW0_TLS_GD: + case R_TILEGX_IMM16_X1_HW0_TLS_IE: + return R_TILEGX_IMM16_X1_HW0_TLS_LE; + + case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: + case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: + return R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE; + + case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: + case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: + return R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE; + + case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: + case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: + return R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE; + + case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: + case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: + return R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE; + } + return r_type; +} + +static int +tilegx_tls_translate_to_ie (int r_type) +{ + switch (r_type) + { + case R_TILEGX_IMM16_X0_HW0_TLS_GD: + case R_TILEGX_IMM16_X0_HW0_TLS_IE: + return R_TILEGX_IMM16_X0_HW0_TLS_IE; + + case R_TILEGX_IMM16_X1_HW0_TLS_GD: + case R_TILEGX_IMM16_X1_HW0_TLS_IE: + return R_TILEGX_IMM16_X1_HW0_TLS_IE; + + case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: + case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: + return R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE; + + case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: + case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: + return R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE; + + case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: + case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: + return R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE; + + case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: + case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: + return R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE; + } + return r_type; +} + +static int +tilegx_elf_tls_transition (struct bfd_link_info *info, int r_type, + int is_local, bfd_boolean disable_le_transition) +{ + if (info->shared) + return r_type; + + if (is_local && !disable_le_transition) + return tilegx_tls_translate_to_le (r_type); + else + return tilegx_tls_translate_to_ie (r_type); +} + /* Look through the relocs for a section during the first phase, and allocate space in the global offset table or procedure linkage table. */ @@ -1553,6 +1652,7 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Rela *rel_end; asection *sreloc; int num_relocs; + bfd_boolean has_tls_gd_or_ie = FALSE, has_tls_add = FALSE; if (info->relocatable) return TRUE; @@ -1571,6 +1671,33 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, htab->elf.dynobj = abfd; rel_end = relocs + num_relocs; + + /* Check whether to do optimization to transform TLS GD/IE + referehces to TLS LE. We disable it if we're linking with old + TLS code sequences that do not support such optimization. Old + TLS code sequences have tls_gd_call/tls_ie_load relocations but + no tls_add relocations. */ + for (rel = relocs; rel < rel_end && !has_tls_add; rel++) + { + int r_type = TILEGX_ELF_R_TYPE (rel->r_info); + switch (r_type) + { + case R_TILEGX_TLS_GD_CALL: + case R_TILEGX_TLS_IE_LOAD: + has_tls_gd_or_ie = TRUE; + break; + case R_TILEGX_IMM8_X0_TLS_ADD: + case R_TILEGX_IMM8_Y0_TLS_ADD: + case R_TILEGX_IMM8_X1_TLS_ADD: + case R_TILEGX_IMM8_Y1_TLS_ADD: + has_tls_add = TRUE; + break; + } + } + + sec->sec_flg0 = (has_tls_gd_or_ie && !has_tls_add); + htab->disable_le_transition |= sec->sec_flg0; + for (rel = relocs; rel < rel_end; rel++) { unsigned int r_type; @@ -1598,39 +1725,36 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, h = (struct elf_link_hash_entry *) h->root.u.i.link; } + r_type = tilegx_elf_tls_transition (info, r_type, h == NULL, + sec->sec_flg0); switch (r_type) { + case R_TILEGX_IMM16_X0_HW0_TLS_LE: + case R_TILEGX_IMM16_X1_HW0_TLS_LE: + case R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: + case R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: + case R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: + case R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: + if (info->shared) + goto r_tilegx_plt32; + break; + case R_TILEGX_IMM16_X0_HW0_TLS_GD: case R_TILEGX_IMM16_X1_HW0_TLS_GD: - case R_TILEGX_IMM16_X0_HW1_TLS_GD: - case R_TILEGX_IMM16_X1_HW1_TLS_GD: - case R_TILEGX_IMM16_X0_HW2_TLS_GD: - case R_TILEGX_IMM16_X1_HW2_TLS_GD: - case R_TILEGX_IMM16_X0_HW3_TLS_GD: - case R_TILEGX_IMM16_X1_HW3_TLS_GD: case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: - case R_TILEGX_IMM16_X0_HW2_LAST_TLS_GD: - case R_TILEGX_IMM16_X1_HW2_LAST_TLS_GD: - tls_type = GOT_TLS_GD; + BFD_ASSERT (info->shared); + tls_type = GOT_TLS_GD; goto have_got_reference; case R_TILEGX_IMM16_X0_HW0_TLS_IE: case R_TILEGX_IMM16_X1_HW0_TLS_IE: - case R_TILEGX_IMM16_X0_HW1_TLS_IE: - case R_TILEGX_IMM16_X1_HW1_TLS_IE: - case R_TILEGX_IMM16_X0_HW2_TLS_IE: - case R_TILEGX_IMM16_X1_HW2_TLS_IE: - case R_TILEGX_IMM16_X0_HW3_TLS_IE: - case R_TILEGX_IMM16_X1_HW3_TLS_IE: case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: - case R_TILEGX_IMM16_X0_HW2_LAST_TLS_IE: - case R_TILEGX_IMM16_X1_HW2_LAST_TLS_IE: tls_type = GOT_TLS_IE; if (info->shared) info->flags |= DF_STATIC_TLS; @@ -1638,18 +1762,10 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_TILEGX_IMM16_X0_HW0_GOT: case R_TILEGX_IMM16_X1_HW0_GOT: - case R_TILEGX_IMM16_X0_HW1_GOT: - case R_TILEGX_IMM16_X1_HW1_GOT: - case R_TILEGX_IMM16_X0_HW2_GOT: - case R_TILEGX_IMM16_X1_HW2_GOT: - case R_TILEGX_IMM16_X0_HW3_GOT: - case R_TILEGX_IMM16_X1_HW3_GOT: case R_TILEGX_IMM16_X0_HW0_LAST_GOT: case R_TILEGX_IMM16_X1_HW0_LAST_GOT: case R_TILEGX_IMM16_X0_HW1_LAST_GOT: case R_TILEGX_IMM16_X1_HW1_LAST_GOT: - case R_TILEGX_IMM16_X0_HW2_LAST_GOT: - case R_TILEGX_IMM16_X1_HW2_LAST_GOT: tls_type = GOT_NORMAL; /* Fall Through */ @@ -1720,6 +1836,24 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, } break; + case R_TILEGX_TLS_GD_CALL: + if (info->shared) + { + /* These are basically R_TILEGX_JUMPOFF_X1_PLT relocs + against __tls_get_addr. */ + struct bfd_link_hash_entry *bh = NULL; + if (! _bfd_generic_link_add_one_symbol (info, abfd, + "__tls_get_addr", 0, + bfd_und_section_ptr, 0, + NULL, FALSE, FALSE, + &bh)) + return FALSE; + h = (struct elf_link_hash_entry *) bh; + } + else + break; + /* Fall through */ + case R_TILEGX_JUMPOFF_X1_PLT: /* This symbol requires a procedure linkage table entry. We actually build the entry in adjust_dynamic_symbol, @@ -1805,16 +1939,15 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_TILEGX_IMM16_X0_HW2_LAST: case R_TILEGX_IMM16_X1_HW2_LAST: if (h != NULL) - { - h->non_got_ref = 1; + h->non_got_ref = 1; - if (!info->shared) - { - /* We may need a .plt entry if the function this reloc - refers to is in a shared lib. */ - h->plt.refcount += 1; - } - } + r_tilegx_plt32: + if (h != NULL && !info->shared) + { + /* We may need a .plt entry if the function this reloc + refers to is in a shared lib. */ + h->plt.refcount += 1; + } /* If we are creating a shared library, and this is a reloc against a global symbol, or a non PC relative reloc @@ -2008,51 +2141,28 @@ tilegx_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, } r_type = TILEGX_ELF_R_TYPE (rel->r_info); - + r_type = tilegx_elf_tls_transition (info, r_type, h != NULL, + sec->sec_flg0); switch (r_type) { case R_TILEGX_IMM16_X0_HW0_GOT: case R_TILEGX_IMM16_X1_HW0_GOT: - case R_TILEGX_IMM16_X0_HW1_GOT: - case R_TILEGX_IMM16_X1_HW1_GOT: - case R_TILEGX_IMM16_X0_HW2_GOT: - case R_TILEGX_IMM16_X1_HW2_GOT: - case R_TILEGX_IMM16_X0_HW3_GOT: - case R_TILEGX_IMM16_X1_HW3_GOT: case R_TILEGX_IMM16_X0_HW0_LAST_GOT: case R_TILEGX_IMM16_X1_HW0_LAST_GOT: case R_TILEGX_IMM16_X0_HW1_LAST_GOT: case R_TILEGX_IMM16_X1_HW1_LAST_GOT: - case R_TILEGX_IMM16_X0_HW2_LAST_GOT: - case R_TILEGX_IMM16_X1_HW2_LAST_GOT: case R_TILEGX_IMM16_X0_HW0_TLS_GD: case R_TILEGX_IMM16_X1_HW0_TLS_GD: - case R_TILEGX_IMM16_X0_HW1_TLS_GD: - case R_TILEGX_IMM16_X1_HW1_TLS_GD: - case R_TILEGX_IMM16_X0_HW2_TLS_GD: - case R_TILEGX_IMM16_X1_HW2_TLS_GD: - case R_TILEGX_IMM16_X0_HW3_TLS_GD: - case R_TILEGX_IMM16_X1_HW3_TLS_GD: case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: - case R_TILEGX_IMM16_X0_HW2_LAST_TLS_GD: - case R_TILEGX_IMM16_X1_HW2_LAST_TLS_GD: case R_TILEGX_IMM16_X0_HW0_TLS_IE: case R_TILEGX_IMM16_X1_HW0_TLS_IE: - case R_TILEGX_IMM16_X0_HW1_TLS_IE: - case R_TILEGX_IMM16_X1_HW1_TLS_IE: - case R_TILEGX_IMM16_X0_HW2_TLS_IE: - case R_TILEGX_IMM16_X1_HW2_TLS_IE: - case R_TILEGX_IMM16_X0_HW3_TLS_IE: - case R_TILEGX_IMM16_X1_HW3_TLS_IE: case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: - case R_TILEGX_IMM16_X0_HW2_LAST_TLS_IE: - case R_TILEGX_IMM16_X1_HW2_LAST_TLS_IE: if (h != NULL) { if (h->got.refcount > 0) @@ -2060,7 +2170,8 @@ tilegx_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, } else { - if (local_got_refcounts[r_symndx] > 0) + if (local_got_refcounts && + local_got_refcounts[r_symndx] > 0) local_got_refcounts[r_symndx]--; } break; @@ -2361,7 +2472,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) h->needs_plt = 0; } - if (h->got.refcount > 0) + /* If a TLS_IE symbol is now local to the binary, make it a TLS_LE + requiring no TLS entry. */ + if (h->got.refcount > 0 + && !htab->disable_le_transition + && !info->shared + && h->dynindx == -1 + && tilegx_elf_hash_entry(h)->tls_type == GOT_TLS_IE) + h->got.offset = (bfd_vma) -1; + else if (h->got.refcount > 0) { asection *s; bfd_boolean dyn; @@ -2781,6 +2900,125 @@ tpoff (struct bfd_link_info *info, bfd_vma address) return (address - htab->tls_sec->vma); } +/* Copy SIZE bits from FROM to TO at address ADDR. */ + +static void +tilegx_copy_bits (bfd_byte *addr, int from, int to, int size) +{ + int i; + for (i = 0; i < size; i++) + { + int from_byte = (from + i) / 8; + int from_bit = (from + i) % 8; + int to_byte = (to + i) / 8; + int to_bit = (to + i) % 8; + bfd_byte to_mask = 1 << to_bit; + addr[to_byte] = (addr[to_byte] & ~to_mask) + | ((addr[from_byte] >> from_bit << to_bit) & to_mask); + } +} + +/* Replace the MASK bits in ADDR with those in INSN, for the next + TILEGX_BUNDLE_SIZE_IN_BYTES bytes. */ + +static void +tilegx_replace_insn (bfd_byte *addr, const bfd_byte *mask, + const bfd_byte *insn) +{ + int i; + for (i = 0; i < TILEGX_BUNDLE_SIZE_IN_BYTES; i++) + { + addr[i] = (addr[i] & ~mask[i]) | (insn[i] & mask[i]); + } +} + +/* Mask to extract the bits corresponding to an instruction in a + specific pipe of a bundle. */ +static const bfd_byte insn_mask_X1[] = { + 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x3f +}; + +/* Mask to extract the bits corresponding to an instruction in a + specific pipe of a bundle, minus the destination operand and the + first source operand. */ +static const bfd_byte insn_mask_X0_no_dest_no_srca[] = { + 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00 +}; + +static const bfd_byte insn_mask_X1_no_dest_no_srca[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x3f +}; + +static const bfd_byte insn_mask_Y0_no_dest_no_srca[] = { + 0x00, 0xf0, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00 +}; +static const bfd_byte insn_mask_Y1_no_dest_no_srca[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x3c +}; + +/* Mask to extract the bits corresponding to an instruction in a + specific pipe of a bundle, minus the register operands. */ +static const bfd_byte insn_mask_X0_no_operand[] = { + 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00 +}; + +static const bfd_byte insn_mask_X1_no_operand[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f +}; + +static const bfd_byte insn_mask_Y0_no_operand[] = { + 0x00, 0x00, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00 +}; + +static const bfd_byte insn_mask_Y1_no_operand[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x3c +}; + +/* Various instructions synthesized to support tls references. */ + +/* ld r0, r0 in the X1 pipe, used for tls ie. */ +static const bfd_byte insn_tls_ie_ld_X1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x6a, 0x28 +}; + +/* ld4s r0, r0 in the X1 pipe, used for tls ie. */ +static const bfd_byte insn_tls_ie_ld4s_X1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x6a, 0x28 +}; + +/* add r0, r0, tp in various pipes, used for tls ie. */ +static const bfd_byte insn_tls_ie_add_X0X1[] = { + 0x00, 0x50, 0x0f, 0x50, 0x00, 0xa8, 0x07, 0x28 +}; +static const bfd_byte insn_tls_ie_add_Y0Y1[] = { + 0x00, 0x50, 0x27, 0x2c, 0x00, 0xa8, 0x13, 0x9a +}; + +/* addx r0, r0, tp in various pipes, used for tls ie. */ +static const bfd_byte insn_tls_ie_addx_X0X1[] = { + 0x00, 0x50, 0x0b, 0x50, 0x00, 0xa8, 0x05, 0x28 +}; +static const bfd_byte insn_tls_ie_addx_Y0Y1[] = { + 0x00, 0x50, 0x03, 0x2c, 0x00, 0xa8, 0x01, 0x9a +}; + +/* move r0, r0 in various pipes, used for tls gd. */ +static const bfd_byte insn_tls_gd_add_X0X1[] = { + 0x00, 0xf0, 0x07, 0x51, 0x00, 0xf8, 0x3b, 0x28 +}; +static const bfd_byte insn_tls_gd_add_Y0Y1[] = { + 0x00, 0xf0, 0x0b, 0x54, 0x00, 0xf8, 0x05, 0xae +}; + +static const bfd_byte *insn_move_X0X1 = insn_tls_gd_add_X0X1; +static const bfd_byte *insn_move_Y0Y1 = insn_tls_gd_add_Y0Y1; + +static const bfd_byte *insn_add_X0X1 = insn_tls_ie_add_X0X1; +static const bfd_byte *insn_add_Y0Y1 = insn_tls_ie_add_Y0Y1; + +static const bfd_byte *insn_addx_X0X1 = insn_tls_ie_addx_X0X1; +static const bfd_byte *insn_addx_Y0Y1 = insn_tls_ie_addx_Y0Y1; + /* Relocate an TILEGX ELF section. The RELOCATE_SECTION function is called by the new ELF backend linker @@ -2845,6 +3083,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, for (; rel < relend; rel++) { int r_type, tls_type; + bfd_boolean is_tls_iele, is_tls_le; reloc_howto_type *howto; unsigned long r_symndx; struct elf_link_hash_entry *h; @@ -2927,20 +3166,203 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, switch (r_type) { + case R_TILEGX_TLS_GD_CALL: + case R_TILEGX_IMM8_X0_TLS_GD_ADD: + case R_TILEGX_IMM8_Y0_TLS_GD_ADD: + case R_TILEGX_IMM8_X1_TLS_GD_ADD: + case R_TILEGX_IMM8_Y1_TLS_GD_ADD: + case R_TILEGX_IMM8_X0_TLS_ADD: + case R_TILEGX_IMM8_Y0_TLS_ADD: + case R_TILEGX_IMM8_X1_TLS_ADD: + case R_TILEGX_IMM8_Y1_TLS_ADD: + tls_type = GOT_UNKNOWN; + if (h == NULL && local_got_offsets) + tls_type = + _bfd_tilegx_elf_local_got_tls_type (input_bfd) [r_symndx]; + else if (h != NULL) + tls_type = tilegx_elf_hash_entry(h)->tls_type; + + is_tls_iele = (! info->shared || tls_type == GOT_TLS_IE); + is_tls_le = is_tls_iele && (!input_section->sec_flg0 + && !info->shared + && (h == NULL || h->dynindx == -1)); + + if (r_type == R_TILEGX_TLS_GD_CALL) + { + if (is_tls_le) + { + /* GD -> LE */ + tilegx_replace_insn (contents + rel->r_offset, + insn_mask_X1, insn_move_X0X1); + continue; + } + else if (is_tls_iele) + { + /* GD -> IE */ + if (ABI_64_P (output_bfd)) + tilegx_replace_insn (contents + rel->r_offset, + insn_mask_X1, insn_tls_ie_ld_X1); + else + tilegx_replace_insn (contents + rel->r_offset, + insn_mask_X1, insn_tls_ie_ld4s_X1); + continue; + } + + /* GD -> GD */ + h = (struct elf_link_hash_entry *) + bfd_link_hash_lookup (info->hash, "__tls_get_addr", FALSE, + FALSE, TRUE); + BFD_ASSERT (h != NULL); + r_type = R_TILEGX_JUMPOFF_X1_PLT; + howto = tilegx_elf_howto_table + r_type; + } + else if (r_type == R_TILEGX_IMM8_X0_TLS_ADD + || r_type == R_TILEGX_IMM8_X1_TLS_ADD + || r_type == R_TILEGX_IMM8_Y0_TLS_ADD + || r_type == R_TILEGX_IMM8_Y1_TLS_ADD) + { + bfd_boolean is_pipe0 = + (r_type == R_TILEGX_IMM8_X0_TLS_ADD + || r_type == R_TILEGX_IMM8_Y0_TLS_ADD); + bfd_boolean is_X0X1 = + (r_type == R_TILEGX_IMM8_X0_TLS_ADD + || r_type == R_TILEGX_IMM8_X1_TLS_ADD); + int dest_begin = is_pipe0 ? 0 : 31; + int src_begin; + const bfd_byte *insn; + const bfd_byte *mask; + + if (is_tls_le) + { + /* 1. copy dest operand into the first source operand. + 2. change the opcode to "move". */ + src_begin = is_pipe0 ? 6 : 37; + insn = is_X0X1 ? insn_move_X0X1 : insn_move_Y0Y1; + + switch (r_type) + { + case R_TILEGX_IMM8_X0_TLS_ADD: + mask = insn_mask_X0_no_dest_no_srca; + break; + case R_TILEGX_IMM8_X1_TLS_ADD: + mask = insn_mask_X1_no_dest_no_srca; + break; + case R_TILEGX_IMM8_Y0_TLS_ADD: + mask = insn_mask_Y0_no_dest_no_srca; + break; + case R_TILEGX_IMM8_Y1_TLS_ADD: + mask = insn_mask_Y1_no_dest_no_srca; + break; + } + } + else + { + /* 1. copy dest operand into the second source operand. + 2. change the opcode to "add". */ + src_begin = is_pipe0 ? 12 : 43; + if (ABI_64_P (output_bfd)) + insn = is_X0X1 ? insn_add_X0X1 : insn_add_Y0Y1; + else + insn = is_X0X1 ? insn_addx_X0X1 : insn_addx_Y0Y1; + + switch (r_type) + { + case R_TILEGX_IMM8_X0_TLS_ADD: + mask = insn_mask_X0_no_operand; + break; + case R_TILEGX_IMM8_X1_TLS_ADD: + mask = insn_mask_X1_no_operand; + break; + case R_TILEGX_IMM8_Y0_TLS_ADD: + mask = insn_mask_Y0_no_operand; + break; + case R_TILEGX_IMM8_Y1_TLS_ADD: + mask = insn_mask_Y1_no_operand; + break; + } + } + + tilegx_copy_bits (contents + rel->r_offset, dest_begin, + src_begin, 6); + tilegx_replace_insn (contents + rel->r_offset, mask, insn); + + continue; + } + else + { + const bfd_byte *mask = NULL; + const bfd_byte *add_insn = NULL; + bfd_boolean is_64bit = ABI_64_P (output_bfd); + + switch (r_type) + { + case R_TILEGX_IMM8_X0_TLS_GD_ADD: + add_insn = is_tls_iele + ? (is_64bit ? insn_tls_ie_add_X0X1 : insn_tls_ie_addx_X0X1) + : insn_tls_gd_add_X0X1; + mask = insn_mask_X0_no_dest_no_srca; + break; + case R_TILEGX_IMM8_X1_TLS_GD_ADD: + add_insn = is_tls_iele + ? (is_64bit ? insn_tls_ie_add_X0X1 : insn_tls_ie_addx_X0X1) + : insn_tls_gd_add_X0X1; + mask = insn_mask_X1_no_dest_no_srca; + break; + case R_TILEGX_IMM8_Y0_TLS_GD_ADD: + add_insn = is_tls_iele + ? (is_64bit ? insn_tls_ie_add_Y0Y1 : insn_tls_ie_addx_Y0Y1) + : insn_tls_gd_add_Y0Y1; + mask = insn_mask_Y0_no_dest_no_srca; + break; + case R_TILEGX_IMM8_Y1_TLS_GD_ADD: + add_insn = is_tls_iele + ? (is_64bit ? insn_tls_ie_add_Y0Y1 : insn_tls_ie_addx_Y0Y1) + : insn_tls_gd_add_Y0Y1; + mask = insn_mask_Y1_no_dest_no_srca; + break; + } + + tilegx_replace_insn (contents + rel->r_offset, mask, add_insn); + + continue; + } + break; + case R_TILEGX_TLS_IE_LOAD: + if (!input_section->sec_flg0 + && !info->shared + && (h == NULL || h->dynindx == -1)) + { + /* IE -> LE */ + tilegx_replace_insn (contents + rel->r_offset, + insn_mask_X1_no_dest_no_srca, + insn_move_X0X1); + } + else + { + /* IE -> IE */ + if (ABI_64_P (output_bfd)) + tilegx_replace_insn (contents + rel->r_offset, + insn_mask_X1_no_dest_no_srca, + insn_tls_ie_ld_X1); + else + tilegx_replace_insn (contents + rel->r_offset, + insn_mask_X1_no_dest_no_srca, + insn_tls_ie_ld4s_X1); + } + continue; + break; + default: + break; + } + + switch (r_type) + { case R_TILEGX_IMM16_X0_HW0_GOT: case R_TILEGX_IMM16_X1_HW0_GOT: - case R_TILEGX_IMM16_X0_HW1_GOT: - case R_TILEGX_IMM16_X1_HW1_GOT: - case R_TILEGX_IMM16_X0_HW2_GOT: - case R_TILEGX_IMM16_X1_HW2_GOT: - case R_TILEGX_IMM16_X0_HW3_GOT: - case R_TILEGX_IMM16_X1_HW3_GOT: case R_TILEGX_IMM16_X0_HW0_LAST_GOT: case R_TILEGX_IMM16_X1_HW0_LAST_GOT: case R_TILEGX_IMM16_X0_HW1_LAST_GOT: case R_TILEGX_IMM16_X1_HW1_LAST_GOT: - case R_TILEGX_IMM16_X0_HW2_LAST_GOT: - case R_TILEGX_IMM16_X1_HW2_LAST_GOT: /* Relocation is to the entry for this symbol in the global offset table. */ if (htab->elf.sgot == NULL) @@ -3248,92 +3670,83 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } break; + case R_TILEGX_IMM16_X0_HW0_TLS_LE: + case R_TILEGX_IMM16_X1_HW0_TLS_LE: + case R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: + case R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: + case R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: + case R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: + if (info->shared) + { + Elf_Internal_Rela outrel; + bfd_boolean skip; + + BFD_ASSERT (sreloc != NULL); + skip = FALSE; + outrel.r_offset = + _bfd_elf_section_offset (output_bfd, info, input_section, + rel->r_offset); + if (outrel.r_offset == (bfd_vma) -1) + skip = TRUE; + else if (outrel.r_offset == (bfd_vma) -2) + skip = TRUE; + outrel.r_offset += (input_section->output_section->vma + + input_section->output_offset); + if (skip) + memset (&outrel, 0, sizeof outrel); + else + { + outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, 0, r_type); + outrel.r_addend = relocation - dtpoff_base (info) + + rel->r_addend; + } + + tilegx_elf_append_rela (output_bfd, sreloc, &outrel); + continue; + } + relocation = tpoff (info, relocation); + break; + case R_TILEGX_IMM16_X0_HW0_TLS_GD: case R_TILEGX_IMM16_X1_HW0_TLS_GD: - case R_TILEGX_IMM16_X0_HW1_TLS_GD: - case R_TILEGX_IMM16_X1_HW1_TLS_GD: - case R_TILEGX_IMM16_X0_HW2_TLS_GD: - case R_TILEGX_IMM16_X1_HW2_TLS_GD: - case R_TILEGX_IMM16_X0_HW3_TLS_GD: - case R_TILEGX_IMM16_X1_HW3_TLS_GD: case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: - case R_TILEGX_IMM16_X0_HW2_LAST_TLS_GD: - case R_TILEGX_IMM16_X1_HW2_LAST_TLS_GD: - tls_type = GOT_TLS_GD; - goto have_tls_reference; - case R_TILEGX_IMM16_X0_HW0_TLS_IE: case R_TILEGX_IMM16_X1_HW0_TLS_IE: - case R_TILEGX_IMM16_X0_HW1_TLS_IE: - case R_TILEGX_IMM16_X1_HW1_TLS_IE: - case R_TILEGX_IMM16_X0_HW2_TLS_IE: - case R_TILEGX_IMM16_X1_HW2_TLS_IE: - case R_TILEGX_IMM16_X0_HW3_TLS_IE: - case R_TILEGX_IMM16_X1_HW3_TLS_IE: case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: - case R_TILEGX_IMM16_X0_HW2_LAST_TLS_IE: - case R_TILEGX_IMM16_X1_HW2_LAST_TLS_IE: - tls_type = GOT_TLS_IE; - /* Fall through. */ - - have_tls_reference: + r_type = tilegx_elf_tls_transition (info, r_type, h == NULL, + input_section->sec_flg0); + tls_type = GOT_UNKNOWN; if (h == NULL && local_got_offsets) - tls_type = _bfd_tilegx_elf_local_got_tls_type (input_bfd) [r_symndx]; + tls_type = + _bfd_tilegx_elf_local_got_tls_type (input_bfd) [r_symndx]; else if (h != NULL) - tls_type = tilegx_elf_hash_entry(h)->tls_type; + { + tls_type = tilegx_elf_hash_entry(h)->tls_type; + if (!info->shared && h->dynindx == -1 && tls_type == GOT_TLS_IE) + r_type = (!input_section->sec_flg0 + ? tilegx_tls_translate_to_le (r_type) + : tilegx_tls_translate_to_ie (r_type)); + } if (tls_type == GOT_TLS_IE) - switch (r_type) - { - case R_TILEGX_IMM16_X0_HW0_TLS_GD: - r_type = R_TILEGX_IMM16_X0_HW0_TLS_IE; - break; - case R_TILEGX_IMM16_X1_HW0_TLS_GD: - r_type = R_TILEGX_IMM16_X1_HW0_TLS_IE; - break; - case R_TILEGX_IMM16_X0_HW1_TLS_GD: - r_type = R_TILEGX_IMM16_X0_HW1_TLS_IE; - break; - case R_TILEGX_IMM16_X1_HW1_TLS_GD: - r_type = R_TILEGX_IMM16_X1_HW1_TLS_IE; - break; - case R_TILEGX_IMM16_X0_HW2_TLS_GD: - r_type = R_TILEGX_IMM16_X0_HW2_TLS_IE; - break; - case R_TILEGX_IMM16_X1_HW2_TLS_GD: - r_type = R_TILEGX_IMM16_X1_HW2_TLS_IE; - break; - case R_TILEGX_IMM16_X0_HW3_TLS_GD: - r_type = R_TILEGX_IMM16_X0_HW3_TLS_IE; - break; - case R_TILEGX_IMM16_X1_HW3_TLS_GD: - r_type = R_TILEGX_IMM16_X1_HW3_TLS_IE; - break; - case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: - r_type = R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE; - break; - case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: - r_type = R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE; - break; - case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: - r_type = R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE; - break; - case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: - r_type = R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE; - break; - case R_TILEGX_IMM16_X0_HW2_LAST_TLS_GD: - r_type = R_TILEGX_IMM16_X0_HW2_LAST_TLS_IE; - break; - case R_TILEGX_IMM16_X1_HW2_LAST_TLS_GD: - r_type = R_TILEGX_IMM16_X1_HW2_LAST_TLS_IE; - break; - } + r_type = tilegx_tls_translate_to_ie (r_type); + + if (r_type == R_TILEGX_IMM16_X0_HW0_TLS_LE + || r_type == R_TILEGX_IMM16_X1_HW0_TLS_LE + || r_type == R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE + || r_type == R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE + || r_type == R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE + || r_type == R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE) + { + relocation = tpoff (info, relocation); + break; + } if (h != NULL) { @@ -3386,18 +3799,10 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { case R_TILEGX_IMM16_X0_HW0_TLS_IE: case R_TILEGX_IMM16_X1_HW0_TLS_IE: - case R_TILEGX_IMM16_X0_HW1_TLS_IE: - case R_TILEGX_IMM16_X1_HW1_TLS_IE: - case R_TILEGX_IMM16_X0_HW2_TLS_IE: - case R_TILEGX_IMM16_X1_HW2_TLS_IE: - case R_TILEGX_IMM16_X0_HW3_TLS_IE: - case R_TILEGX_IMM16_X1_HW3_TLS_IE: case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: - case R_TILEGX_IMM16_X0_HW2_LAST_TLS_IE: - case R_TILEGX_IMM16_X1_HW2_LAST_TLS_IE: if (need_relocs) { TILEGX_ELF_PUT_WORD (htab, output_bfd, 0, htab->elf.sgot->contents + off); @@ -3418,18 +3823,10 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, case R_TILEGX_IMM16_X0_HW0_TLS_GD: case R_TILEGX_IMM16_X1_HW0_TLS_GD: - case R_TILEGX_IMM16_X0_HW1_TLS_GD: - case R_TILEGX_IMM16_X1_HW1_TLS_GD: - case R_TILEGX_IMM16_X0_HW2_TLS_GD: - case R_TILEGX_IMM16_X1_HW2_TLS_GD: - case R_TILEGX_IMM16_X0_HW3_TLS_GD: - case R_TILEGX_IMM16_X1_HW3_TLS_GD: case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: - case R_TILEGX_IMM16_X0_HW2_LAST_TLS_GD: - case R_TILEGX_IMM16_X1_HW2_LAST_TLS_GD: if (need_relocs) { outrel.r_offset = (htab->elf.sgot->output_section->vma + htab->elf.sgot->output_offset + off); diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 62f128f..78860ff 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -2406,6 +2406,12 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_TILEPRO_SHAMT_X1", "BFD_RELOC_TILEPRO_SHAMT_Y0", "BFD_RELOC_TILEPRO_SHAMT_Y1", + "BFD_RELOC_TILEPRO_TLS_GD_CALL", + "BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD", + "BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD", + "BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD", + "BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD", + "BFD_RELOC_TILEPRO_TLS_IE_LOAD", "BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD", "BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD", "BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO", @@ -2425,6 +2431,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_TILEPRO_TLS_DTPMOD32", "BFD_RELOC_TILEPRO_TLS_DTPOFF32", "BFD_RELOC_TILEPRO_TLS_TPOFF32", + "BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE", + "BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE", + "BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO", + "BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO", + "BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI", + "BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI", + "BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA", + "BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA", "BFD_RELOC_TILEGX_HW0", "BFD_RELOC_TILEGX_HW1", "BFD_RELOC_TILEGX_HW2", @@ -2482,52 +2496,44 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL", "BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT", "BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW3_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW3_GOT", "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT", "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT", "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT", "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_GOT", "BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD", "BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD", + "BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE", + "BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE", + "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE", + "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE", + "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE", + "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE", "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD", "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD", "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD", "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD", "BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE", "BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE", "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE", "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE", "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE", "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE", "BFD_RELOC_TILEGX_TLS_DTPMOD64", "BFD_RELOC_TILEGX_TLS_DTPOFF64", "BFD_RELOC_TILEGX_TLS_TPOFF64", "BFD_RELOC_TILEGX_TLS_DTPMOD32", "BFD_RELOC_TILEGX_TLS_DTPOFF32", "BFD_RELOC_TILEGX_TLS_TPOFF32", + "BFD_RELOC_TILEGX_TLS_GD_CALL", + "BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD", + "BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD", + "BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD", + "BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD", + "BFD_RELOC_TILEGX_TLS_IE_LOAD", + "BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD", + "BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD", + "BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD", + "BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD", "BFD_RELOC_EPIPHANY_SIMM8", "BFD_RELOC_EPIPHANY_SIMM24", "BFD_RELOC_EPIPHANY_HIGH", diff --git a/bfd/reloc.c b/bfd/reloc.c index ac1ecb5..4e1958c 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -5799,6 +5799,18 @@ ENUMX ENUMX BFD_RELOC_TILEPRO_SHAMT_Y1 ENUMX + BFD_RELOC_TILEPRO_TLS_GD_CALL +ENUMX + BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD +ENUMX + BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD +ENUMX + BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD +ENUMX + BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD +ENUMX + BFD_RELOC_TILEPRO_TLS_IE_LOAD +ENUMX BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD ENUMX BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD @@ -5836,6 +5848,22 @@ ENUMX BFD_RELOC_TILEPRO_TLS_DTPOFF32 ENUMX BFD_RELOC_TILEPRO_TLS_TPOFF32 +ENUMX + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE +ENUMX + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE +ENUMX + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO +ENUMX + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO +ENUMX + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI +ENUMX + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI +ENUMX + BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA +ENUMX + BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA ENUMDOC Tilera TILEPro Relocations. @@ -5954,18 +5982,6 @@ ENUMX ENUMX BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW3_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW3_GOT -ENUMX BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT ENUMX BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT @@ -5974,25 +5990,21 @@ ENUMX ENUMX BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_GOT -ENUMX BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD ENUMX BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD + BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD + BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD + BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD + BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD + BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD + BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE ENUMX BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD ENUMX @@ -6002,26 +6014,10 @@ ENUMX ENUMX BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD -ENUMX BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE ENUMX BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE -ENUMX BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE ENUMX BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE @@ -6030,10 +6026,6 @@ ENUMX ENUMX BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE -ENUMX BFD_RELOC_TILEGX_TLS_DTPMOD64 ENUMX BFD_RELOC_TILEGX_TLS_DTPOFF64 @@ -6045,6 +6037,26 @@ ENUMX BFD_RELOC_TILEGX_TLS_DTPOFF32 ENUMX BFD_RELOC_TILEGX_TLS_TPOFF32 +ENUMX + BFD_RELOC_TILEGX_TLS_GD_CALL +ENUMX + BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD +ENUMX + BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD +ENUMX + BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD +ENUMX + BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD +ENUMX + BFD_RELOC_TILEGX_TLS_IE_LOAD +ENUMX + BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD +ENUMX + BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD +ENUMX + BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD +ENUMX + BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD ENUMDOC Tilera TILE-Gx Relocations. |