hv: multi-arch: refine relocation related code

Move dynamic sections and relocation sections data structures to
elf.h and enclose function relocate with CONFIG_RELOC. The input
parameter struct Elf64_Dyn *dynamic is not used by x86-64 now because
x86-64 can use pc-relative addressing to get the acutaly load address
of _DYNAMIC in the C code.

Tracked-On: #8825
Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com>
Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
Jian Jun Chen
2025-09-30 08:22:31 +08:00
committed by acrnsi-robot
parent f094632178
commit f904dbffbb
4 changed files with 59 additions and 46 deletions

View File

@@ -224,12 +224,14 @@ primary_start_long_mode:
/* 16 = CPU_STACK_ALIGN */ /* 16 = CPU_STACK_ALIGN */
and $(~(16 - 1)),%rsp and $(~(16 - 1)),%rsp
#ifdef CONFIG_RELOC
/* /*
* Fix up the .rela sections * Fix up the .rela sections
* Notes: this includes the fixup to IDT tables and temporary * Notes: this includes the fixup to IDT tables and temporary
* page tables * page tables
*/ */
call relocate call relocate
#endif /* CONFIG_RELOC */
call 0f call 0f
0: pop %rsi 0: pop %rsi

View File

@@ -8,33 +8,8 @@
#include <reloc.h> #include <reloc.h>
#include <asm/boot/ld_sym.h> #include <asm/boot/ld_sym.h>
#ifdef CONFIG_RELOC
#define DT_NULL 0U /* end of .dynamic section */
#define DT_RELA 7U /* relocation table */
#define DT_RELASZ 8U /* size of reloc table */
#define DT_RELAENT 9U /* size of one entry */
#define R_X86_64_RELATIVE 8UL
struct Elf64_Dyn {
uint64_t d_tag;
uint64_t d_ptr;
};
struct Elf64_Rel {
uint64_t r_offset;
uint64_t r_info;
uint64_t reserved;
};
static inline uint64_t elf64_r_type(uint64_t i)
{
return (i & 0xffffffffUL);
}
#endif
/* get the delta between CONFIG_HV_RAM_START and the actual load address */ /* get the delta between CONFIG_HV_RAM_START and the actual load address */
uint64_t get_hv_image_delta(void) uint64_t arch_get_hv_image_delta(void)
{ {
uint64_t addr; uint64_t addr;
@@ -49,20 +24,9 @@ uint64_t get_hv_image_delta(void)
return addr; return addr;
} }
/* get the actual Hypervisor load address (HVA) */
uint64_t get_hv_image_base(void)
{
return (get_hv_image_delta() + CONFIG_HV_RAM_START);
}
inline uint64_t get_hv_image_size(void)
{
return (uint64_t)(&ld_ram_end - &ld_ram_start);
}
void relocate(void)
{
#ifdef CONFIG_RELOC #ifdef CONFIG_RELOC
void relocate(__unused struct Elf64_Dyn *dynamic)
{
struct Elf64_Dyn *dyn; struct Elf64_Dyn *dyn;
struct Elf64_Rel *entry = NULL; struct Elf64_Rel *entry = NULL;
uint8_t *rela_start = NULL, *rela_end = NULL; uint8_t *rela_start = NULL, *rela_end = NULL;
@@ -125,5 +89,5 @@ void relocate(void)
rela_start += entry_size; rela_start += entry_size;
} }
} }
#endif
} }
#endif /* CONFIG_RELOC */

View File

@@ -158,4 +158,34 @@ struct elf32_sec_entry
uint32_t sh_entsize; uint32_t sh_entsize;
}; };
/* Dynamic structure */
struct Elf64_Dyn {
uint64_t d_tag;
uint64_t d_ptr;
};
/* external symbols that are helpful for relocation */
extern struct Elf64_Dyn *_DYNAMIC;
/* Dynamic Array Tags - d_tag */
#define DT_NULL 0U /* end of .dynamic section */
#define DT_RELA 7U /* relocation table */
#define DT_RELASZ 8U /* size of reloc table */
#define DT_RELAENT 9U /* size of one entry */
/* Relocation entry with explicit addend */
struct Elf64_Rel {
uint64_t r_offset;
uint64_t r_info;
int64_t r_addend;
};
static inline uint64_t elf64_r_type(uint64_t i)
{
return (i & 0xffffffffUL);
}
/* x86-64 relocation types */
#define R_X86_64_RELATIVE 8U
#endif /* !ELF_H */ #endif /* !ELF_H */

View File

@@ -6,12 +6,29 @@
#ifndef RELOCATE_H #ifndef RELOCATE_H
#define RELOCATE_H #define RELOCATE_H
extern void relocate(void); #include <elf.h>
extern uint64_t get_hv_image_delta(void); #include <asm/boot/ld_sym.h>
extern uint64_t get_hv_image_base(void);
extern uint64_t get_hv_image_size(void);
/* external symbols that are helpful for relocation */ uint64_t arch_get_hv_image_delta(void);
extern uint8_t _DYNAMIC[1];
static inline uint64_t get_hv_image_delta(void)
{
return arch_get_hv_image_delta();
}
/* get the actual Hypervisor load address (HVA) */
static inline uint64_t get_hv_image_base(void)
{
return (get_hv_image_delta() + CONFIG_HV_RAM_START);
}
static inline uint64_t get_hv_image_size(void)
{
return (uint64_t)(&ld_ram_end - &ld_ram_start);
}
#ifdef CONFIG_RELOC
extern void relocate(struct Elf64_Dyn *dynamic);
#endif
#endif /* RELOCATE_H */ #endif /* RELOCATE_H */