OSDN Git Service

riscv: compat: Add elf.h implementation
authorGuo Ren <guoren@linux.alibaba.com>
Tue, 5 Apr 2022 07:13:08 +0000 (15:13 +0800)
committerPalmer Dabbelt <palmer@rivosinc.com>
Tue, 26 Apr 2022 20:36:42 +0000 (13:36 -0700)
Implement necessary type and macro for compat elf. See the code
comment for detail.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Link: https://lore.kernel.org/r/20220405071314.3225832-15-guoren@kernel.org
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/include/asm/elf.h

index f53c400..a234656 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _ASM_RISCV_ELF_H
 #define _ASM_RISCV_ELF_H
 
+#include <uapi/linux/elf.h>
+#include <linux/compat.h>
 #include <uapi/asm/elf.h>
 #include <asm/auxvec.h>
 #include <asm/byteorder.h>
  */
 #define ELF_ARCH       EM_RISCV
 
+#ifndef ELF_CLASS
 #ifdef CONFIG_64BIT
 #define ELF_CLASS      ELFCLASS64
 #else
 #define ELF_CLASS      ELFCLASS32
 #endif
+#endif
 
 #define ELF_DATA       ELFDATA2LSB
 
@@ -31,6 +35,8 @@
  */
 #define elf_check_arch(x) ((x)->e_machine == EM_RISCV)
 
+#define compat_elf_check_arch(x) ((x)->e_machine == EM_RISCV)
+
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE      (PAGE_SIZE)
 
 #define ELF_ET_DYN_BASE                ((TASK_SIZE / 3) * 2)
 
 #ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
+#define STACK_RND_MASK         (test_thread_flag(TIF_32BIT) ? \
+                                0x7ff >> (PAGE_SHIFT - 12) : \
+                                0x3ffff >> (PAGE_SHIFT - 12))
+#else
 #define STACK_RND_MASK         (0x3ffff >> (PAGE_SHIFT - 12))
 #endif
+#endif
 /*
  * This yields a mask that user programs can use to figure out what
  * instruction set this CPU supports.  This could be done in user space,
@@ -60,11 +72,19 @@ extern unsigned long elf_hwcap;
  */
 #define ELF_PLATFORM   (NULL)
 
+#define COMPAT_ELF_PLATFORM    (NULL)
+
 #ifdef CONFIG_MMU
 #define ARCH_DLINFO                                            \
 do {                                                           \
+       /*                                                      \
+        * Note that we add ulong after elf_addr_t because      \
+        * casting current->mm->context.vdso triggers a cast    \
+        * warning of cast from pointer to integer for          \
+        * COMPAT ELFCLASS32.                                   \
+        */                                                     \
        NEW_AUX_ENT(AT_SYSINFO_EHDR,                            \
-               (elf_addr_t)current->mm->context.vdso);         \
+               (elf_addr_t)(ulong)current->mm->context.vdso);  \
        NEW_AUX_ENT(AT_L1I_CACHESIZE,                           \
                get_cache_size(1, CACHE_TYPE_INST));            \
        NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY,                       \
@@ -90,4 +110,23 @@ do {                                                        \
                *(struct user_regs_struct *)regs;       \
 } while (0);
 
+#ifdef CONFIG_COMPAT
+
+#define SET_PERSONALITY(ex)                                    \
+do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)              \
+               set_thread_flag(TIF_32BIT);                     \
+       else                                                    \
+               clear_thread_flag(TIF_32BIT);                   \
+       if (personality(current->personality) != PER_LINUX32)   \
+               set_personality(PER_LINUX |                     \
+                       (current->personality & (~PER_MASK)));  \
+} while (0)
+
+#define COMPAT_ELF_ET_DYN_BASE         ((TASK_SIZE_32 / 3) * 2)
+
+/* rv32 registers */
+typedef compat_ulong_t                 compat_elf_greg_t;
+typedef compat_elf_greg_t              compat_elf_gregset_t[ELF_NGREG];
+
+#endif /* CONFIG_COMPAT */
 #endif /* _ASM_RISCV_ELF_H */