@@ -2417,24 +2417,22 @@ GOT_ENTRY_OFFSET = %#lx, GOT_ENTRY_VMA = %#lx, for symbol %s\n",
24172417 }
24182418}
24192419
2420+ /* Initialize the PLT with ARC specific PLT header. See arc-plt.def.
2421+ Use middle-endian to fill in the data as it is executable code. */
2422+
24202423static void
24212424relocate_plt_for_entry (bfd * abfd ,
24222425 struct bfd_link_info * info )
24232426{
24242427 const struct plt_version_t * plt_data = arc_get_plt_version (info );
24252428 struct elf_link_hash_table * htab = elf_hash_table (info );
2429+ bfd_vma i = 0 ;
2430+ uint16_t * ptr = (uint16_t * ) plt_data -> entry ;
24262431
2427- {
2428- bfd_vma i = 0 ;
2429- uint16_t * ptr = (uint16_t * ) plt_data -> entry ;
2430- for (i = 0 ; i < plt_data -> entry_size /2 ; i ++ )
2431- {
2432- uint16_t data = ptr [i ];
2433- bfd_put_16 (abfd ,
2434- (bfd_vma ) data ,
2435- htab -> splt -> contents + (i * 2 ));
2436- }
2437- }
2432+ for (i = 0 ; i < plt_data -> entry_size /2 ; i ++ )
2433+ {
2434+ bfd_put_16 (abfd , (bfd_vma ) ptr [i ], htab -> splt -> contents + (i * 2 ));
2435+ }
24382436 PLT_DO_RELOCS_FOR_ENTRY (abfd , htab , plt_data -> entry_relocs );
24392437}
24402438
@@ -2693,13 +2691,15 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd,
26932691 asection * sdyn = bfd_get_linker_section (dynobj , ".dynamic" );
26942692 const struct elf_backend_data * bed = get_elf_backend_data (output_bfd );
26952693
2694+ /* TODO: instead of checking for sdyn, we can use elf_hash_table
2695+ (info)->dynamic_sections_created to see if we have dynamic
2696+ sections creared. */
26962697 if (sdyn )
26972698 {
26982699 ElfNN_External_Dyn * dyncon , * dynconend ;
26992700
27002701 dyncon = (ElfNN_External_Dyn * ) sdyn -> contents ;
2701- dynconend
2702- = (ElfNN_External_Dyn * ) (sdyn -> contents + sdyn -> size );
2702+ dynconend = (ElfNN_External_Dyn * ) (sdyn -> contents + sdyn -> size );
27032703 for (; dyncon < dynconend ; dyncon ++ )
27042704 {
27052705 Elf_Internal_Dyn internal_dyn ;
@@ -2775,6 +2775,7 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd,
27752775 bed -> s -> swap_dyn_out (output_bfd , & internal_dyn , dyncon );
27762776 }
27772777
2778+ /* Fill in the first entry in the procedure linkage table. */
27782779 if (htab -> splt -> size > 0 )
27792780 {
27802781 relocate_plt_for_entry (output_bfd , info );
@@ -2789,28 +2790,32 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd,
27892790 /* Fill in the first three entries in the global offset table. */
27902791 if (htab -> sgot )
27912792 {
2792- struct elf_link_hash_entry * h ;
2793- h = elf_link_hash_lookup (elf_hash_table (info ), "_GLOBAL_OFFSET_TABLE_" ,
2794- false, false, true);
2793+ struct elf_link_hash_entry * got ;
2794+ /* Get the hash entry of the first GOT entry. */
2795+ got = elf_link_hash_lookup (elf_hash_table (info ),
2796+ "_GLOBAL_OFFSET_TABLE_" , false, false, true);
27952797
2796- if (h != NULL && h -> root .type != bfd_link_hash_undefined
2797- && h -> root .u .def .section != NULL )
2798+ if (got != NULL
2799+ && got -> root .type != bfd_link_hash_undefined
2800+ && got -> root .u .def .section != NULL )
27982801 {
2799- asection * sec = h -> root .u .def .section ;
2802+ asection * sec = got -> root .u .def .section ;
2803+ bfd_vma dyn_vma = 0 ;
28002804
2801- if (sdyn == NULL )
2805+ /* Check if we participate in a dynamic linking. */
2806+ if (sdyn )
28022807 {
2803- write_in_got (output_bfd , (bfd_vma ) 0 ,
2804- sec -> contents );
2805- }
2806- else
2807- {
2808- write_in_got (output_bfd ,
2809- sdyn -> output_section -> vma + sdyn -> output_offset ,
2810- sec -> contents );
2808+ /* Get the unrelocated address of the _DYNAMIC, which is
2809+ the start of the start of the dynamic sction. */
2810+ dyn_vma = sdyn -> output_section -> vma + sdyn -> output_offset ;
28112811 }
2812+
2813+ /* _GLOBAL_OFFSET_TABLE_[0] = VMA (.dynamic) */
2814+ write_in_got (output_bfd , dyn_vma , sec -> contents );
2815+ /* _GLOBAL_OFFSET_TABLE_[1] = 0. Reserved for dynamic linker. */
28122816 write_in_got (output_bfd , (bfd_vma ) 0 ,
28132817 sec -> contents + (GOT_ENTRY_SIZE ));
2818+ /* _GLOBAL_OFFSET_TABLE_[2] = 0. Reserved for dynamic linker. */
28142819 write_in_got (output_bfd , (bfd_vma ) 0 ,
28152820 sec -> contents + (GOT_ENTRY_SIZE * 2 ));
28162821 }
0 commit comments