2222#ifndef ARC_GOT_H
2323#define ARC_GOT_H
2424
25+ /* Thread Control Block (TCB) contains at offset zero a pointer to the
26+ dynamic thread vector dtvt for the thread. */
2527#if ARCH_SIZE == 32
2628#define TCB_SIZE (8)
2729#else
@@ -303,56 +305,58 @@ relocate_fix_got_relocs_for_got_info (struct got_entry **list_p,
303305 && SYMBOL_REFERENCES_LOCAL (info , h ))))
304306 {
305307 const char ATTRIBUTE_UNUSED * symbol_name ;
306- static const char local_name [] = "(local)" ;
307- asection * tls_sec = NULL ;
308+ static const char * local_name = "(local)" ;
308309 bfd_vma sym_value = 0 ;
310+ asection * sec = NULL ;
309311
310312 if (h != NULL )
311313 {
312- /* TODO: This should not be here. */
313314 reloc_data -> sym_value = h -> root .u .def .value ;
314315 reloc_data -> sym_section = h -> root .u .def .section ;
315316
316- if (h -> root .u .def .section -> output_section != NULL )
317- sym_value = h -> root .u .def .value
318- + h -> root .u .def .section -> output_section -> vma
319- + h -> root .u .def .section -> output_offset ;
320-
321- tls_sec = elf_hash_table (info )-> tls_sec ;
322-
317+ sec = h -> root .u .def .section ;
318+ sym_value = h -> root .u .def .value ;
323319 symbol_name = h -> root .root .string ;
324320 }
325321 else
326322 {
327323 Elf_Internal_Sym * sym = local_syms + r_symndx ;
328- asection * sec = local_sections [r_symndx ];
329-
330- sym_value = sym -> st_value
331- + sec -> output_section -> vma
332- + sec -> output_offset ;
333-
334- tls_sec = elf_hash_table (info )-> tls_sec ;
335324
325+ sec = local_sections [r_symndx ];
326+ sym_value = sym -> st_value ;
336327 symbol_name = local_name ;
337328 }
338329
339330 if (entry && !entry -> processed )
340331 {
332+ int tcb_size = 0 ;
333+
341334 switch (entry -> type )
342335 {
336+ case GOT_TLS_IE :
337+ tcb_size = TCB_SIZE ;
338+ /* Fall through. */
343339 case GOT_TLS_GD :
344340 {
341+ asection * tls_sec = elf_hash_table (info )-> tls_sec ;
342+
345343 BFD_ASSERT (tls_sec && tls_sec -> output_section );
346- bfd_vma sec_vma = tls_sec -> output_section -> vma ;
344+ bfd_vma tls_vma = tls_sec -> output_section -> vma ;
345+
346+ BFD_ASSERT (sec -> output_section );
347+ sym_value += sec -> output_section -> vma + sec -> output_offset ;
347348
348- if (h == NULL || h -> forced_local
349- || !elf_hash_table (info )-> dynamic_sections_created )
349+ if (h == NULL
350+ || h -> forced_local
351+ || !elf_hash_table (info )-> dynamic_sections_created )
350352 {
351353 write_in_got
352354 (output_bfd ,
353- sym_value - sec_vma
355+ /* S - TLS_REL + { round (TCB_SIZE, align), 0 } */
356+ sym_value - tls_vma
354357 + (elf_hash_table (info )-> dynamic_sections_created
355- ? 0 : (align_power (0 , tls_sec -> alignment_power ))),
358+ ? 0 : (align_power (tcb_size ,
359+ tls_sec -> alignment_power ))),
356360 htab -> sgot -> contents + entry -> offset
357361 + (entry -> existing_entries == TLS_GOT_MOD_AND_OFF
358362 ? GOT_ENTRY_SIZE : 0 ));
@@ -362,7 +366,7 @@ relocate_fix_got_relocs_for_got_info (struct got_entry **list_p,
362366 "@ %lx, for symbol %s\n" ,
363367 (entry -> type == GOT_TLS_GD ? "GOT_TLS_GD" :
364368 "GOT_TLS_IE" ),
365- (long ) (sym_value - sec_vma ),
369+ (long ) (sym_value - tls_vma ),
366370 (long ) (htab -> sgot -> output_section -> vma
367371 + htab -> sgot -> output_offset
368372 + entry -> offset
@@ -373,44 +377,12 @@ relocate_fix_got_relocs_for_got_info (struct got_entry **list_p,
373377 }
374378 break ;
375379
376- case GOT_TLS_IE :
377- {
378- BFD_ASSERT (tls_sec && tls_sec -> output_section );
379- bfd_vma ATTRIBUTE_UNUSED sec_vma
380- = tls_sec -> output_section -> vma ;
381-
382- if (h == NULL || h -> forced_local
383- || !elf_hash_table (info )-> dynamic_sections_created )
384- {
385- write_in_got (output_bfd ,
386- sym_value - sec_vma
387- + (elf_hash_table (info )-> dynamic_sections_created
388- ? 0
389- : (align_power (TCB_SIZE ,
390- tls_sec -> alignment_power ))),
391- htab -> sgot -> contents + entry -> offset
392- + (entry -> existing_entries == TLS_GOT_MOD_AND_OFF
393- ? GOT_ENTRY_SIZE : 0 ));
394-
395- ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
396- "@ %p, for symbol %s\n" ,
397- (entry -> type == GOT_TLS_GD ? "GOT_TLS_GD" :
398- "GOT_TLS_IE" ),
399- (long ) (sym_value - sec_vma ),
400- (void * ) (htab -> sgot -> output_section -> vma
401- + htab -> sgot -> output_offset
402- + entry -> offset
403- + (entry -> existing_entries == TLS_GOT_MOD_AND_OFF
404- ? GOT_ENTRY_SIZE : 0 )),
405- symbol_name );
406- }
407- }
408- break ;
409-
410380 case GOT_NORMAL :
411381 {
412- if (h != NULL
413- && h -> root .type == bfd_link_hash_undefweak )
382+ BFD_ASSERT (h );
383+ if (h -> root .type == bfd_link_hash_undefweak
384+ /* FIXME! catch the undefined situation in a test. */
385+ || h -> root .type == bfd_link_hash_undefined )
414386 ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
415387 "@ %#08lx for sym %s in got offset %#lx "
416388 "(is undefweak)\n" ,
@@ -421,16 +393,16 @@ relocate_fix_got_relocs_for_got_info (struct got_entry **list_p,
421393 (long ) entry -> offset );
422394 else
423395 {
424- bfd_vma sec_vma
425- = reloc_data -> sym_section -> output_section -> vma
426- + reloc_data -> sym_section -> output_offset ;
396+ BFD_ASSERT ( sec -> output_section );
397+
398+ sym_value += sec -> output_section -> vma + sec -> output_offset ;
427399
428400 write_in_got (output_bfd ,
429- reloc_data -> sym_value + sec_vma ,
401+ sym_value ,
430402 htab -> sgot -> contents + entry -> offset );
431403 ARC_DEBUG ("arc_info: PATCHED: %#08lx "
432404 "@ %#08lx for sym %s in got offset %#lx\n" ,
433- (long ) ( reloc_data -> sym_value + sec_vma ) ,
405+ (long ) sym_value ,
434406 (long ) (htab -> sgot -> output_section -> vma
435407 + htab -> sgot -> output_offset
436408 + entry -> offset ),
0 commit comments