]> code.ossystems Code Review - openembedded-core.git/blob
4b0caafb48411d02ebed943cf321ba00de7a5424
[openembedded-core.git] /
1 Upstream-Status: Backport
2
3 From 7e2b7154b03e4c77233171eec5cba8d113e04fea Mon Sep 17 00:00:00 2001
4 From: cltang <cltang>
5 Date: Mon, 19 Dec 2011 10:49:24 +0000
6 Subject: [PATCH 037/262] 2011-12-19  Chung-Lin Tang 
7  <cltang@codesourcery.com>
8
9         Backport from mainline:
10
11         2011-12-19  Chung-Lin Tang  <cltang@codesourcery.com>
12
13         gas/
14         * config/tc-mips.c (mips_pseudo_table): Add tprelword/tpreldword
15         entries.
16         (mips16_percent_op): Add MIPS16 TLS relocation ops.
17         (md_apply_fix): Add BFD_RELOC_MIPS16_TLS_* switch cases.
18         (s_tls_rel_directive): Rename from s_dtprel_internal(). Abstract out
19         directive string and reloc type as function parameters. Update
20         comments.
21         (s_dtprelword,s_dtpreldword): Change to use s_tls_rel_directive().
22         (s_tprelword,s_tpreldword): New functions.
23
24         include/
25         * elf/mips.h (elf_mips_reloc_type): Add R_MIPS16_TLS_* entries.
26
27         bfd/
28         * reloc.c (BFD_RELOC_MIPS16_TLS_GD,BFD_RELOC_MIPS16_TLS_LDM,
29         BFD_RELOC_MIPS16_TLS_DTPREL_HI16,BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
30         BFD_RELOC_MIPS16_TLS_GOTTPREL,BFD_RELOC_MIPS16_TLS_TPREL_HI16,
31         BFD_RELOC_MIPS16_TLS_TPREL_LO16): New relocations for MIPS16 TLS.
32         * bfd-in2.h (bfd_reloc_code_real): Regenerate.
33         * libbfd.h (bfd_reloc_code_real_names): Regenerate.
34         * elf32-mips.c (elf_mips16_howto_table_rel): Add R_MIPS16_TLS_*
35         entries.
36         (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_*
37         mappings.
38         * elfn32-mips.c (elf_mips16_howto_table_rel,
39         elf_mips16_howto_table_rela): Add R_MIPS16_TLS_* entries.
40         (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_*
41         mappings.
42         * elf64-mips.c (mips16_elf64_howto_table_rel,
43         mips16_elf64_howto_table_rela): Add R_MIPS16_TLS_* entries.
44         (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_*
45         mappings.
46         * elfxx-mips.c (TLS_RELOC_P,mips16_reloc_p,
47         _bfd_mips_elf_check_relocs): Add cases for R_MIPS16_TLS_* relocations.
48         (tls_gd_reloc_p): Add R_MIPS16_TLS_GD case.
49         (tls_ldm_reloc_p): Add R_MIPS16_TLS_LDM case.
50         (tls_gottprel_reloc_p): Add R_MIPS16_TLS_GOTTPREL case.
51         (mips_elf_calculate_relocation): Add cases for R_MIPS16_TLS_*,
52         R_MIPS_TLS_DTPREL32/64, and R_MIPS_TLS_TPREL32/64 relocations.
53 ---
54  bfd/ChangeLog        |   32 ++++++++
55  bfd/bfd-in2.h        |    9 +++
56  bfd/elf32-mips.c     |  114 ++++++++++++++++++++++++++
57  bfd/elf64-mips.c     |  219 ++++++++++++++++++++++++++++++++++++++++++++++++++
58  bfd/elfn32-mips.c    |  219 ++++++++++++++++++++++++++++++++++++++++++++++++++
59  bfd/elfxx-mips.c     |   48 +++++++++--
60  bfd/libbfd.h         |    7 ++
61  bfd/reloc.c          |   17 ++++
62  gas/ChangeLog        |   16 ++++
63  gas/config/tc-mips.c |   62 ++++++++++----
64  include/ChangeLog    |    8 ++
65  include/elf/mips.h   |    9 ++-
66  12 files changed, 739 insertions(+), 21 deletions(-)
67
68 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
69 index 22fcdf6..cd90740 100644
70 --- a/bfd/bfd-in2.h
71 +++ b/bfd/bfd-in2.h
72 @@ -2780,6 +2780,15 @@ to compensate for the borrow when the low bits are added.  */
73  /* MIPS16 low 16 bits.  */
74    BFD_RELOC_MIPS16_LO16,
75  
76 +/* MIPS16 TLS relocations  */
77 +  BFD_RELOC_MIPS16_TLS_GD,
78 +  BFD_RELOC_MIPS16_TLS_LDM,
79 +  BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
80 +  BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
81 +  BFD_RELOC_MIPS16_TLS_GOTTPREL,
82 +  BFD_RELOC_MIPS16_TLS_TPREL_HI16,
83 +  BFD_RELOC_MIPS16_TLS_TPREL_LO16,
84 +
85  /* Relocation against a MIPS literal section.  */
86    BFD_RELOC_MIPS_LITERAL,
87    BFD_RELOC_MICROMIPS_LITERAL,
88 diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
89 index fd3d4ba..61e8b45 100644
90 --- a/bfd/elf32-mips.c
91 +++ b/bfd/elf32-mips.c
92 @@ -830,6 +830,111 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
93          0x0000ffff,            /* src_mask */
94          0x0000ffff,            /* dst_mask */
95          FALSE),                /* pcrel_offset */
96 +
97 +  /* MIPS16 TLS general dynamic variable reference.  */
98 +  HOWTO (R_MIPS16_TLS_GD,      /* type */
99 +        0,                     /* rightshift */
100 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
101 +        16,                    /* bitsize */
102 +        FALSE,                 /* pc_relative */
103 +        0,                     /* bitpos */
104 +        complain_overflow_signed, /* complain_on_overflow */
105 +        _bfd_mips_elf_generic_reloc, /* special_function */
106 +        "R_MIPS16_TLS_GD",     /* name */
107 +        TRUE,                  /* partial_inplace */
108 +        0x0000ffff,            /* src_mask */
109 +        0x0000ffff,            /* dst_mask */
110 +        FALSE),                /* pcrel_offset */
111 +
112 +  /* MIPS16 TLS local dynamic variable reference.  */
113 +  HOWTO (R_MIPS16_TLS_LDM,     /* type */
114 +        0,                     /* rightshift */
115 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
116 +        16,                    /* bitsize */
117 +        FALSE,                 /* pc_relative */
118 +        0,                     /* bitpos */
119 +        complain_overflow_signed, /* complain_on_overflow */
120 +        _bfd_mips_elf_generic_reloc, /* special_function */
121 +        "R_MIPS16_TLS_LDM",    /* name */
122 +        TRUE,                  /* partial_inplace */
123 +        0x0000ffff,            /* src_mask */
124 +        0x0000ffff,            /* dst_mask */
125 +        FALSE),                /* pcrel_offset */
126 +
127 +  /* MIPS16 TLS local dynamic offset.  */
128 +  HOWTO (R_MIPS16_TLS_DTPREL_HI16,     /* type */
129 +        0,                     /* rightshift */
130 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
131 +        16,                    /* bitsize */
132 +        FALSE,                 /* pc_relative */
133 +        0,                     /* bitpos */
134 +        complain_overflow_signed, /* complain_on_overflow */
135 +        _bfd_mips_elf_generic_reloc, /* special_function */
136 +        "R_MIPS16_TLS_DTPREL_HI16",    /* name */
137 +        TRUE,                  /* partial_inplace */
138 +        0x0000ffff,            /* src_mask */
139 +        0x0000ffff,            /* dst_mask */
140 +        FALSE),                /* pcrel_offset */
141 +
142 +  /* MIPS16 TLS local dynamic offset.  */
143 +  HOWTO (R_MIPS16_TLS_DTPREL_LO16,     /* type */
144 +        0,                     /* rightshift */
145 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
146 +        16,                    /* bitsize */
147 +        FALSE,                 /* pc_relative */
148 +        0,                     /* bitpos */
149 +        complain_overflow_signed, /* complain_on_overflow */
150 +        _bfd_mips_elf_generic_reloc, /* special_function */
151 +        "R_MIPS16_TLS_DTPREL_LO16",    /* name */
152 +        TRUE,                  /* partial_inplace */
153 +        0x0000ffff,            /* src_mask */
154 +        0x0000ffff,            /* dst_mask */
155 +        FALSE),                /* pcrel_offset */
156 +
157 +  /* MIPS16 TLS thread pointer offset.  */
158 +  HOWTO (R_MIPS16_TLS_GOTTPREL,        /* type */
159 +        0,                     /* rightshift */
160 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
161 +        16,                    /* bitsize */
162 +        FALSE,                 /* pc_relative */
163 +        0,                     /* bitpos */
164 +        complain_overflow_signed, /* complain_on_overflow */
165 +        _bfd_mips_elf_generic_reloc, /* special_function */
166 +        "R_MIPS16_TLS_GOTTPREL",       /* name */
167 +        TRUE,                  /* partial_inplace */
168 +        0x0000ffff,            /* src_mask */
169 +        0x0000ffff,            /* dst_mask */
170 +        FALSE),                /* pcrel_offset */
171 +
172 +  /* MIPS16 TLS thread pointer offset.  */
173 +  HOWTO (R_MIPS16_TLS_TPREL_HI16,      /* type */
174 +        0,                     /* rightshift */
175 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
176 +        16,                    /* bitsize */
177 +        FALSE,                 /* pc_relative */
178 +        0,                     /* bitpos */
179 +        complain_overflow_signed, /* complain_on_overflow */
180 +        _bfd_mips_elf_generic_reloc, /* special_function */
181 +        "R_MIPS16_TLS_TPREL_HI16", /* name */
182 +        TRUE,                  /* partial_inplace */
183 +        0x0000ffff,            /* src_mask */
184 +        0x0000ffff,            /* dst_mask */
185 +        FALSE),                /* pcrel_offset */
186 +
187 +  /* MIPS16 TLS thread pointer offset.  */
188 +  HOWTO (R_MIPS16_TLS_TPREL_LO16,      /* type */
189 +        0,                     /* rightshift */
190 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
191 +        16,                    /* bitsize */
192 +        FALSE,                 /* pc_relative */
193 +        0,                     /* bitpos */
194 +        complain_overflow_signed, /* complain_on_overflow */
195 +        _bfd_mips_elf_generic_reloc, /* special_function */
196 +        "R_MIPS16_TLS_TPREL_LO16", /* name */
197 +        TRUE,                  /* partial_inplace */
198 +        0x0000ffff,            /* src_mask */
199 +        0x0000ffff,            /* dst_mask */
200 +        FALSE),                /* pcrel_offset */
201  };
202  
203  static reloc_howto_type elf_micromips_howto_table_rel[] =
204 @@ -1796,6 +1901,15 @@ static const struct elf_reloc_map mips16_reloc_map[] =
205    { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
206    { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
207    { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
208 +  { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
209 +  { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
210 +  { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
211 +    R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
212 +  { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
213 +    R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
214 +  { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
215 +  { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
216 +  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
217  };
218  
219  static const struct elf_reloc_map micromips_reloc_map[] =
220 diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
221 index 3feb1bb..bdd0c19 100644
222 --- a/bfd/elf64-mips.c
223 +++ b/bfd/elf64-mips.c
224 @@ -1590,6 +1590,111 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
225          0x0000ffff,            /* src_mask */
226          0x0000ffff,            /* dst_mask */
227          FALSE),                /* pcrel_offset */
228 +
229 +  /* MIPS16 TLS general dynamic variable reference.  */
230 +  HOWTO (R_MIPS16_TLS_GD,      /* type */
231 +        0,                     /* rightshift */
232 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
233 +        16,                    /* bitsize */
234 +        FALSE,                 /* pc_relative */
235 +        0,                     /* bitpos */
236 +        complain_overflow_signed, /* complain_on_overflow */
237 +        _bfd_mips_elf_generic_reloc, /* special_function */
238 +        "R_MIPS16_TLS_GD",     /* name */
239 +        TRUE,                  /* partial_inplace */
240 +        0x0000ffff,            /* src_mask */
241 +        0x0000ffff,            /* dst_mask */
242 +        FALSE),                /* pcrel_offset */
243 +
244 +  /* MIPS16 TLS local dynamic variable reference.  */
245 +  HOWTO (R_MIPS16_TLS_LDM,     /* type */
246 +        0,                     /* rightshift */
247 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
248 +        16,                    /* bitsize */
249 +        FALSE,                 /* pc_relative */
250 +        0,                     /* bitpos */
251 +        complain_overflow_signed, /* complain_on_overflow */
252 +        _bfd_mips_elf_generic_reloc, /* special_function */
253 +        "R_MIPS16_TLS_LDM",    /* name */
254 +        TRUE,                  /* partial_inplace */
255 +        0x0000ffff,            /* src_mask */
256 +        0x0000ffff,            /* dst_mask */
257 +        FALSE),                /* pcrel_offset */
258 +
259 +  /* MIPS16 TLS local dynamic offset.  */
260 +  HOWTO (R_MIPS16_TLS_DTPREL_HI16,     /* type */
261 +        0,                     /* rightshift */
262 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
263 +        16,                    /* bitsize */
264 +        FALSE,                 /* pc_relative */
265 +        0,                     /* bitpos */
266 +        complain_overflow_signed, /* complain_on_overflow */
267 +        _bfd_mips_elf_generic_reloc, /* special_function */
268 +        "R_MIPS16_TLS_DTPREL_HI16",    /* name */
269 +        TRUE,                  /* partial_inplace */
270 +        0x0000ffff,            /* src_mask */
271 +        0x0000ffff,            /* dst_mask */
272 +        FALSE),                /* pcrel_offset */
273 +
274 +  /* MIPS16 TLS local dynamic offset.  */
275 +  HOWTO (R_MIPS16_TLS_DTPREL_LO16,     /* type */
276 +        0,                     /* rightshift */
277 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
278 +        16,                    /* bitsize */
279 +        FALSE,                 /* pc_relative */
280 +        0,                     /* bitpos */
281 +        complain_overflow_signed, /* complain_on_overflow */
282 +        _bfd_mips_elf_generic_reloc, /* special_function */
283 +        "R_MIPS16_TLS_DTPREL_LO16",    /* name */
284 +        TRUE,                  /* partial_inplace */
285 +        0x0000ffff,            /* src_mask */
286 +        0x0000ffff,            /* dst_mask */
287 +        FALSE),                /* pcrel_offset */
288 +
289 +  /* MIPS16 TLS thread pointer offset.  */
290 +  HOWTO (R_MIPS16_TLS_GOTTPREL,        /* type */
291 +        0,                     /* rightshift */
292 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
293 +        16,                    /* bitsize */
294 +        FALSE,                 /* pc_relative */
295 +        0,                     /* bitpos */
296 +        complain_overflow_signed, /* complain_on_overflow */
297 +        _bfd_mips_elf_generic_reloc, /* special_function */
298 +        "R_MIPS16_TLS_GOTTPREL",       /* name */
299 +        TRUE,                  /* partial_inplace */
300 +        0x0000ffff,            /* src_mask */
301 +        0x0000ffff,            /* dst_mask */
302 +        FALSE),                /* pcrel_offset */
303 +
304 +  /* MIPS16 TLS thread pointer offset.  */
305 +  HOWTO (R_MIPS16_TLS_TPREL_HI16,      /* type */
306 +        0,                     /* rightshift */
307 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
308 +        16,                    /* bitsize */
309 +        FALSE,                 /* pc_relative */
310 +        0,                     /* bitpos */
311 +        complain_overflow_signed, /* complain_on_overflow */
312 +        _bfd_mips_elf_generic_reloc, /* special_function */
313 +        "R_MIPS16_TLS_TPREL_HI16", /* name */
314 +        TRUE,                  /* partial_inplace */
315 +        0x0000ffff,            /* src_mask */
316 +        0x0000ffff,            /* dst_mask */
317 +        FALSE),                /* pcrel_offset */
318 +
319 +  /* MIPS16 TLS thread pointer offset.  */
320 +  HOWTO (R_MIPS16_TLS_TPREL_LO16,      /* type */
321 +        0,                     /* rightshift */
322 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
323 +        16,                    /* bitsize */
324 +        FALSE,                 /* pc_relative */
325 +        0,                     /* bitpos */
326 +        complain_overflow_signed, /* complain_on_overflow */
327 +        _bfd_mips_elf_generic_reloc, /* special_function */
328 +        "R_MIPS16_TLS_TPREL_LO16", /* name */
329 +        TRUE,                  /* partial_inplace */
330 +        0x0000ffff,            /* src_mask */
331 +        0x0000ffff,            /* dst_mask */
332 +        FALSE),                /* pcrel_offset */
333  };
334  
335  static reloc_howto_type mips16_elf64_howto_table_rela[] =
336 @@ -1686,6 +1791,111 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
337          0x0000ffff,            /* src_mask */
338          0x0000ffff,            /* dst_mask */
339          FALSE),                /* pcrel_offset */
340 +
341 +  /* MIPS16 TLS general dynamic variable reference.  */
342 +  HOWTO (R_MIPS16_TLS_GD,      /* type */
343 +        0,                     /* rightshift */
344 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
345 +        16,                    /* bitsize */
346 +        FALSE,                 /* pc_relative */
347 +        0,                     /* bitpos */
348 +        complain_overflow_signed, /* complain_on_overflow */
349 +        _bfd_mips_elf_generic_reloc, /* special_function */
350 +        "R_MIPS16_TLS_GD",     /* name */
351 +        FALSE,                 /* partial_inplace */
352 +        0x0000ffff,            /* src_mask */
353 +        0x0000ffff,            /* dst_mask */
354 +        FALSE),                /* pcrel_offset */
355 +
356 +  /* MIPS16 TLS local dynamic variable reference.  */
357 +  HOWTO (R_MIPS16_TLS_LDM,     /* type */
358 +        0,                     /* rightshift */
359 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
360 +        16,                    /* bitsize */
361 +        FALSE,                 /* pc_relative */
362 +        0,                     /* bitpos */
363 +        complain_overflow_signed, /* complain_on_overflow */
364 +        _bfd_mips_elf_generic_reloc, /* special_function */
365 +        "R_MIPS16_TLS_LDM",    /* name */
366 +        FALSE,                 /* partial_inplace */
367 +        0x0000ffff,            /* src_mask */
368 +        0x0000ffff,            /* dst_mask */
369 +        FALSE),                /* pcrel_offset */
370 +
371 +  /* MIPS16 TLS local dynamic offset.  */
372 +  HOWTO (R_MIPS16_TLS_DTPREL_HI16,     /* type */
373 +        0,                     /* rightshift */
374 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
375 +        16,                    /* bitsize */
376 +        FALSE,                 /* pc_relative */
377 +        0,                     /* bitpos */
378 +        complain_overflow_signed, /* complain_on_overflow */
379 +        _bfd_mips_elf_generic_reloc, /* special_function */
380 +        "R_MIPS16_TLS_DTPREL_HI16",    /* name */
381 +        FALSE,                 /* partial_inplace */
382 +        0x0000ffff,            /* src_mask */
383 +        0x0000ffff,            /* dst_mask */
384 +        FALSE),                /* pcrel_offset */
385 +
386 +  /* MIPS16 TLS local dynamic offset.  */
387 +  HOWTO (R_MIPS16_TLS_DTPREL_LO16,     /* type */
388 +        0,                     /* rightshift */
389 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
390 +        16,                    /* bitsize */
391 +        FALSE,                 /* pc_relative */
392 +        0,                     /* bitpos */
393 +        complain_overflow_signed, /* complain_on_overflow */
394 +        _bfd_mips_elf_generic_reloc, /* special_function */
395 +        "R_MIPS16_TLS_DTPREL_LO16",    /* name */
396 +        FALSE,                 /* partial_inplace */
397 +        0x0000ffff,            /* src_mask */
398 +        0x0000ffff,            /* dst_mask */
399 +        FALSE),                /* pcrel_offset */
400 +
401 +  /* MIPS16 TLS thread pointer offset.  */
402 +  HOWTO (R_MIPS16_TLS_GOTTPREL,        /* type */
403 +        0,                     /* rightshift */
404 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
405 +        16,                    /* bitsize */
406 +        FALSE,                 /* pc_relative */
407 +        0,                     /* bitpos */
408 +        complain_overflow_signed, /* complain_on_overflow */
409 +        _bfd_mips_elf_generic_reloc, /* special_function */
410 +        "R_MIPS16_TLS_GOTTPREL",       /* name */
411 +        FALSE,                 /* partial_inplace */
412 +        0x0000ffff,            /* src_mask */
413 +        0x0000ffff,            /* dst_mask */
414 +        FALSE),                /* pcrel_offset */
415 +
416 +  /* MIPS16 TLS thread pointer offset.  */
417 +  HOWTO (R_MIPS16_TLS_TPREL_HI16,      /* type */
418 +        0,                     /* rightshift */
419 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
420 +        16,                    /* bitsize */
421 +        FALSE,                 /* pc_relative */
422 +        0,                     /* bitpos */
423 +        complain_overflow_signed, /* complain_on_overflow */
424 +        _bfd_mips_elf_generic_reloc, /* special_function */
425 +        "R_MIPS16_TLS_TPREL_HI16", /* name */
426 +        FALSE,                 /* partial_inplace */
427 +        0x0000ffff,            /* src_mask */
428 +        0x0000ffff,            /* dst_mask */
429 +        FALSE),                /* pcrel_offset */
430 +
431 +  /* MIPS16 TLS thread pointer offset.  */
432 +  HOWTO (R_MIPS16_TLS_TPREL_LO16,      /* type */
433 +        0,                     /* rightshift */
434 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
435 +        16,                    /* bitsize */
436 +        FALSE,                 /* pc_relative */
437 +        0,                     /* bitpos */
438 +        complain_overflow_signed, /* complain_on_overflow */
439 +        _bfd_mips_elf_generic_reloc, /* special_function */
440 +        "R_MIPS16_TLS_TPREL_LO16", /* name */
441 +        FALSE,                 /* partial_inplace */
442 +        0x0000ffff,            /* src_mask */
443 +        0x0000ffff,            /* dst_mask */
444 +        FALSE),                /* pcrel_offset */
445  };
446  
447  static reloc_howto_type micromips_elf64_howto_table_rel[] =
448 @@ -2908,6 +3118,15 @@ static const struct elf_reloc_map mips16_reloc_map[] =
449    { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
450    { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
451    { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
452 +  { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
453 +  { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
454 +  { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
455 +    R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
456 +  { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
457 +    R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
458 +  { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
459 +  { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
460 +  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
461  };
462  
463  static const struct elf_reloc_map micromips_reloc_map[] =
464 diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
465 index 00ec8b0..2189566 100644
466 --- a/bfd/elfn32-mips.c
467 +++ b/bfd/elfn32-mips.c
468 @@ -1555,6 +1555,111 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
469          0x0000ffff,            /* src_mask */
470          0x0000ffff,            /* dst_mask */
471          FALSE),                /* pcrel_offset */
472 +
473 +  /* MIPS16 TLS general dynamic variable reference.  */
474 +  HOWTO (R_MIPS16_TLS_GD,      /* type */
475 +        0,                     /* rightshift */
476 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
477 +        16,                    /* bitsize */
478 +        FALSE,                 /* pc_relative */
479 +        0,                     /* bitpos */
480 +        complain_overflow_signed, /* complain_on_overflow */
481 +        _bfd_mips_elf_generic_reloc, /* special_function */
482 +        "R_MIPS16_TLS_GD",     /* name */
483 +        TRUE,                  /* partial_inplace */
484 +        0x0000ffff,            /* src_mask */
485 +        0x0000ffff,            /* dst_mask */
486 +        FALSE),                /* pcrel_offset */
487 +
488 +  /* MIPS16 TLS local dynamic variable reference.  */
489 +  HOWTO (R_MIPS16_TLS_LDM,     /* type */
490 +        0,                     /* rightshift */
491 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
492 +        16,                    /* bitsize */
493 +        FALSE,                 /* pc_relative */
494 +        0,                     /* bitpos */
495 +        complain_overflow_signed, /* complain_on_overflow */
496 +        _bfd_mips_elf_generic_reloc, /* special_function */
497 +        "R_MIPS16_TLS_LDM",    /* name */
498 +        TRUE,                  /* partial_inplace */
499 +        0x0000ffff,            /* src_mask */
500 +        0x0000ffff,            /* dst_mask */
501 +        FALSE),                /* pcrel_offset */
502 +
503 +  /* MIPS16 TLS local dynamic offset.  */
504 +  HOWTO (R_MIPS16_TLS_DTPREL_HI16,     /* type */
505 +        0,                     /* rightshift */
506 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
507 +        16,                    /* bitsize */
508 +        FALSE,                 /* pc_relative */
509 +        0,                     /* bitpos */
510 +        complain_overflow_signed, /* complain_on_overflow */
511 +        _bfd_mips_elf_generic_reloc, /* special_function */
512 +        "R_MIPS16_TLS_DTPREL_HI16",    /* name */
513 +        TRUE,                  /* partial_inplace */
514 +        0x0000ffff,            /* src_mask */
515 +        0x0000ffff,            /* dst_mask */
516 +        FALSE),                /* pcrel_offset */
517 +
518 +  /* MIPS16 TLS local dynamic offset.  */
519 +  HOWTO (R_MIPS16_TLS_DTPREL_LO16,     /* type */
520 +        0,                     /* rightshift */
521 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
522 +        16,                    /* bitsize */
523 +        FALSE,                 /* pc_relative */
524 +        0,                     /* bitpos */
525 +        complain_overflow_signed, /* complain_on_overflow */
526 +        _bfd_mips_elf_generic_reloc, /* special_function */
527 +        "R_MIPS16_TLS_DTPREL_LO16",    /* name */
528 +        TRUE,                  /* partial_inplace */
529 +        0x0000ffff,            /* src_mask */
530 +        0x0000ffff,            /* dst_mask */
531 +        FALSE),                /* pcrel_offset */
532 +
533 +  /* MIPS16 TLS thread pointer offset.  */
534 +  HOWTO (R_MIPS16_TLS_GOTTPREL,        /* type */
535 +        0,                     /* rightshift */
536 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
537 +        16,                    /* bitsize */
538 +        FALSE,                 /* pc_relative */
539 +        0,                     /* bitpos */
540 +        complain_overflow_signed, /* complain_on_overflow */
541 +        _bfd_mips_elf_generic_reloc, /* special_function */
542 +        "R_MIPS16_TLS_GOTTPREL",       /* name */
543 +        TRUE,                  /* partial_inplace */
544 +        0x0000ffff,            /* src_mask */
545 +        0x0000ffff,            /* dst_mask */
546 +        FALSE),                /* pcrel_offset */
547 +
548 +  /* MIPS16 TLS thread pointer offset.  */
549 +  HOWTO (R_MIPS16_TLS_TPREL_HI16,      /* type */
550 +        0,                     /* rightshift */
551 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
552 +        16,                    /* bitsize */
553 +        FALSE,                 /* pc_relative */
554 +        0,                     /* bitpos */
555 +        complain_overflow_signed, /* complain_on_overflow */
556 +        _bfd_mips_elf_generic_reloc, /* special_function */
557 +        "R_MIPS16_TLS_TPREL_HI16", /* name */
558 +        TRUE,                  /* partial_inplace */
559 +        0x0000ffff,            /* src_mask */
560 +        0x0000ffff,            /* dst_mask */
561 +        FALSE),                /* pcrel_offset */
562 +
563 +  /* MIPS16 TLS thread pointer offset.  */
564 +  HOWTO (R_MIPS16_TLS_TPREL_LO16,      /* type */
565 +        0,                     /* rightshift */
566 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
567 +        16,                    /* bitsize */
568 +        FALSE,                 /* pc_relative */
569 +        0,                     /* bitpos */
570 +        complain_overflow_signed, /* complain_on_overflow */
571 +        _bfd_mips_elf_generic_reloc, /* special_function */
572 +        "R_MIPS16_TLS_TPREL_LO16", /* name */
573 +        TRUE,                  /* partial_inplace */
574 +        0x0000ffff,            /* src_mask */
575 +        0x0000ffff,            /* dst_mask */
576 +        FALSE),                /* pcrel_offset */
577  };
578  
579  static reloc_howto_type elf_mips16_howto_table_rela[] =
580 @@ -1651,6 +1756,111 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
581          0x0000ffff,            /* src_mask */
582          0x0000ffff,            /* dst_mask */
583          FALSE),                /* pcrel_offset */
584 +
585 +  /* MIPS16 TLS general dynamic variable reference.  */
586 +  HOWTO (R_MIPS16_TLS_GD,      /* type */
587 +        0,                     /* rightshift */
588 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
589 +        16,                    /* bitsize */
590 +        FALSE,                 /* pc_relative */
591 +        0,                     /* bitpos */
592 +        complain_overflow_signed, /* complain_on_overflow */
593 +        _bfd_mips_elf_generic_reloc, /* special_function */
594 +        "R_MIPS16_TLS_GD",     /* name */
595 +        FALSE,                 /* partial_inplace */
596 +        0x0000ffff,            /* src_mask */
597 +        0x0000ffff,            /* dst_mask */
598 +        FALSE),                /* pcrel_offset */
599 +
600 +  /* MIPS16 TLS local dynamic variable reference.  */
601 +  HOWTO (R_MIPS16_TLS_LDM,     /* type */
602 +        0,                     /* rightshift */
603 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
604 +        16,                    /* bitsize */
605 +        FALSE,                 /* pc_relative */
606 +        0,                     /* bitpos */
607 +        complain_overflow_signed, /* complain_on_overflow */
608 +        _bfd_mips_elf_generic_reloc, /* special_function */
609 +        "R_MIPS16_TLS_LDM",    /* name */
610 +        FALSE,                 /* partial_inplace */
611 +        0x0000ffff,            /* src_mask */
612 +        0x0000ffff,            /* dst_mask */
613 +        FALSE),                /* pcrel_offset */
614 +
615 +  /* MIPS16 TLS local dynamic offset.  */
616 +  HOWTO (R_MIPS16_TLS_DTPREL_HI16,     /* type */
617 +        0,                     /* rightshift */
618 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
619 +        16,                    /* bitsize */
620 +        FALSE,                 /* pc_relative */
621 +        0,                     /* bitpos */
622 +        complain_overflow_signed, /* complain_on_overflow */
623 +        _bfd_mips_elf_generic_reloc, /* special_function */
624 +        "R_MIPS16_TLS_DTPREL_HI16",    /* name */
625 +        FALSE,                 /* partial_inplace */
626 +        0x0000ffff,            /* src_mask */
627 +        0x0000ffff,            /* dst_mask */
628 +        FALSE),                /* pcrel_offset */
629 +
630 +  /* MIPS16 TLS local dynamic offset.  */
631 +  HOWTO (R_MIPS16_TLS_DTPREL_LO16,     /* type */
632 +        0,                     /* rightshift */
633 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
634 +        16,                    /* bitsize */
635 +        FALSE,                 /* pc_relative */
636 +        0,                     /* bitpos */
637 +        complain_overflow_signed, /* complain_on_overflow */
638 +        _bfd_mips_elf_generic_reloc, /* special_function */
639 +        "R_MIPS16_TLS_DTPREL_LO16",    /* name */
640 +        FALSE,                 /* partial_inplace */
641 +        0x0000ffff,            /* src_mask */
642 +        0x0000ffff,            /* dst_mask */
643 +        FALSE),                /* pcrel_offset */
644 +
645 +  /* MIPS16 TLS thread pointer offset.  */
646 +  HOWTO (R_MIPS16_TLS_GOTTPREL,        /* type */
647 +        0,                     /* rightshift */
648 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
649 +        16,                    /* bitsize */
650 +        FALSE,                 /* pc_relative */
651 +        0,                     /* bitpos */
652 +        complain_overflow_signed, /* complain_on_overflow */
653 +        _bfd_mips_elf_generic_reloc, /* special_function */
654 +        "R_MIPS16_TLS_GOTTPREL",       /* name */
655 +        FALSE,                 /* partial_inplace */
656 +        0x0000ffff,            /* src_mask */
657 +        0x0000ffff,            /* dst_mask */
658 +        FALSE),                /* pcrel_offset */
659 +
660 +  /* MIPS16 TLS thread pointer offset.  */
661 +  HOWTO (R_MIPS16_TLS_TPREL_HI16,      /* type */
662 +        0,                     /* rightshift */
663 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
664 +        16,                    /* bitsize */
665 +        FALSE,                 /* pc_relative */
666 +        0,                     /* bitpos */
667 +        complain_overflow_signed, /* complain_on_overflow */
668 +        _bfd_mips_elf_generic_reloc, /* special_function */
669 +        "R_MIPS16_TLS_TPREL_HI16", /* name */
670 +        FALSE,                 /* partial_inplace */
671 +        0x0000ffff,            /* src_mask */
672 +        0x0000ffff,            /* dst_mask */
673 +        FALSE),                /* pcrel_offset */
674 +
675 +  /* MIPS16 TLS thread pointer offset.  */
676 +  HOWTO (R_MIPS16_TLS_TPREL_LO16,      /* type */
677 +        0,                     /* rightshift */
678 +        2,                     /* size (0 = byte, 1 = short, 2 = long) */
679 +        16,                    /* bitsize */
680 +        FALSE,                 /* pc_relative */
681 +        0,                     /* bitpos */
682 +        complain_overflow_signed, /* complain_on_overflow */
683 +        _bfd_mips_elf_generic_reloc, /* special_function */
684 +        "R_MIPS16_TLS_TPREL_LO16", /* name */
685 +        FALSE,                 /* partial_inplace */
686 +        0x0000ffff,            /* src_mask */
687 +        0x0000ffff,            /* dst_mask */
688 +        FALSE),                /* pcrel_offset */
689  };
690  
691  static reloc_howto_type elf_micromips_howto_table_rel[] =
692 @@ -2724,6 +2934,15 @@ static const struct elf_reloc_map mips16_reloc_map[] =
693    { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
694    { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
695    { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
696 +  { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
697 +  { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
698 +  { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
699 +    R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
700 +  { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
701 +    R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
702 +  { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
703 +  { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
704 +  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
705  };
706  
707  static const struct elf_reloc_map micromips_reloc_map[] =
708 diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
709 index 9f3833b..fa906cd 100644
710 --- a/bfd/elfxx-mips.c
711 +++ b/bfd/elfxx-mips.c
712 @@ -529,6 +529,13 @@ struct mips_htab_traverse_info
713     || r_type == R_MIPS_TLS_TPREL64             \
714     || r_type == R_MIPS_TLS_TPREL_HI16          \
715     || r_type == R_MIPS_TLS_TPREL_LO16          \
716 +   || r_type == R_MIPS16_TLS_GD                        \
717 +   || r_type == R_MIPS16_TLS_LDM               \
718 +   || r_type == R_MIPS16_TLS_DTPREL_HI16       \
719 +   || r_type == R_MIPS16_TLS_DTPREL_LO16       \
720 +   || r_type == R_MIPS16_TLS_GOTTPREL          \
721 +   || r_type == R_MIPS16_TLS_TPREL_HI16                \
722 +   || r_type == R_MIPS16_TLS_TPREL_LO16                \
723     || r_type == R_MICROMIPS_TLS_GD             \
724     || r_type == R_MICROMIPS_TLS_LDM            \
725     || r_type == R_MICROMIPS_TLS_DTPREL_HI16    \
726 @@ -1885,6 +1892,13 @@ mips16_reloc_p (int r_type)
727      case R_MIPS16_CALL16:
728      case R_MIPS16_HI16:
729      case R_MIPS16_LO16:
730 +    case R_MIPS16_TLS_GD:
731 +    case R_MIPS16_TLS_LDM:
732 +    case R_MIPS16_TLS_DTPREL_HI16:
733 +    case R_MIPS16_TLS_DTPREL_LO16:
734 +    case R_MIPS16_TLS_GOTTPREL:
735 +    case R_MIPS16_TLS_TPREL_HI16:
736 +    case R_MIPS16_TLS_TPREL_LO16:
737        return TRUE;
738  
739      default:
740 @@ -2012,19 +2026,25 @@ micromips_branch_reloc_p (int r_type)
741  static inline bfd_boolean
742  tls_gd_reloc_p (unsigned int r_type)
743  {
744 -  return r_type == R_MIPS_TLS_GD || r_type == R_MICROMIPS_TLS_GD;
745 +  return (r_type == R_MIPS_TLS_GD
746 +         || r_type == R_MIPS16_TLS_GD
747 +         || r_type == R_MICROMIPS_TLS_GD);
748  }
749  
750  static inline bfd_boolean
751  tls_ldm_reloc_p (unsigned int r_type)
752  {
753 -  return r_type == R_MIPS_TLS_LDM || r_type == R_MICROMIPS_TLS_LDM;
754 +  return (r_type == R_MIPS_TLS_LDM
755 +         || r_type == R_MIPS16_TLS_LDM
756 +         || r_type == R_MICROMIPS_TLS_LDM);
757  }
758  
759  static inline bfd_boolean
760  tls_gottprel_reloc_p (unsigned int r_type)
761  {
762 -  return r_type == R_MIPS_TLS_GOTTPREL || r_type == R_MICROMIPS_TLS_GOTTPREL;
763 +  return (r_type == R_MIPS_TLS_GOTTPREL
764 +         || r_type == R_MIPS16_TLS_GOTTPREL
765 +         || r_type == R_MICROMIPS_TLS_GOTTPREL);
766  }
767  
768  void
769 @@ -5361,6 +5381,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
770      case R_MIPS_TLS_GD:
771      case R_MIPS_TLS_GOTTPREL:
772      case R_MIPS_TLS_LDM:
773 +    case R_MIPS16_TLS_GD:
774 +    case R_MIPS16_TLS_GOTTPREL:
775 +    case R_MIPS16_TLS_LDM:
776      case R_MICROMIPS_TLS_GD:
777      case R_MICROMIPS_TLS_GOTTPREL:
778      case R_MICROMIPS_TLS_LDM:
779 @@ -5530,6 +5553,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
780        break;
781  
782      case R_MIPS_TLS_DTPREL_HI16:
783 +    case R_MIPS16_TLS_DTPREL_HI16:
784      case R_MICROMIPS_TLS_DTPREL_HI16:
785        value = (mips_elf_high (addend + symbol - dtprel_base (info))
786                & howto->dst_mask);
787 @@ -5538,17 +5562,22 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
788      case R_MIPS_TLS_DTPREL_LO16:
789      case R_MIPS_TLS_DTPREL32:
790      case R_MIPS_TLS_DTPREL64:
791 +    case R_MIPS16_TLS_DTPREL_LO16:
792      case R_MICROMIPS_TLS_DTPREL_LO16:
793        value = (symbol + addend - dtprel_base (info)) & howto->dst_mask;
794        break;
795  
796      case R_MIPS_TLS_TPREL_HI16:
797 +    case R_MIPS16_TLS_TPREL_HI16:
798      case R_MICROMIPS_TLS_TPREL_HI16:
799        value = (mips_elf_high (addend + symbol - tprel_base (info))
800                & howto->dst_mask);
801        break;
802  
803      case R_MIPS_TLS_TPREL_LO16:
804 +    case R_MIPS_TLS_TPREL32:
805 +    case R_MIPS_TLS_TPREL64:
806 +    case R_MIPS16_TLS_TPREL_LO16:
807      case R_MICROMIPS_TLS_TPREL_LO16:
808        value = (symbol + addend - tprel_base (info)) & howto->dst_mask;
809        break;
810 @@ -5681,6 +5710,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
811      case R_MIPS_TLS_GOTTPREL:
812      case R_MIPS_TLS_LDM:
813      case R_MIPS_GOT_DISP:
814 +    case R_MIPS16_TLS_GD:
815 +    case R_MIPS16_TLS_GOTTPREL:
816 +    case R_MIPS16_TLS_LDM:
817      case R_MICROMIPS_TLS_GD:
818      case R_MICROMIPS_TLS_GOTTPREL:
819      case R_MICROMIPS_TLS_LDM:
820 @@ -7813,8 +7845,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
821        can_make_dynamic_p = FALSE;
822        switch (r_type)
823         {
824 -       case R_MIPS16_GOT16:
825 -       case R_MIPS16_CALL16:
826         case R_MIPS_GOT16:
827         case R_MIPS_CALL16:
828         case R_MIPS_CALL_HI16:
829 @@ -7827,6 +7857,11 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
830         case R_MIPS_TLS_GOTTPREL:
831         case R_MIPS_TLS_GD:
832         case R_MIPS_TLS_LDM:
833 +       case R_MIPS16_GOT16:
834 +       case R_MIPS16_CALL16:
835 +       case R_MIPS16_TLS_GOTTPREL:
836 +       case R_MIPS16_TLS_GD:
837 +       case R_MIPS16_TLS_LDM:
838         case R_MICROMIPS_GOT16:
839         case R_MICROMIPS_CALL16:
840         case R_MICROMIPS_CALL_HI16:
841 @@ -8063,12 +8098,14 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
842           break;
843  
844         case R_MIPS_TLS_GOTTPREL:
845 +       case R_MIPS16_TLS_GOTTPREL:
846         case R_MICROMIPS_TLS_GOTTPREL:
847           if (info->shared)
848             info->flags |= DF_STATIC_TLS;
849           /* Fall through */
850  
851         case R_MIPS_TLS_LDM:
852 +       case R_MIPS16_TLS_LDM:
853         case R_MICROMIPS_TLS_LDM:
854           if (tls_ldm_reloc_p (r_type))
855             {
856 @@ -8078,6 +8115,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
857           /* Fall through */
858  
859         case R_MIPS_TLS_GD:
860 +       case R_MIPS16_TLS_GD:
861         case R_MICROMIPS_TLS_GD:
862           /* This symbol requires a global offset table entry, or two
863              for TLS GD relocations.  */
864 diff --git a/bfd/libbfd.h b/bfd/libbfd.h
865 index 200a6fa..0395ec2 100644
866 --- a/bfd/libbfd.h
867 +++ b/bfd/libbfd.h
868 @@ -1086,6 +1086,13 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
869    "BFD_RELOC_MIPS16_HI16",
870    "BFD_RELOC_MIPS16_HI16_S",
871    "BFD_RELOC_MIPS16_LO16",
872 +  "BFD_RELOC_MIPS16_TLS_GD",
873 +  "BFD_RELOC_MIPS16_TLS_LDM",
874 +  "BFD_RELOC_MIPS16_TLS_DTPREL_HI16",
875 +  "BFD_RELOC_MIPS16_TLS_DTPREL_LO16",
876 +  "BFD_RELOC_MIPS16_TLS_GOTTPREL",
877 +  "BFD_RELOC_MIPS16_TLS_TPREL_HI16",
878 +  "BFD_RELOC_MIPS16_TLS_TPREL_LO16",
879    "BFD_RELOC_MIPS_LITERAL",
880    "BFD_RELOC_MICROMIPS_LITERAL",
881    "BFD_RELOC_MICROMIPS_7_PCREL_S1",
882 diff --git a/bfd/reloc.c b/bfd/reloc.c
883 index 6ac7148..ef55cc3 100644
884 --- a/bfd/reloc.c
885 +++ b/bfd/reloc.c
886 @@ -2247,6 +2247,23 @@ ENUMDOC
887    MIPS16 low 16 bits.
888  
889  ENUM
890 +  BFD_RELOC_MIPS16_TLS_GD
891 +ENUMX
892 +  BFD_RELOC_MIPS16_TLS_LDM
893 +ENUMX
894 +  BFD_RELOC_MIPS16_TLS_DTPREL_HI16
895 +ENUMX
896 +  BFD_RELOC_MIPS16_TLS_DTPREL_LO16
897 +ENUMX
898 +  BFD_RELOC_MIPS16_TLS_GOTTPREL
899 +ENUMX
900 +  BFD_RELOC_MIPS16_TLS_TPREL_HI16
901 +ENUMX
902 +  BFD_RELOC_MIPS16_TLS_TPREL_LO16
903 +ENUMDOC
904 +  MIPS16 TLS relocations
905 +
906 +ENUM
907    BFD_RELOC_MIPS_LITERAL
908  ENUMX
909    BFD_RELOC_MICROMIPS_LITERAL
910 diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
911 index 0e4c66e..0fb3a6e 100644
912 --- a/gas/config/tc-mips.c
913 +++ b/gas/config/tc-mips.c
914 @@ -1352,6 +1352,8 @@ static void s_cprestore (int);
915  static void s_cpreturn (int);
916  static void s_dtprelword (int);
917  static void s_dtpreldword (int);
918 +static void s_tprelword (int);
919 +static void s_tpreldword (int);
920  static void s_gpvalue (int);
921  static void s_gpword (int);
922  static void s_gpdword (int);
923 @@ -1431,6 +1433,8 @@ static const pseudo_typeS mips_pseudo_table[] =
924    {"cpreturn", s_cpreturn, 0},
925    {"dtprelword", s_dtprelword, 0},
926    {"dtpreldword", s_dtpreldword, 0},
927 +  {"tprelword", s_tprelword, 0},
928 +  {"tpreldword", s_tpreldword, 0},
929    {"gpvalue", s_gpvalue, 0},
930    {"gpword", s_gpword, 0},
931    {"gpdword", s_gpdword, 0},
932 @@ -14040,7 +14044,14 @@ static const struct percent_op_match mips16_percent_op[] =
933    {"%gprel", BFD_RELOC_MIPS16_GPREL},
934    {"%got", BFD_RELOC_MIPS16_GOT16},
935    {"%call16", BFD_RELOC_MIPS16_CALL16},
936 -  {"%hi", BFD_RELOC_MIPS16_HI16_S}
937 +  {"%hi", BFD_RELOC_MIPS16_HI16_S},
938 +  {"%tlsgd", BFD_RELOC_MIPS16_TLS_GD},
939 +  {"%tlsldm", BFD_RELOC_MIPS16_TLS_LDM},
940 +  {"%dtprel_hi", BFD_RELOC_MIPS16_TLS_DTPREL_HI16},
941 +  {"%dtprel_lo", BFD_RELOC_MIPS16_TLS_DTPREL_LO16},
942 +  {"%tprel_hi", BFD_RELOC_MIPS16_TLS_TPREL_HI16},
943 +  {"%tprel_lo", BFD_RELOC_MIPS16_TLS_TPREL_LO16},
944 +  {"%gottprel", BFD_RELOC_MIPS16_TLS_GOTTPREL}
945  };
946  
947  
948 @@ -15369,6 +15380,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
949      case BFD_RELOC_MIPS_TLS_DTPREL_HI16:
950      case BFD_RELOC_MIPS_TLS_DTPREL_LO16:
951      case BFD_RELOC_MIPS_TLS_GOTTPREL:
952 +    case BFD_RELOC_MIPS_TLS_TPREL32:
953 +    case BFD_RELOC_MIPS_TLS_TPREL64:
954      case BFD_RELOC_MIPS_TLS_TPREL_HI16:
955      case BFD_RELOC_MIPS_TLS_TPREL_LO16:
956      case BFD_RELOC_MICROMIPS_TLS_GD:
957 @@ -15378,6 +15391,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
958      case BFD_RELOC_MICROMIPS_TLS_GOTTPREL:
959      case BFD_RELOC_MICROMIPS_TLS_TPREL_HI16:
960      case BFD_RELOC_MICROMIPS_TLS_TPREL_LO16:
961 +    case BFD_RELOC_MIPS16_TLS_GD:
962 +    case BFD_RELOC_MIPS16_TLS_LDM:
963 +    case BFD_RELOC_MIPS16_TLS_DTPREL_HI16:
964 +    case BFD_RELOC_MIPS16_TLS_DTPREL_LO16:
965 +    case BFD_RELOC_MIPS16_TLS_GOTTPREL:
966 +    case BFD_RELOC_MIPS16_TLS_TPREL_HI16:
967 +    case BFD_RELOC_MIPS16_TLS_TPREL_LO16:
968        S_SET_THREAD_LOCAL (fixP->fx_addsy);
969        /* fall through */
970  
971 @@ -16547,12 +16567,14 @@ s_cpreturn (int ignore ATTRIBUTE_UNUSED)
972    demand_empty_rest_of_line ();
973  }
974  
975 -/* Handle the .dtprelword and .dtpreldword pseudo-ops.  They generate
976 -   a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
977 -   use in DWARF debug information.  */
978 +/* Handle a .dtprelword, .dtpreldword, .tprelword, or .tpreldword
979 +   pseudo-op; DIRSTR says which. The pseudo-op generates a BYTES-size
980 +   DTP- or TP-relative relocation of type RTYPE, for use in either DWARF
981 +   debug information or MIPS16 TLS.  */
982  
983  static void
984 -s_dtprel_internal (size_t bytes)
985 +s_tls_rel_directive (const size_t bytes, const char *dirstr,
986 +                    bfd_reloc_code_real_type rtype)
987  {
988    expressionS ex;
989    char *p;
990 @@ -16561,19 +16583,13 @@ s_dtprel_internal (size_t bytes)
991  
992    if (ex.X_op != O_symbol)
993      {
994 -      as_bad (_("Unsupported use of %s"), (bytes == 8
995 -                                          ? ".dtpreldword"
996 -                                          : ".dtprelword"));
997 +      as_bad (_("Unsupported use of %s"), dirstr);
998        ignore_rest_of_line ();
999      }
1000  
1001    p = frag_more (bytes);
1002    md_number_to_chars (p, 0, bytes);
1003 -  fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
1004 -              (bytes == 8
1005 -               ? BFD_RELOC_MIPS_TLS_DTPREL64
1006 -               : BFD_RELOC_MIPS_TLS_DTPREL32));
1007 -
1008 +  fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE, rtype);
1009    demand_empty_rest_of_line ();
1010  }
1011  
1012 @@ -16582,7 +16598,7 @@ s_dtprel_internal (size_t bytes)
1013  static void
1014  s_dtprelword (int ignore ATTRIBUTE_UNUSED)
1015  {
1016 -  s_dtprel_internal (4);
1017 +  s_tls_rel_directive (4, ".dtprelword", BFD_RELOC_MIPS_TLS_DTPREL32);
1018  }
1019  
1020  /* Handle .dtpreldword.  */
1021 @@ -16590,7 +16606,23 @@ s_dtprelword (int ignore ATTRIBUTE_UNUSED)
1022  static void
1023  s_dtpreldword (int ignore ATTRIBUTE_UNUSED)
1024  {
1025 -  s_dtprel_internal (8);
1026 +  s_tls_rel_directive (8, ".dtpreldword", BFD_RELOC_MIPS_TLS_DTPREL64);
1027 +}
1028 +
1029 +/* Handle .tprelword.  */
1030 +
1031 +static void
1032 +s_tprelword (int ignore ATTRIBUTE_UNUSED)
1033 +{
1034 +  s_tls_rel_directive (4, ".tprelword", BFD_RELOC_MIPS_TLS_TPREL32);
1035 +}
1036 +
1037 +/* Handle .tpreldword.  */
1038 +
1039 +static void
1040 +s_tpreldword (int ignore ATTRIBUTE_UNUSED)
1041 +{
1042 +  s_tls_rel_directive (8, ".tpreldword", BFD_RELOC_MIPS_TLS_TPREL64);
1043  }
1044  
1045  /* Handle the .gpvalue pseudo-op.  This is used when generating NewABI PIC
1046 diff --git a/include/elf/mips.h b/include/elf/mips.h
1047 index db5fa54..c2c5922 100644
1048 --- a/include/elf/mips.h
1049 +++ b/include/elf/mips.h
1050 @@ -98,7 +98,14 @@ START_RELOC_NUMBERS (elf_mips_reloc_type)
1051    RELOC_NUMBER (R_MIPS16_CALL16, 103)
1052    RELOC_NUMBER (R_MIPS16_HI16, 104)
1053    RELOC_NUMBER (R_MIPS16_LO16, 105)
1054 -  FAKE_RELOC (R_MIPS16_max, 106)
1055 +  RELOC_NUMBER (R_MIPS16_TLS_GD, 106)
1056 +  RELOC_NUMBER (R_MIPS16_TLS_LDM, 107)
1057 +  RELOC_NUMBER (R_MIPS16_TLS_DTPREL_HI16, 108)
1058 +  RELOC_NUMBER (R_MIPS16_TLS_DTPREL_LO16, 109)
1059 +  RELOC_NUMBER (R_MIPS16_TLS_GOTTPREL, 110)
1060 +  RELOC_NUMBER (R_MIPS16_TLS_TPREL_HI16, 111)
1061 +  RELOC_NUMBER (R_MIPS16_TLS_TPREL_LO16, 112)
1062 +  FAKE_RELOC (R_MIPS16_max, 113)
1063    /* These relocations are specific to VxWorks.  */
1064    RELOC_NUMBER (R_MIPS_COPY, 126)
1065    RELOC_NUMBER (R_MIPS_JUMP_SLOT, 127)
1066 -- 
1067 1.7.9.5
1068