mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 18:44:20 +08:00
x86: Add DT_RELR support
DT_RELR is implemented with linker relaxation: 1. During linker relaxation, we scan input relocations with the same logic in relocate_section to determine if a relative relocation should be generated and save the relative relocation candidate information for sizing the DT_RELR section later after all symbols addresses can be determined. For these relative relocations which can't be placed in the DT_RELR section, they will be placed in the rela.dyn/rel.dyn section. 2. When DT_RELR is enabled, _bfd_elf_map_sections_to_segments calls a backend function to size the DT_RELR section which will compute the DT_RELR section size and tell ldelf_map_segments to layout sections again when the DT_RELR section size has been increased. 3. After regular symbol processing is finished, bfd_elf_final_link calls a backend function to finish the DT_RELR section. * elf32-i386.c (elf_i386_relocate_section): Don't generate relative relocation when DT_RELR is enabled. (elf_i386_finish_dynamic_symbol): Likewise. * elf64-x86-64.c (elf_x86_64_relocate_section): Don't generate relative relocation when DT_RELR is enabled. (elf_x86_64_finish_dynamic_symbol): Likewise. * elfxx-x86.c (_bfd_x86_elf_link_hash_table_create): Initialize relative_r_type, relative_r_name, elf_append_reloc, elf_write_addend and elf_write_addend_in_got. (elf_x86_relative_reloc_record_add): New function. (_bfd_x86_elf_link_relax_section): Likewise. (elf64_dt_relr_bitmap_add): Likewise. (elf32_dt_relr_bitmap_add): Likewise. (_bfd_elf32_write_addend): Likewise. (_bfd_elf64_write_addend): Likewise. (elf_x86_size_or_finish_relative_reloc): Likewise. (elf_x86_compute_dl_relr_bitmap): Likewise. (elf_x86_write_dl_relr_bitmap): Likewise. (elf_x86_relative_reloc_compare ): Likewise. (_bfd_elf_x86_size_relative_relocs): Likewise. (_bfd_elf_x86_finish_relative_relocs): Likewise. (_bfd_x86_elf_size_dynamic_sections): Skip the .relr.dyn section. (_bfd_x86_elf_finish_dynamic_sections): Convert 3 spare dynamic tags to DT_RELR, DT_RELRSZ and for compact relative relocation. * elfxx-x86.h (X86_64_GOT_TYPE_P): New. (I386_GOT_TYPE_P): Likewise. (X86_GOT_TYPE_P): Likewise. (X86_64_RELATIVE_RELOC_TYPE_P): Likewise. (I386_RELATIVE_RELOC_TYPE_P): Likewise. (X86_RELATIVE_RELOC_TYPE_P): Likewise. (X86_LOCAL_GOT_RELATIVE_RELOC_P): Likewise. (I386_PCREL_TYPE_P): Likewise. (X86_64_PCREL_TYPE_P): Likewise. (X86_64_NEED_DYNAMIC_RELOC_TYPE_P): Rewrite. (I386_NEED_DYNAMIC_RELOC_TYPE_P): Likewise. (GENERATE_DYNAMIC_RELOCATION_P): Also check rel_from_abs. (elf_x86_link_hash_entry): Add got_relative_reloc_done. (elf_x86_relative_reloc_record): New. (elf_x86_relative_reloc_data): Likewise. (elf_dt_relr_bitmap): Likewise. (elf_x86_link_hash_table): Add dt_relr_bitmap, relative_reloc, unaligned_relative_reloc, relative_r_type, relative_r_name, elf_append_reloc, elf_write_addend, elf_write_addend_in_got and relative_reloc_done. (elf_x86_relative_reloc_done): New. (relative_reloc_packed): Likewise. (_bfd_x86_elf_link_relax_section): Likewise. (_bfd_elf_x86_size_relative_relocs): Likewise. (_bfd_elf_x86_finish_relative_relocs): Likewise. (_bfd_elf32_write_addend): Likewise. (_bfd_elf64_write_addend): Likewise. (bfd_elf32_bfd_relax_section): Likewise. (bfd_elf64_bfd_relax_section): Likewise. (elf_backend_size_relative_relocs): Likewise. (elf_backend_finish_relative_relocs): Likewise. (elf_x86_allocate_local_got_info): Also allocate relative_reloc_done.
This commit is contained in:
parent
f2e37a5c7f
commit
5af6f000d8
@ -2473,8 +2473,10 @@ elf_i386_relocate_section (bfd *output_bfd,
|
||||
bfd_put_32 (output_bfd, relocation,
|
||||
htab->elf.sgot->contents + off);
|
||||
h->got.offset |= 1;
|
||||
|
||||
if (GENERATE_RELATIVE_RELOC_P (info, h))
|
||||
/* NB: Don't generate relative relocation here if
|
||||
it has been generated by DT_RELR. */
|
||||
if (!info->enable_dt_relr
|
||||
&& GENERATE_RELATIVE_RELOC_P (info, h))
|
||||
{
|
||||
/* PR ld/21402: If this symbol isn't dynamic
|
||||
in PIC, generate R_386_RELATIVE here. */
|
||||
@ -2504,7 +2506,9 @@ elf_i386_relocate_section (bfd *output_bfd,
|
||||
htab->elf.sgot->contents + off);
|
||||
local_got_offsets[r_symndx] |= 1;
|
||||
|
||||
if (bfd_link_pic (info))
|
||||
/* NB: Don't generate relative relocation here if it
|
||||
has been generated by DT_RELR. */
|
||||
if (!info->enable_dt_relr && bfd_link_pic (info))
|
||||
relative_reloc = true;
|
||||
}
|
||||
}
|
||||
@ -2707,6 +2711,7 @@ elf_i386_relocate_section (bfd *output_bfd,
|
||||
{
|
||||
Elf_Internal_Rela outrel;
|
||||
bool skip, relocate;
|
||||
bool generate_dynamic_reloc = true;
|
||||
asection *sreloc;
|
||||
|
||||
/* When generating a shared object, these relocations
|
||||
@ -2734,23 +2739,33 @@ elf_i386_relocate_section (bfd *output_bfd,
|
||||
{
|
||||
/* This symbol is local, or marked to become local. */
|
||||
relocate = true;
|
||||
outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
|
||||
/* NB: Don't generate relative relocation here if it
|
||||
has been generated by DT_RELR. */
|
||||
if (info->enable_dt_relr)
|
||||
generate_dynamic_reloc = false;
|
||||
else
|
||||
{
|
||||
outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
|
||||
|
||||
if (htab->params->report_relative_reloc)
|
||||
_bfd_x86_elf_link_report_relative_reloc
|
||||
(info, input_section, h, sym, "R_386_RELATIVE",
|
||||
&outrel);
|
||||
if (htab->params->report_relative_reloc)
|
||||
_bfd_x86_elf_link_report_relative_reloc
|
||||
(info, input_section, h, sym, "R_386_RELATIVE",
|
||||
&outrel);
|
||||
}
|
||||
}
|
||||
|
||||
sreloc = elf_section_data (input_section)->sreloc;
|
||||
|
||||
if (sreloc == NULL || sreloc->contents == NULL)
|
||||
if (generate_dynamic_reloc)
|
||||
{
|
||||
r = bfd_reloc_notsupported;
|
||||
goto check_relocation_error;
|
||||
}
|
||||
sreloc = elf_section_data (input_section)->sreloc;
|
||||
|
||||
elf_append_rel (output_bfd, sreloc, &outrel);
|
||||
if (sreloc == NULL || sreloc->contents == NULL)
|
||||
{
|
||||
r = bfd_reloc_notsupported;
|
||||
goto check_relocation_error;
|
||||
}
|
||||
|
||||
elf_append_rel (output_bfd, sreloc, &outrel);
|
||||
}
|
||||
|
||||
/* If this reloc is against an external symbol, we do
|
||||
not want to fiddle with the addend. Otherwise, we
|
||||
@ -3776,6 +3791,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
|
||||
Elf_Internal_Rela rel;
|
||||
asection *relgot = htab->elf.srelgot;
|
||||
const char *relative_reloc_name = NULL;
|
||||
bool generate_dynamic_reloc = true;
|
||||
|
||||
/* This symbol has an entry in the global offset table. Set it
|
||||
up. */
|
||||
@ -3858,8 +3874,13 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
|
||||
&& SYMBOL_REFERENCES_LOCAL_P (info, h))
|
||||
{
|
||||
BFD_ASSERT((h->got.offset & 1) != 0);
|
||||
rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
|
||||
relative_reloc_name = "R_386_RELATIVE";
|
||||
if (info->enable_dt_relr)
|
||||
generate_dynamic_reloc = false;
|
||||
else
|
||||
{
|
||||
rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
|
||||
relative_reloc_name = "R_386_RELATIVE";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3870,12 +3891,15 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
|
||||
rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
|
||||
}
|
||||
|
||||
if (relative_reloc_name != NULL
|
||||
&& htab->params->report_relative_reloc)
|
||||
_bfd_x86_elf_link_report_relative_reloc
|
||||
(info, relgot, h, sym, relative_reloc_name, &rel);
|
||||
if (generate_dynamic_reloc)
|
||||
{
|
||||
if (relative_reloc_name != NULL
|
||||
&& htab->params->report_relative_reloc)
|
||||
_bfd_x86_elf_link_report_relative_reloc
|
||||
(info, relgot, h, sym, relative_reloc_name, &rel);
|
||||
|
||||
elf_append_rel (output_bfd, relgot, &rel);
|
||||
elf_append_rel (output_bfd, relgot, &rel);
|
||||
}
|
||||
}
|
||||
|
||||
if (h->needs_copy)
|
||||
|
@ -2867,7 +2867,10 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
||||
as -1 | 1 still is -1. */
|
||||
h->got.offset |= 1;
|
||||
|
||||
if (GENERATE_RELATIVE_RELOC_P (info, h))
|
||||
/* NB: Don't generate relative relocation here if
|
||||
it has been generated by DT_RELR. */
|
||||
if (!info->enable_dt_relr
|
||||
&& GENERATE_RELATIVE_RELOC_P (info, h))
|
||||
{
|
||||
/* If this symbol isn't dynamic in PIC,
|
||||
generate R_X86_64_RELATIVE here. */
|
||||
@ -2899,8 +2902,11 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
||||
|
||||
/* NB: GOTPCREL relocations against local absolute
|
||||
symbol store relocation value in the GOT slot
|
||||
without relative relocation. */
|
||||
if (bfd_link_pic (info)
|
||||
without relative relocation. Don't generate
|
||||
relative relocation here if it has been generated
|
||||
by DT_RELR. */
|
||||
if (!info->enable_dt_relr
|
||||
&& bfd_link_pic (info)
|
||||
&& !(sym->st_shndx == SHN_ABS
|
||||
&& (r_type == R_X86_64_GOTPCREL
|
||||
|| r_type == R_X86_64_GOTPCRELX
|
||||
@ -3215,6 +3221,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
||||
{
|
||||
Elf_Internal_Rela outrel;
|
||||
bool skip, relocate;
|
||||
bool generate_dynamic_reloc = true;
|
||||
asection *sreloc;
|
||||
const char *relative_reloc_name = NULL;
|
||||
|
||||
@ -3253,9 +3260,17 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
||||
&& htab->params->no_reloc_overflow_check))
|
||||
{
|
||||
relocate = true;
|
||||
outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
|
||||
outrel.r_addend = relocation + rel->r_addend;
|
||||
relative_reloc_name = "R_X86_64_RELATIVE";
|
||||
/* NB: Don't generate relative relocation here if
|
||||
it has been generated by DT_RELR. */
|
||||
if (info->enable_dt_relr)
|
||||
generate_dynamic_reloc = false;
|
||||
else
|
||||
{
|
||||
outrel.r_info =
|
||||
htab->r_info (0, R_X86_64_RELATIVE);
|
||||
outrel.r_addend = relocation + rel->r_addend;
|
||||
relative_reloc_name = "R_X86_64_RELATIVE";
|
||||
}
|
||||
}
|
||||
else if (r_type == R_X86_64_64
|
||||
&& !ABI_64_P (output_bfd))
|
||||
@ -3323,22 +3338,25 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
||||
}
|
||||
}
|
||||
|
||||
sreloc = elf_section_data (input_section)->sreloc;
|
||||
|
||||
if (sreloc == NULL || sreloc->contents == NULL)
|
||||
if (generate_dynamic_reloc)
|
||||
{
|
||||
r = bfd_reloc_notsupported;
|
||||
goto check_relocation_error;
|
||||
sreloc = elf_section_data (input_section)->sreloc;
|
||||
|
||||
if (sreloc == NULL || sreloc->contents == NULL)
|
||||
{
|
||||
r = bfd_reloc_notsupported;
|
||||
goto check_relocation_error;
|
||||
}
|
||||
|
||||
if (relative_reloc_name
|
||||
&& htab->params->report_relative_reloc)
|
||||
_bfd_x86_elf_link_report_relative_reloc
|
||||
(info, input_section, h, sym,
|
||||
relative_reloc_name, &outrel);
|
||||
|
||||
elf_append_rela (output_bfd, sreloc, &outrel);
|
||||
}
|
||||
|
||||
if (relative_reloc_name
|
||||
&& htab->params->report_relative_reloc)
|
||||
_bfd_x86_elf_link_report_relative_reloc
|
||||
(info, input_section, h, sym, relative_reloc_name,
|
||||
&outrel);
|
||||
|
||||
elf_append_rela (output_bfd, sreloc, &outrel);
|
||||
|
||||
/* If this reloc is against an external symbol, we do
|
||||
not want to fiddle with the addend. Otherwise, we
|
||||
need to include the symbol value so that it becomes
|
||||
@ -4424,6 +4442,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
|
||||
Elf_Internal_Rela rela;
|
||||
asection *relgot = htab->elf.srelgot;
|
||||
const char *relative_reloc_name = NULL;
|
||||
bool generate_dynamic_reloc = true;
|
||||
|
||||
/* This symbol has an entry in the global offset table. Set it
|
||||
up. */
|
||||
@ -4506,11 +4525,16 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
|
||||
if (!SYMBOL_DEFINED_NON_SHARED_P (h))
|
||||
return false;
|
||||
BFD_ASSERT((h->got.offset & 1) != 0);
|
||||
rela.r_info = htab->r_info (0, R_X86_64_RELATIVE);
|
||||
rela.r_addend = (h->root.u.def.value
|
||||
+ h->root.u.def.section->output_section->vma
|
||||
+ h->root.u.def.section->output_offset);
|
||||
relative_reloc_name = "R_X86_64_RELATIVE";
|
||||
if (info->enable_dt_relr)
|
||||
generate_dynamic_reloc = false;
|
||||
else
|
||||
{
|
||||
rela.r_info = htab->r_info (0, R_X86_64_RELATIVE);
|
||||
rela.r_addend = (h->root.u.def.value
|
||||
+ h->root.u.def.section->output_section->vma
|
||||
+ h->root.u.def.section->output_offset);
|
||||
relative_reloc_name = "R_X86_64_RELATIVE";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4522,12 +4546,15 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
|
||||
rela.r_addend = 0;
|
||||
}
|
||||
|
||||
if (relative_reloc_name != NULL
|
||||
&& htab->params->report_relative_reloc)
|
||||
_bfd_x86_elf_link_report_relative_reloc
|
||||
(info, relgot, h, sym, relative_reloc_name, &rela);
|
||||
if (generate_dynamic_reloc)
|
||||
{
|
||||
if (relative_reloc_name != NULL
|
||||
&& htab->params->report_relative_reloc)
|
||||
_bfd_x86_elf_link_report_relative_reloc
|
||||
(info, relgot, h, sym, relative_reloc_name, &rela);
|
||||
|
||||
elf_append_rela (output_bfd, relgot, &rela);
|
||||
elf_append_rela (output_bfd, relgot, &rela);
|
||||
}
|
||||
}
|
||||
|
||||
if (h->needs_copy)
|
||||
|
954
bfd/elfxx-x86.c
954
bfd/elfxx-x86.c
File diff suppressed because it is too large
Load Diff
147
bfd/elfxx-x86.h
147
bfd/elfxx-x86.h
@ -47,18 +47,35 @@
|
||||
#define X86_SIZE_TYPE_P(IS_X86_64, TYPE) \
|
||||
((IS_X86_64) ? X86_64_SIZE_TYPE_P(TYPE) : I386_SIZE_TYPE_P (TYPE))
|
||||
|
||||
#define X86_64_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \
|
||||
(X86_64_SIZE_TYPE_P (TYPE) \
|
||||
|| X86_64_PCREL_TYPE_P (TYPE) \
|
||||
#define X86_64_GOT_TYPE_P(TYPE) \
|
||||
((TYPE) == R_X86_64_GOTPCREL \
|
||||
|| (TYPE) == R_X86_64_GOTPCRELX \
|
||||
|| (TYPE) == R_X86_64_REX_GOTPCRELX)
|
||||
#define I386_GOT_TYPE_P(TYPE) \
|
||||
((TYPE) == R_386_GOT32 || (TYPE) == R_386_GOT32X)
|
||||
#define X86_GOT_TYPE_P(IS_X86_64, TYPE) \
|
||||
((IS_X86_64) ? X86_64_GOT_TYPE_P (TYPE) : I386_GOT_TYPE_P (TYPE))
|
||||
|
||||
#define X86_64_RELATIVE_RELOC_TYPE_P(TYPE) \
|
||||
(X86_64_PCREL_TYPE_P (TYPE) \
|
||||
|| (TYPE) == R_X86_64_8 \
|
||||
|| (TYPE) == R_X86_64_16 \
|
||||
|| (TYPE) == R_X86_64_32 \
|
||||
|| (TYPE) == R_X86_64_32S \
|
||||
|| (TYPE) == R_X86_64_64)
|
||||
#define I386_RELATIVE_RELOC_TYPE_P(TYPE) \
|
||||
((TYPE) == R_386_32 || (TYPE) == R_386_PC32)
|
||||
#define X86_RELATIVE_RELOC_TYPE_P(IS_X86_64, TYPE) \
|
||||
((IS_X86_64) \
|
||||
? X86_64_RELATIVE_RELOC_TYPE_P (TYPE) \
|
||||
: I386_RELATIVE_RELOC_TYPE_P(TYPE))
|
||||
|
||||
#define X86_64_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \
|
||||
(X86_64_SIZE_TYPE_P (TYPE) \
|
||||
|| X86_64_RELATIVE_RELOC_TYPE_P (TYPE))
|
||||
#define I386_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \
|
||||
(I386_SIZE_TYPE_P (TYPE) \
|
||||
|| I386_PCREL_TYPE_P (TYPE) \
|
||||
|| (TYPE) == R_386_32 \
|
||||
|| I386_RELATIVE_RELOC_TYPE_P (TYPE) \
|
||||
|| (TYPE) == R_386_TLS_LE \
|
||||
|| (TYPE) == R_386_TLS_LE_32)
|
||||
#define X86_NEED_DYNAMIC_RELOC_TYPE_P(IS_X86_64, TYPE) \
|
||||
@ -66,11 +83,23 @@
|
||||
? X86_64_NEED_DYNAMIC_RELOC_TYPE_P (TYPE) \
|
||||
: I386_NEED_DYNAMIC_RELOC_TYPE_P (TYPE))
|
||||
|
||||
#define X86_LOCAL_GOT_RELATIVE_RELOC_P(IS_X86_64, INFO, SYM) \
|
||||
(bfd_link_pic (INFO) \
|
||||
&& (!(IS_X86_64) || ((SYM) != NULL && (SYM)->st_shndx != SHN_ABS)))
|
||||
|
||||
#define PLT_CIE_LENGTH 20
|
||||
#define PLT_FDE_LENGTH 36
|
||||
#define PLT_FDE_START_OFFSET 4 + PLT_CIE_LENGTH + 8
|
||||
#define PLT_FDE_LEN_OFFSET 4 + PLT_CIE_LENGTH + 12
|
||||
|
||||
#define I386_PCREL_TYPE_P(TYPE) ((TYPE) == R_386_PC32)
|
||||
#define X86_64_PCREL_TYPE_P(TYPE) \
|
||||
((TYPE) == R_X86_64_PC8 \
|
||||
|| (TYPE) == R_X86_64_PC16 \
|
||||
|| (TYPE) == R_X86_64_PC32 \
|
||||
|| (TYPE) == R_X86_64_PC32_BND \
|
||||
|| (TYPE) == R_X86_64_PC64)
|
||||
|
||||
#define ABI_64_P(abfd) \
|
||||
(get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
|
||||
|
||||
@ -160,12 +189,18 @@
|
||||
relocations against resolved undefined weak symbols in PIE, except
|
||||
when PC32_RELOC is TRUE. Undefined weak symbol is bound locally
|
||||
when PIC is false. Don't generate dynamic relocations against
|
||||
non-preemptible absolute symbol. */
|
||||
non-preemptible absolute symbol. NB: rel_from_abs is set on symbols
|
||||
defined by linker scripts from "dot" (also SEGMENT_START or ORIGIN)
|
||||
outside of an output section statement, which will be converted from
|
||||
absolute to section-relative in set_sym_sections called from
|
||||
ldexp_finalize_syms after ldemul_finish. */
|
||||
#define GENERATE_DYNAMIC_RELOCATION_P(IS_X86_64, INFO, EH, R_TYPE, \
|
||||
SEC, NEED_COPY_RELOC_IN_PIE, \
|
||||
RESOLVED_TO_ZERO, PC32_RELOC) \
|
||||
((bfd_link_pic (INFO) \
|
||||
&& !(bfd_is_abs_section (SEC) \
|
||||
&& ((EH) == NULL \
|
||||
|| (EH)->elf.root.rel_from_abs == 0) \
|
||||
&& ((EH) == NULL \
|
||||
|| SYMBOL_REFERENCES_LOCAL (INFO, &(EH)->elf))) \
|
||||
&& !(NEED_COPY_RELOC_IN_PIE) \
|
||||
@ -302,6 +337,10 @@ struct elf_x86_link_hash_entry
|
||||
/* Don't call finish_dynamic_symbol on this symbol. */
|
||||
unsigned int no_finish_dynamic_symbol : 1;
|
||||
|
||||
/* R_*_RELATIVE relocation in GOT for this symbol has been
|
||||
processed. */
|
||||
unsigned int got_relative_reloc_done : 1;
|
||||
|
||||
/* TRUE if symbol is __tls_get_addr. */
|
||||
unsigned int tls_get_addr : 1;
|
||||
|
||||
@ -481,6 +520,52 @@ struct elf_x86_plt_layout
|
||||
#define elf_x86_hash_entry(ent) \
|
||||
((struct elf_x86_link_hash_entry *)(ent))
|
||||
|
||||
/* Information of an input relocation used to compute its contribution
|
||||
to the DT_RELR section size. */
|
||||
|
||||
struct elf_x86_relative_reloc_record
|
||||
{
|
||||
/* The original relocation info. */
|
||||
Elf_Internal_Rela rel;
|
||||
/* The input or the GOT section where the relocation is applied. */
|
||||
asection *sec;
|
||||
/* Local symbol info. NULL for global symbol. */
|
||||
Elf_Internal_Sym *sym;
|
||||
union
|
||||
{
|
||||
/* Section where the local symbol is defined. */
|
||||
asection *sym_sec;
|
||||
/* Global symbol hash. */
|
||||
struct elf_link_hash_entry *h;
|
||||
} u;
|
||||
/* The offset into the output section where the relative relocation
|
||||
will be applied at run-time. */
|
||||
bfd_vma offset;
|
||||
/* The run-time address. */
|
||||
bfd_vma address;
|
||||
};
|
||||
|
||||
struct elf_x86_relative_reloc_data
|
||||
{
|
||||
bfd_size_type count;
|
||||
bfd_size_type size;
|
||||
struct elf_x86_relative_reloc_record *data;
|
||||
};
|
||||
|
||||
/* DT_RELR bitmap. */
|
||||
struct elf_dt_relr_bitmap
|
||||
{
|
||||
bfd_size_type count;
|
||||
bfd_size_type size;
|
||||
union
|
||||
{
|
||||
/* 32-bit bitmap. */
|
||||
uint32_t *elf32;
|
||||
/* 64-bit bitmap. */
|
||||
uint64_t *elf64;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* x86 ELF linker hash table. */
|
||||
|
||||
struct elf_x86_link_hash_table
|
||||
@ -533,6 +618,18 @@ struct elf_x86_link_hash_table
|
||||
is only used for i386. */
|
||||
bfd_vma next_tls_desc_index;
|
||||
|
||||
/* DT_RELR bitmap. */
|
||||
struct elf_dt_relr_bitmap dt_relr_bitmap;
|
||||
|
||||
/* Relative relocation data. */
|
||||
struct elf_x86_relative_reloc_data relative_reloc;
|
||||
|
||||
/* Unaligned relative relocation data. */
|
||||
struct elf_x86_relative_reloc_data unaligned_relative_reloc;
|
||||
|
||||
/* Number of relative reloc generation pass. */
|
||||
unsigned int generate_relative_reloc_pass;
|
||||
|
||||
/* Value used to fill the unused bytes of the first PLT entry. This
|
||||
is only used for i386. */
|
||||
bfd_byte plt0_pad_byte;
|
||||
@ -554,9 +651,14 @@ struct elf_x86_link_hash_table
|
||||
unsigned int sizeof_reloc;
|
||||
unsigned int got_entry_size;
|
||||
unsigned int pointer_r_type;
|
||||
unsigned int relative_r_type;
|
||||
int dynamic_interpreter_size;
|
||||
const char *dynamic_interpreter;
|
||||
const char *tls_get_addr;
|
||||
const char *relative_r_name;
|
||||
void (*elf_append_reloc) (bfd *, asection *, Elf_Internal_Rela *);
|
||||
void (*elf_write_addend) (bfd *, uint64_t, void *);
|
||||
void (*elf_write_addend_in_got) (bfd *, uint64_t, void *);
|
||||
|
||||
/* Options passed from the linker. */
|
||||
struct elf_linker_x86_params *params;
|
||||
@ -591,6 +693,10 @@ struct elf_x86_obj_tdata
|
||||
|
||||
/* GOTPLT entries for TLS descriptors. */
|
||||
bfd_vma *local_tlsdesc_gotent;
|
||||
|
||||
/* R_*_RELATIVE relocation in GOT for this local symbol has been
|
||||
processed. */
|
||||
char *relative_reloc_done;
|
||||
};
|
||||
|
||||
enum elf_x86_plt_type
|
||||
@ -626,6 +732,9 @@ struct elf_x86_plt
|
||||
#define elf_x86_local_tlsdesc_gotent(abfd) \
|
||||
(elf_x86_tdata (abfd)->local_tlsdesc_gotent)
|
||||
|
||||
#define elf_x86_relative_reloc_done(abfd) \
|
||||
(elf_x86_tdata (abfd)->relative_reloc_done)
|
||||
|
||||
#define elf_x86_compute_jump_table_size(htab) \
|
||||
((htab)->elf.srelplt->reloc_count * (htab)->got_entry_size)
|
||||
|
||||
@ -637,6 +746,7 @@ struct elf_x86_plt
|
||||
/* Rename some of the generic section flags to better document how they
|
||||
are used here. */
|
||||
#define check_relocs_failed sec_flg0
|
||||
#define relative_reloc_packed sec_flg1
|
||||
|
||||
extern bool _bfd_x86_elf_mkobject
|
||||
(bfd *);
|
||||
@ -676,6 +786,18 @@ extern bool _bfd_x86_elf_check_relocs
|
||||
(bfd *, struct bfd_link_info *, asection *,
|
||||
const Elf_Internal_Rela *);
|
||||
|
||||
extern bool _bfd_x86_elf_link_relax_section
|
||||
(bfd *, asection *, struct bfd_link_info *, bool *);
|
||||
|
||||
extern bool _bfd_elf_x86_size_relative_relocs
|
||||
(struct bfd_link_info *, bool *);
|
||||
|
||||
extern bool _bfd_elf_x86_finish_relative_relocs
|
||||
(struct bfd_link_info *);
|
||||
|
||||
extern void _bfd_elf32_write_addend (bfd *, uint64_t, void *);
|
||||
extern void _bfd_elf64_write_addend (bfd *, uint64_t, void *);
|
||||
|
||||
extern bool _bfd_elf_x86_valid_reloc_p
|
||||
(asection *, struct bfd_link_info *, struct elf_x86_link_hash_table *,
|
||||
const Elf_Internal_Rela *, struct elf_link_hash_entry *,
|
||||
@ -752,6 +874,10 @@ extern void _bfd_x86_elf_link_report_relative_reloc
|
||||
_bfd_x86_elf_link_check_relocs
|
||||
#define bfd_elf32_bfd_link_check_relocs \
|
||||
_bfd_x86_elf_link_check_relocs
|
||||
#define bfd_elf32_bfd_relax_section \
|
||||
_bfd_x86_elf_link_relax_section
|
||||
#define bfd_elf64_bfd_relax_section \
|
||||
_bfd_x86_elf_link_relax_section
|
||||
|
||||
#define elf_backend_check_relocs \
|
||||
_bfd_x86_elf_check_relocs
|
||||
@ -777,6 +903,10 @@ extern void _bfd_x86_elf_link_report_relative_reloc
|
||||
_bfd_x86_elf_merge_gnu_properties
|
||||
#define elf_backend_fixup_gnu_properties \
|
||||
_bfd_x86_elf_link_fixup_gnu_properties
|
||||
#define elf_backend_size_relative_relocs \
|
||||
_bfd_elf_x86_size_relative_relocs
|
||||
#define elf_backend_finish_relative_relocs \
|
||||
_bfd_elf_x86_finish_relative_relocs
|
||||
|
||||
#define ELF_P_ALIGN ELF_MINPAGESIZE
|
||||
|
||||
@ -789,7 +919,8 @@ elf_x86_allocate_local_got_info (bfd *abfd, bfd_size_type count)
|
||||
if (local_got_refcounts == NULL)
|
||||
{
|
||||
bfd_size_type size = count * (sizeof (bfd_signed_vma)
|
||||
+ sizeof (bfd_vma) + sizeof(char));
|
||||
+ sizeof (bfd_vma)
|
||||
+ 2 * sizeof(char));
|
||||
local_got_refcounts = (bfd_signed_vma *) bfd_zalloc (abfd, size);
|
||||
if (local_got_refcounts == NULL)
|
||||
return false;
|
||||
@ -798,6 +929,8 @@ elf_x86_allocate_local_got_info (bfd *abfd, bfd_size_type count)
|
||||
(bfd_vma *) (local_got_refcounts + count);
|
||||
elf_x86_local_got_tls_type (abfd) =
|
||||
(char *) (local_got_refcounts + 2 * count);
|
||||
elf_x86_relative_reloc_done (abfd) =
|
||||
((char *) (local_got_refcounts + 2 * count)) + count;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user