summaryrefslogtreecommitdiff
path: root/bfd/elf64-x86-64.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2021-01-15 18:06:48 -0800
committerH.J. Lu <hjl.tools@gmail.com>2021-01-15 18:07:07 -0800
commit68b007788a6cc5376708af42bc220f540e8c4b8a (patch)
treeea89e2a6a9e242932f93752ba6df8c19a15caf79 /bfd/elf64-x86-64.c
parentad92f33d386e050304bf5986f28071ede9dd2284 (diff)
downloadbinutils-gdb-68b007788a6cc5376708af42bc220f540e8c4b8a.tar.gz
ld/x86: Add -z report-relative-reloc
Linker generated relative relocations don't have symbol info: [hjl@gnu-cfl-2 tmpdir]$ readelf -rW dump Relocation section '.rela.dyn' at offset 0x180 contains 2 entries: Offset Info Type Sym. Value Symbol's Name + Addend 00002f70 00000008 R_X86_64_RELATIVE 1000 00002f68 00000025 R_X86_64_IRELATIVE 1007 [hjl@gnu-cfl-2 tmpdir]$ Add -z report-relative-reloc to x86 ELF linker to report dynamic relative relocations: [hjl@gnu-cfl-2 tmpdir]$ ../ld-new -pie -melf32_x86_64 -z report-relative-reloc -o dump report-reloc-1.o dump: R_X86_64_IRELATIVE (offset: 0x00002f68, info: 0x00000025, addend: 0x00001007) against 'ifunc' for section '.data.rel.ro.local' in report-reloc-1.o dump: R_X86_64_RELATIVE (offset: 0x00002f70, info: 0x00000008, addend: 0x00001000) against '_start' for section '.data.rel.ro.local' in report-reloc-1.o [hjl@gnu-cfl-2 tmpdir]$ It can be used to map relative relocations to corresponding symbols. bfd/ * elf-linker-x86.h (elf_linker_x86_params): Add report_relative_reloc. * elf32-i386.c (elf_i386_relocate_section): Call _bfd_x86_elf_link_report_relative_reloc to report relative relocations for -z report-relative-reloc. (elf_i386_finish_dynamic_symbol): Likewse. * elf64-x86-64.c (elf_x86_64_relocate_section): Likewse. (elf_x86_64_finish_dynamic_symbol): Likewse. * elfxx-x86.c (_bfd_x86_elf_link_report_relative_reloc): New function. * elfxx-x86.h (_bfd_x86_elf_link_report_relative_reloc): New prototype. ld/ * NEWS: Mention -z report-relative-reloc. * ld.texi: Document -z report-relative-reloc. * emulparams/elf32_x86_64.sh: Source x86-report-relative.sh. * emulparams/elf_i386.sh: Likewse. * emulparams/elf_x86_64.sh: Likewse. * emulparams/x86-report-relative.sh: New file. * testsuite/ld-i386/report-reloc-1.d: Likewse. * testsuite/ld-i386/report-reloc-1.l: Likewse. * testsuite/ld-i386/report-reloc-1.s: Likewse. * testsuite/ld-x86-64/report-reloc-1-x32.d: Likewse. * testsuite/ld-x86-64/report-reloc-1.d: Likewse. * testsuite/ld-x86-64/report-reloc-1.l: Likewse. * testsuite/ld-x86-64/report-reloc-1.s: Likewse. * testsuite/ld-i386/i386.exp: Run report-reloc-1. * testsuite/ld-x86-64/x86-64.exp: Run report-reloc-1 and report-reloc-1-x32.
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r--bfd/elf64-x86-64.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index daae52b9537..500f8bfa309 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2784,6 +2784,11 @@ elf_x86_64_relocate_section (bfd *output_bfd,
outrel.r_addend = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
+
+ if (htab->params->report_relative_reloc)
+ _bfd_x86_elf_link_report_relative_reloc
+ (info, input_section, h, sym,
+ "R_X86_64_IRELATIVE", &outrel);
}
else
{
@@ -2940,6 +2945,12 @@ elf_x86_64_relocate_section (bfd *output_bfd,
+ off);
outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
outrel.r_addend = relocation;
+
+ if (htab->params->report_relative_reloc)
+ _bfd_x86_elf_link_report_relative_reloc
+ (info, input_section, h, sym, "R_X86_64_RELATIVE",
+ &outrel);
+
elf_append_rela (output_bfd, s, &outrel);
}
@@ -3221,6 +3232,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
Elf_Internal_Rela outrel;
bfd_boolean skip, relocate;
asection *sreloc;
+ const char *relative_reloc_name = NULL;
/* When generating a shared object, these relocations
are copied into the output file to be resolved at run
@@ -3259,6 +3271,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
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";
}
else if (r_type == R_X86_64_64
&& !ABI_64_P (output_bfd))
@@ -3267,6 +3280,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
outrel.r_info = htab->r_info (0,
R_X86_64_RELATIVE64);
outrel.r_addend = relocation + rel->r_addend;
+ relative_reloc_name = "R_X86_64_RELATIVE64";
/* Check addend overflow. */
if ((outrel.r_addend & 0x80000000)
!= (rel->r_addend & 0x80000000))
@@ -3333,6 +3347,12 @@ elf_x86_64_relocate_section (bfd *output_bfd,
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 this reloc is against an external symbol, we do
@@ -4292,6 +4312,11 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
rela.r_addend = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
+
+ if (htab->params->report_relative_reloc)
+ _bfd_x86_elf_link_report_relative_reloc
+ (info, relplt, h, sym, "R_X86_64_IRELATIVE", &rela);
+
/* R_X86_64_IRELATIVE comes last. */
plt_index = htab->next_irelative_index--;
}
@@ -4409,6 +4434,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;
/* This symbol has an entry in the global offset table. Set it
up. */
@@ -4447,6 +4473,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
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_IRELATIVE";
}
else
goto do_glob_dat;
@@ -4494,6 +4521,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
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
{
@@ -4505,6 +4533,11 @@ 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);
+
elf_append_rela (output_bfd, relgot, &rela);
}