Use elf_relocaddr() when handling R_X86_64_RELATIVE relocations.

This is required for DPCPU and VNET data variable definitions to work when
KLDs are linked as DSOs.  R_X86_64_RELATIVE relocations should not appear
in object files, so assert this in elf_relocaddr().

Reviewed by:	kib
MFC after:	1 month
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D21755
This commit is contained in:
Mark Johnston 2019-09-23 14:14:43 +00:00
parent 751727948a
commit 38dae42c26
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=352623
2 changed files with 4 additions and 2 deletions

View File

@ -267,7 +267,6 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
*/
printf("kldload: unexpected R_COPY relocation\n");
return (-1);
break;
case R_X86_64_GLOB_DAT: /* S */
case R_X86_64_JMP_SLOT: /* XXX need addend + offset */
@ -279,7 +278,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
break;
case R_X86_64_RELATIVE: /* B + A */
addr = relocbase + addend;
addr = elf_relocaddr(lf, relocbase + addend);
val = addr;
if (*where != val)
*where = val;

View File

@ -1162,6 +1162,9 @@ elf_relocaddr(linker_file_t lf, Elf_Addr x)
{
elf_file_t ef;
KASSERT(lf->ops->cls == (kobj_class_t)&link_elf_class,
("elf_relocaddr: unexpected linker file %p", lf));
ef = (elf_file_t)lf;
if (x >= ef->pcpu_start && x < ef->pcpu_stop)
return ((x - ef->pcpu_start) + ef->pcpu_base);