]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/ukreloc/arch/x86_64: Add `ur_mov` instruction macro
authorSergiu Moga <sergiu.moga@protonmail.com>
Wed, 22 Mar 2023 19:10:42 +0000 (21:10 +0200)
committerUnikraft <monkey@unikraft.io>
Fri, 11 Aug 2023 08:11:27 +0000 (08:11 +0000)
Due to the high number of references to absolute symbol values in the
16-bit and 32-bit bootstrap code, a new macro, `ur_mov`, was introduced.
The new macro creates a new type of `_uk_reloc_` symbol, with an `imm`
suffix, to show that it is placed right after a `mov` instruction whose
immediate value must be relocated/patched. Thus, update `mkukreloc.py`
accordingly.

Furthermore, although useless, for completeness's sake add a 64-bit
variant. This variant does a `movabs` with the placeholder to
guarantee that the size of the immediate is 8 bytes.

Signed-off-by: Sergiu Moga <sergiu.moga@protonmail.com>
Reviewed-by: Dragos Petre <dragos.petre27@gmail.com>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Razvan Deaconescu <razvand@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #772

lib/ukreloc/arch/x86_64/include/uk/asm/reloc.h [new file with mode: 0644]
support/scripts/mkukreloc.py

diff --git a/lib/ukreloc/arch/x86_64/include/uk/asm/reloc.h b/lib/ukreloc/arch/x86_64/include/uk/asm/reloc.h
new file mode 100644 (file)
index 0000000..a2925b0
--- /dev/null
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors.
+ * Licensed under the BSD-3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ */
+
+#ifndef __UK_RELOC_H__
+#error Do not include this header directly
+#endif
+
+#ifdef __ASSEMBLY__
+
+/* Relocation-friendly ur_mov to replace mov instructions incompatible with
+ * a PIE binary. Usage example:
+ * ```
+ * ur_mov      gdt64_ptr, %eax, 4
+ * ```
+ * The above will get mkukreloc.py to process the symbol gdt64_ptr_ukeloc_imm4
+ * representing in memory where this data is placed and the following entry:
+ * struct uk_reloc {
+ *        __u64 r_mem_off = gdt64_ptr_ukeloc_imm4 - __BASE_ADDR
+ *        __u64 r_addr = gdt64_ptr - __BASE_ADDR
+ *        __u32 r_sz = 4 from gdt64_ptr_ukeloc_imm[4]
+ *        __u32 flags = 0
+ * } __packed;
+ *
+ * If CONFIG_LIBUKRELOC is not enabled then it will be simply resolved to
+ * ```
+ * mov $gdt64_ptr, %eax
+ * ```
+ *
+ * @param sym The symbol to relocate
+ * @param req The register into which to place the value
+ * @param bytes The size in bytes of the relocation
+ * @param flags Optional, if value is _phys, UKRELOC_FLAGS_PHYS_REL is set
+ */
+.macro ur_mov  sym:req, reg:req, bytes:req, flags
+#if CONFIG_LIBUKRELOC
+/* UKRELOC_PLACEHODER is 16 bits, so in 64-bit code we must force a `movabs`
+ * to ensure that the last amount of opcodes are meant for the immediate
+ */
+.ifeq  (8 - \bytes)
+       movabs  $UKRELOC_PLACEHOLDER, \reg
+.endif
+.ifgt  (8 - \bytes)
+       mov     $UKRELOC_PLACEHOLDER, \reg
+.endif
+       ur_sym  \sym\()_uk_reloc_imm\bytes\()\flags\(), (. - \bytes)
+       nop
+       ur_sec_updt     \sym
+#else  /* CONFIG_LIBUKRELOC */
+       mov     $\sym, \reg
+#endif /* !CONFIG_LIBUKRELOC */
+.endm
+
+#endif /* __ASSEMBLY__ */
index 423d0526e69097c95279d291e870af477b00a769..c955046e0e918822ae373e7925e31eec959d0ddc 100755 (executable)
@@ -221,6 +221,7 @@ def uk_reloc_sym_to_struct(elf, uk_reloc_sym):
 def build_uk_relocs(elf, rela_dyn_secs, max_r_mem_off):
     uk_relocs = [rela_to_uk_reloc(r) for r in rela_dyn_secs]
     uk_reloc_syms = get_nm_syms(elf, get_uk_reloc_sym_exp(r'data'))
+    uk_reloc_syms += get_nm_syms(elf, get_uk_reloc_sym_exp(r'imm'))
 
     # Also gather all of the PTE uk_reloc's for use against relocatable
     # PTE's.