+ return true;
+}
+
+static int
+elf_mn10300_tls_transition (struct bfd_link_info * info,
+ int r_type,
+ struct elf_link_hash_entry * h,
+ asection * sec,
+ bool counting)
+{
+ bool is_local;
+
+ if (r_type == R_MN10300_TLS_GD
+ && h != NULL
+ && elf_mn10300_hash_entry (h)->tls_type == GOT_TLS_IE)
+ return R_MN10300_TLS_GOTIE;
+
+ if (bfd_link_pic (info))
+ return r_type;
+
+ if (! (sec->flags & SEC_CODE))
+ return r_type;
+
+ if (! counting && h != NULL && ! elf_hash_table (info)->dynamic_sections_created)
+ is_local = true;
+ else
+ is_local = SYMBOL_CALLS_LOCAL (info, h);
+
+ /* For the main program, these are the transitions we do. */
+ switch (r_type)
+ {
+ case R_MN10300_TLS_GD: return is_local ? R_MN10300_TLS_LE : R_MN10300_TLS_GOTIE;
+ case R_MN10300_TLS_LD: return R_MN10300_NONE;
+ case R_MN10300_TLS_LDO: return R_MN10300_TLS_LE;
+ case R_MN10300_TLS_IE:
+ case R_MN10300_TLS_GOTIE: return is_local ? R_MN10300_TLS_LE : r_type;
+ }
+
+ return r_type;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+dtpoff (struct bfd_link_info * info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ return address - htab->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+tpoff (struct bfd_link_info * info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ return address - (htab->tls_size + htab->tls_sec->vma);
+}
+
+/* Returns nonzero if there's a R_MN10300_PLT32 reloc that we now need
+ to skip, after this one. The actual value is the offset between
+ this reloc and the PLT reloc. */
+
+static int
+mn10300_do_tls_transition (bfd * input_bfd,
+ unsigned int r_type,
+ unsigned int tls_r_type,
+ bfd_byte * contents,
+ bfd_vma offset)
+{
+ bfd_byte *op = contents + offset;
+ int gotreg = 0;
+
+#define TLS_PAIR(r1,r2) ((r1) * R_MN10300_MAX + (r2))
+
+ /* This is common to all GD/LD transitions, so break it out. */
+ if (r_type == R_MN10300_TLS_GD
+ || r_type == R_MN10300_TLS_LD)
+ {
+ op -= 2;
+ /* mov imm,d0. */
+ BFD_ASSERT (bfd_get_8 (input_bfd, op) == 0xFC);
+ BFD_ASSERT (bfd_get_8 (input_bfd, op + 1) == 0xCC);
+ /* add aN,d0. */
+ BFD_ASSERT (bfd_get_8 (input_bfd, op + 6) == 0xF1);
+ gotreg = (bfd_get_8 (input_bfd, op + 7) & 0x0c) >> 2;
+ /* Call. */
+ BFD_ASSERT (bfd_get_8 (input_bfd, op + 8) == 0xDD);
+ }
+
+ switch (TLS_PAIR (r_type, tls_r_type))
+ {
+ case TLS_PAIR (R_MN10300_TLS_GD, R_MN10300_TLS_GOTIE):
+ {
+ /* Keep track of which register we put GOTptr in. */
+ /* mov (_x@indntpoff,a2),a0. */
+ memcpy (op, "\xFC\x20\x00\x00\x00\x00", 6);
+ op[1] |= gotreg;
+ /* add e2,a0. */
+ memcpy (op+6, "\xF9\x78\x28", 3);
+ /* or 0x00000000, d0 - six byte nop. */
+ memcpy (op+9, "\xFC\xE4\x00\x00\x00\x00", 6);
+ }
+ return 7;
+
+ case TLS_PAIR (R_MN10300_TLS_GD, R_MN10300_TLS_LE):
+ {
+ /* Register is *always* a0. */
+ /* mov _x@tpoff,a0. */
+ memcpy (op, "\xFC\xDC\x00\x00\x00\x00", 6);
+ /* add e2,a0. */
+ memcpy (op+6, "\xF9\x78\x28", 3);
+ /* or 0x00000000, d0 - six byte nop. */
+ memcpy (op+9, "\xFC\xE4\x00\x00\x00\x00", 6);
+ }
+ return 7;
+ case TLS_PAIR (R_MN10300_TLS_LD, R_MN10300_NONE):
+ {
+ /* Register is *always* a0. */
+ /* mov e2,a0. */
+ memcpy (op, "\xF5\x88", 2);
+ /* or 0x00000000, d0 - six byte nop. */
+ memcpy (op+2, "\xFC\xE4\x00\x00\x00\x00", 6);
+ /* or 0x00000000, e2 - seven byte nop. */
+ memcpy (op+8, "\xFE\x19\x22\x00\x00\x00\x00", 7);
+ }
+ return 7;
+
+ case TLS_PAIR (R_MN10300_TLS_LDO, R_MN10300_TLS_LE):
+ /* No changes needed, just the reloc change. */
+ return 0;
+
+ /* These are a little tricky, because we have to detect which
+ opcode is being used (they're different sizes, with the reloc
+ at different offsets within the opcode) and convert each
+ accordingly, copying the operands as needed. The conversions
+ we do are as follows (IE,GOTIE,LE):
+
+ 1111 1100 1010 01Dn [-- abs32 --] MOV (x@indntpoff),Dn
+ 1111 1100 0000 DnAm [-- abs32 --] MOV (x@gotntpoff,Am),Dn
+ 1111 1100 1100 11Dn [-- abs32 --] MOV x@tpoff,Dn
+
+ 1111 1100 1010 00An [-- abs32 --] MOV (x@indntpoff),An
+ 1111 1100 0010 AnAm [-- abs32 --] MOV (x@gotntpoff,Am),An
+ 1111 1100 1101 11An [-- abs32 --] MOV x@tpoff,An
+
+ 1111 1110 0000 1110 Rnnn Xxxx [-- abs32 --] MOV (x@indntpoff),Rn
+ 1111 1110 0000 1010 Rnnn Rmmm [-- abs32 --] MOV (x@indntpoff,Rm),Rn
+ 1111 1110 0000 1000 Rnnn Xxxx [-- abs32 --] MOV x@tpoff,Rn
+
+ Since the GOT pointer is always $a2, we assume the last
+ normally won't happen, but let's be paranoid and plan for the
+ day that GCC optimizes it somewhow. */
+
+ case TLS_PAIR (R_MN10300_TLS_IE, R_MN10300_TLS_LE):
+ if (op[-2] == 0xFC)
+ {
+ op -= 2;
+ if ((op[1] & 0xFC) == 0xA4) /* Dn */
+ {
+ op[1] &= 0x03; /* Leaves Dn. */
+ op[1] |= 0xCC;
+ }
+ else /* An */
+ {
+ op[1] &= 0x03; /* Leaves An. */
+ op[1] |= 0xDC;
+ }
+ }
+ else if (op[-3] == 0xFE)
+ op[-2] = 0x08;
+ else
+ abort ();
+ break;
+
+ case TLS_PAIR (R_MN10300_TLS_GOTIE, R_MN10300_TLS_LE):
+ if (op[-2] == 0xFC)
+ {
+ op -= 2;
+ if ((op[1] & 0xF0) == 0x00) /* Dn */
+ {
+ op[1] &= 0x0C; /* Leaves Dn. */
+ op[1] >>= 2;
+ op[1] |= 0xCC;
+ }
+ else /* An */
+ {
+ op[1] &= 0x0C; /* Leaves An. */
+ op[1] >>= 2;
+ op[1] |= 0xDC;
+ }
+ }
+ else if (op[-3] == 0xFE)
+ op[-2] = 0x08;
+ else
+ abort ();
+ break;
+
+ default:
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: unsupported transition from %s to %s"),
+ input_bfd,
+ elf_mn10300_howto_table[r_type].name,
+ elf_mn10300_howto_table[tls_r_type].name);
+ break;
+ }
+#undef TLS_PAIR
+ return 0;