@ -249,7 +249,7 @@
| | ( R_TYPE ) = = BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
| | ( R_TYPE ) = = BFD_RELOC_AARCH64_TLSDESC_OFF_G1 )
# define ELIMINATE_COPY_RELOCS 0
# define ELIMINATE_COPY_RELOCS 1
/* Return size of a relocation entry. HTAB is the bfd's
elf_aarch64_link_hash_entry . */
@ -5169,12 +5169,25 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
/* When generating a shared object or relocatable executable, these
relocations are copied into the output file to be resolved at
run time . */
if ( ( bfd_link_pic ( info )
| | globals - > root . is_relocatable_executable )
& & ( input_section - > flags & SEC_ALLOC )
& & ( h = = NULL
| | ELF_ST_VISIBILITY ( h - > other ) = = STV_DEFAULT
| | h - > root . type ! = bfd_link_hash_undefweak ) )
if ( ( ( bfd_link_pic ( info )
| | globals - > root . is_relocatable_executable )
& & ( input_section - > flags & SEC_ALLOC )
& & ( h = = NULL
| | ELF_ST_VISIBILITY ( h - > other ) = = STV_DEFAULT
| | h - > root . type ! = bfd_link_hash_undefweak ) )
/* Or we are creating an executable, we may need to keep relocations
for symbols satisfied by a dynamic library if we manage to avoid
copy relocs for the symbol . */
| | ( ELIMINATE_COPY_RELOCS
& & ! bfd_link_pic ( info )
& & h ! = NULL
& & ( input_section - > flags & SEC_ALLOC )
& & h - > dynindx ! = - 1
& & ! h - > non_got_ref
& & ( ( h - > def_dynamic
& & ! h - > def_regular )
| | h - > root . type = = bfd_link_hash_undefweak
| | h - > root . type = = bfd_link_hash_undefined ) ) )
{
Elf_Internal_Rela outrel ;
bfd_byte * loc ;
@ -6846,15 +6859,22 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
h - > plt . refcount - = 1 ;
break ;
case BFD_RELOC_AARCH64_ADD_LO12 :
case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL :
case BFD_RELOC_AARCH64_ADR_HI21_PCREL :
case BFD_RELOC_AARCH64_ADR_LO21_PCREL :
case BFD_RELOC_AARCH64_LDST128_LO12 :
case BFD_RELOC_AARCH64_LDST16_LO12 :
case BFD_RELOC_AARCH64_LDST32_LO12 :
case BFD_RELOC_AARCH64_LDST64_LO12 :
case BFD_RELOC_AARCH64_LDST8_LO12 :
case BFD_RELOC_AARCH64_LD_LO19_PCREL :
case BFD_RELOC_AARCH64_MOVW_G0_NC :
case BFD_RELOC_AARCH64_MOVW_G1_NC :
case BFD_RELOC_AARCH64_MOVW_G2_NC :
case BFD_RELOC_AARCH64_MOVW_G3 :
case BFD_RELOC_AARCH64_NN :
if ( h ! = NULL & & bfd_link_executable ( info ) )
if ( h ! = NULL & & ! bfd_link_pic ( info ) )
{
if ( h - > plt . refcount > 0 )
h - > plt . refcount - = 1 ;
@ -6869,6 +6889,31 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
return TRUE ;
}
/* Return true if we need copy relocation against EH. */
static bfd_boolean
need_copy_relocation_p ( struct elf_aarch64_link_hash_entry * eh )
{
struct elf_dyn_relocs * p ;
asection * s ;
for ( p = eh - > dyn_relocs ; p ! = NULL ; p = p - > next )
{
/* If there is any pc-relative reference, we need to keep copy relocation
to avoid propagating the relocation into runtime that current glibc
does not support . */
if ( p - > pc_count )
return TRUE ;
s = p - > sec - > output_section ;
/* Need copy relocation if it's against read-only section. */
if ( s ! = NULL & & ( s - > flags & SEC_READONLY ) ! = 0 )
return TRUE ;
}
return FALSE ;
}
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object . The current definition is in some section of the
dynamic object , but we ' re not including those sections . We have to
@ -6942,6 +6987,19 @@ elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE ;
}
if ( ELIMINATE_COPY_RELOCS )
{
struct elf_aarch64_link_hash_entry * eh ;
/* If we didn't find any dynamic relocs in read-only sections, then
we ' ll be keeping the dynamic relocs and avoiding the copy reloc . */
eh = ( struct elf_aarch64_link_hash_entry * ) h ;
if ( ! need_copy_relocation_p ( eh ) )
{
h - > non_got_ref = 0 ;
return TRUE ;
}
}
/* We must allocate the symbol in our .dynbss section, which will
become part of the . bss section of the executable . There will be
an entry for this symbol in the . dynsym section . The dynamic
@ -7196,6 +7254,41 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
switch ( bfd_r_type )
{
case BFD_RELOC_AARCH64_MOVW_G0_NC :
case BFD_RELOC_AARCH64_MOVW_G1_NC :
case BFD_RELOC_AARCH64_MOVW_G2_NC :
case BFD_RELOC_AARCH64_MOVW_G3 :
if ( bfd_link_pic ( info ) )
{
int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START ;
_bfd_error_handler
/* xgettext:c-format */
( _ ( " %B: relocation %s against `%s' can not be used when making "
" a shared object; recompile with -fPIC " ) ,
abfd , elfNN_aarch64_howto_table [ howto_index ] . name ,
( h ) ? h - > root . root . string : " a local symbol " ) ;
bfd_set_error ( bfd_error_bad_value ) ;
return FALSE ;
}
/* Fall through. */
case BFD_RELOC_AARCH64_16_PCREL :
case BFD_RELOC_AARCH64_32_PCREL :
case BFD_RELOC_AARCH64_64_PCREL :
case BFD_RELOC_AARCH64_ADD_LO12 :
case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL :
case BFD_RELOC_AARCH64_ADR_HI21_PCREL :
case BFD_RELOC_AARCH64_ADR_LO21_PCREL :
case BFD_RELOC_AARCH64_LDST128_LO12 :
case BFD_RELOC_AARCH64_LDST16_LO12 :
case BFD_RELOC_AARCH64_LDST32_LO12 :
case BFD_RELOC_AARCH64_LDST64_LO12 :
case BFD_RELOC_AARCH64_LDST8_LO12 :
case BFD_RELOC_AARCH64_LD_LO19_PCREL :
if ( h = = NULL | | bfd_link_pic ( info ) )
break ;
/* Fall through. */
case BFD_RELOC_AARCH64_NN :
/* We don't need to handle relocs into sections not going into
@ -7214,12 +7307,32 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
/* No need to do anything if we're not creating a shared
object . */
if ( ! bfd_link_pic ( info ) )
if ( ! ( bfd_link_pic ( info )
/* If on the other hand, we are creating an executable, we
may need to keep relocations for symbols satisfied by a
dynamic library if we manage to avoid copy relocs for the
symbol .
NOTE : Currently , there is no support of copy relocs
elimination on pc - relative relocation types , because there is
no dynamic relocation support for them in glibc . We still
record the dynamic symbol reference for them . This is
because one symbol may be referenced by both absolute
relocation ( for example , BFD_RELOC_AARCH64_NN ) and
pc - relative relocation . We need full symbol reference
information to make correct decision later in
elfNN_aarch64_adjust_dynamic_symbol . */
| | ( ELIMINATE_COPY_RELOCS
& & ! bfd_link_pic ( info )
& & h ! = NULL
& & ( h - > root . type = = bfd_link_hash_defweak
| | ! h - > def_regular ) ) ) )
break ;
{
struct elf_dyn_relocs * p ;
struct elf_dyn_relocs * * head ;
int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START ;
/* We must copy these reloc types into the output file.
Create a reloc section in dynobj and make room for
@ -7283,6 +7396,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
p - > count + = 1 ;
if ( elfNN_aarch64_howto_table [ howto_index ] . pc_relative )
p - > pc_count + = 1 ;
}
break ;
@ -7386,44 +7501,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
break ;
}
case BFD_RELOC_AARCH64_MOVW_G0_NC :
case BFD_RELOC_AARCH64_MOVW_G1_NC :
case BFD_RELOC_AARCH64_MOVW_G2_NC :
case BFD_RELOC_AARCH64_MOVW_G3 :
if ( bfd_link_pic ( info ) )
{
int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START ;
_bfd_error_handler
/* xgettext:c-format */
( _ ( " %B: relocation %s against `%s' can not be used when making "
" a shared object; recompile with -fPIC " ) ,
abfd , elfNN_aarch64_howto_table [ howto_index ] . name ,
( h ) ? h - > root . root . string : " a local symbol " ) ;
bfd_set_error ( bfd_error_bad_value ) ;
return FALSE ;
}
/* Fall through. */
case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL :
case BFD_RELOC_AARCH64_ADR_HI21_PCREL :
case BFD_RELOC_AARCH64_ADR_LO21_PCREL :
if ( h ! = NULL & & bfd_link_executable ( info ) )
{
/* If this reloc is in a read-only section, we might
need a copy reloc . We can ' t check reliably at this
stage whether the section is read - only , as input
sections have not yet been mapped to output sections .
Tentatively set the flag for now , and correct in
adjust_dynamic_symbol . */
h - > non_got_ref = 1 ;
h - > plt . refcount + = 1 ;
h - > pointer_equality_needed = 1 ;
}
/* FIXME:: RR need to handle these in shared libraries
and essentially bomb out as these being non - PIC
relocations in shared libraries . */
break ;
case BFD_RELOC_AARCH64_CALL26 :
case BFD_RELOC_AARCH64_JUMP26 :
/* If this is a local symbol then we resolve it