162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 362306a36Sopenharmony_ci * Licensed under the GPL 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci#ifndef __UM_ELF_X86_H 662306a36Sopenharmony_ci#define __UM_ELF_X86_H 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <asm/user.h> 962306a36Sopenharmony_ci#include <skas.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#ifdef CONFIG_X86_32 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define R_386_NONE 0 1462306a36Sopenharmony_ci#define R_386_32 1 1562306a36Sopenharmony_ci#define R_386_PC32 2 1662306a36Sopenharmony_ci#define R_386_GOT32 3 1762306a36Sopenharmony_ci#define R_386_PLT32 4 1862306a36Sopenharmony_ci#define R_386_COPY 5 1962306a36Sopenharmony_ci#define R_386_GLOB_DAT 6 2062306a36Sopenharmony_ci#define R_386_JMP_SLOT 7 2162306a36Sopenharmony_ci#define R_386_RELATIVE 8 2262306a36Sopenharmony_ci#define R_386_GOTOFF 9 2362306a36Sopenharmony_ci#define R_386_GOTPC 10 2462306a36Sopenharmony_ci#define R_386_NUM 11 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci/* 2762306a36Sopenharmony_ci * This is used to ensure we don't load something for the wrong architecture. 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_ci#define elf_check_arch(x) \ 3062306a36Sopenharmony_ci (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define ELF_CLASS ELFCLASS32 3362306a36Sopenharmony_ci#define ELF_DATA ELFDATA2LSB 3462306a36Sopenharmony_ci#define ELF_ARCH EM_386 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define ELF_PLAT_INIT(regs, load_addr) do { \ 3762306a36Sopenharmony_ci PT_REGS_BX(regs) = 0; \ 3862306a36Sopenharmony_ci PT_REGS_CX(regs) = 0; \ 3962306a36Sopenharmony_ci PT_REGS_DX(regs) = 0; \ 4062306a36Sopenharmony_ci PT_REGS_SI(regs) = 0; \ 4162306a36Sopenharmony_ci PT_REGS_DI(regs) = 0; \ 4262306a36Sopenharmony_ci PT_REGS_BP(regs) = 0; \ 4362306a36Sopenharmony_ci PT_REGS_AX(regs) = 0; \ 4462306a36Sopenharmony_ci} while (0) 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* Shamelessly stolen from include/asm-i386/elf.h */ 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ 4962306a36Sopenharmony_ci pr_reg[0] = PT_REGS_BX(regs); \ 5062306a36Sopenharmony_ci pr_reg[1] = PT_REGS_CX(regs); \ 5162306a36Sopenharmony_ci pr_reg[2] = PT_REGS_DX(regs); \ 5262306a36Sopenharmony_ci pr_reg[3] = PT_REGS_SI(regs); \ 5362306a36Sopenharmony_ci pr_reg[4] = PT_REGS_DI(regs); \ 5462306a36Sopenharmony_ci pr_reg[5] = PT_REGS_BP(regs); \ 5562306a36Sopenharmony_ci pr_reg[6] = PT_REGS_AX(regs); \ 5662306a36Sopenharmony_ci pr_reg[7] = PT_REGS_DS(regs); \ 5762306a36Sopenharmony_ci pr_reg[8] = PT_REGS_ES(regs); \ 5862306a36Sopenharmony_ci /* fake once used fs and gs selectors? */ \ 5962306a36Sopenharmony_ci pr_reg[9] = PT_REGS_DS(regs); \ 6062306a36Sopenharmony_ci pr_reg[10] = PT_REGS_DS(regs); \ 6162306a36Sopenharmony_ci pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ 6262306a36Sopenharmony_ci pr_reg[12] = PT_REGS_IP(regs); \ 6362306a36Sopenharmony_ci pr_reg[13] = PT_REGS_CS(regs); \ 6462306a36Sopenharmony_ci pr_reg[14] = PT_REGS_EFLAGS(regs); \ 6562306a36Sopenharmony_ci pr_reg[15] = PT_REGS_SP(regs); \ 6662306a36Sopenharmony_ci pr_reg[16] = PT_REGS_SS(regs); \ 6762306a36Sopenharmony_ci} while (0); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ciextern char * elf_aux_platform; 7062306a36Sopenharmony_ci#define ELF_PLATFORM (elf_aux_platform) 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciextern unsigned long vsyscall_ehdr; 7362306a36Sopenharmony_ciextern unsigned long vsyscall_end; 7462306a36Sopenharmony_ciextern unsigned long __kernel_vsyscall; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/* 7762306a36Sopenharmony_ci * This is the range that is readable by user mode, and things 7862306a36Sopenharmony_ci * acting like user mode such as get_user_pages. 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_ci#define FIXADDR_USER_START vsyscall_ehdr 8162306a36Sopenharmony_ci#define FIXADDR_USER_END vsyscall_end 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci/* 8562306a36Sopenharmony_ci * Architecture-neutral AT_ values in 0-17, leave some room 8662306a36Sopenharmony_ci * for more of them, start the x86-specific ones at 32. 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_ci#define AT_SYSINFO 32 8962306a36Sopenharmony_ci#define AT_SYSINFO_EHDR 33 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci#define ARCH_DLINFO \ 9262306a36Sopenharmony_cido { \ 9362306a36Sopenharmony_ci if ( vsyscall_ehdr ) { \ 9462306a36Sopenharmony_ci NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \ 9562306a36Sopenharmony_ci NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \ 9662306a36Sopenharmony_ci } \ 9762306a36Sopenharmony_ci} while (0) 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci#else 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/* x86-64 relocation types, taken from asm-x86_64/elf.h */ 10262306a36Sopenharmony_ci#define R_X86_64_NONE 0 /* No reloc */ 10362306a36Sopenharmony_ci#define R_X86_64_64 1 /* Direct 64 bit */ 10462306a36Sopenharmony_ci#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ 10562306a36Sopenharmony_ci#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ 10662306a36Sopenharmony_ci#define R_X86_64_PLT32 4 /* 32 bit PLT address */ 10762306a36Sopenharmony_ci#define R_X86_64_COPY 5 /* Copy symbol at runtime */ 10862306a36Sopenharmony_ci#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ 10962306a36Sopenharmony_ci#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ 11062306a36Sopenharmony_ci#define R_X86_64_RELATIVE 8 /* Adjust by program base */ 11162306a36Sopenharmony_ci#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative 11262306a36Sopenharmony_ci offset to GOT */ 11362306a36Sopenharmony_ci#define R_X86_64_32 10 /* Direct 32 bit zero extended */ 11462306a36Sopenharmony_ci#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ 11562306a36Sopenharmony_ci#define R_X86_64_16 12 /* Direct 16 bit zero extended */ 11662306a36Sopenharmony_ci#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ 11762306a36Sopenharmony_ci#define R_X86_64_8 14 /* Direct 8 bit sign extended */ 11862306a36Sopenharmony_ci#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ 11962306a36Sopenharmony_ci#define R_X86_64_PC64 24 /* Place relative 64-bit signed */ 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/* 12262306a36Sopenharmony_ci * This is used to ensure we don't load something for the wrong architecture. 12362306a36Sopenharmony_ci */ 12462306a36Sopenharmony_ci#define elf_check_arch(x) \ 12562306a36Sopenharmony_ci ((x)->e_machine == EM_X86_64) 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci#define ELF_CLASS ELFCLASS64 12862306a36Sopenharmony_ci#define ELF_DATA ELFDATA2LSB 12962306a36Sopenharmony_ci#define ELF_ARCH EM_X86_64 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci#define ELF_PLAT_INIT(regs, load_addr) do { \ 13262306a36Sopenharmony_ci PT_REGS_BX(regs) = 0; \ 13362306a36Sopenharmony_ci PT_REGS_CX(regs) = 0; \ 13462306a36Sopenharmony_ci PT_REGS_DX(regs) = 0; \ 13562306a36Sopenharmony_ci PT_REGS_SI(regs) = 0; \ 13662306a36Sopenharmony_ci PT_REGS_DI(regs) = 0; \ 13762306a36Sopenharmony_ci PT_REGS_BP(regs) = 0; \ 13862306a36Sopenharmony_ci PT_REGS_AX(regs) = 0; \ 13962306a36Sopenharmony_ci PT_REGS_R8(regs) = 0; \ 14062306a36Sopenharmony_ci PT_REGS_R9(regs) = 0; \ 14162306a36Sopenharmony_ci PT_REGS_R10(regs) = 0; \ 14262306a36Sopenharmony_ci PT_REGS_R11(regs) = 0; \ 14362306a36Sopenharmony_ci PT_REGS_R12(regs) = 0; \ 14462306a36Sopenharmony_ci PT_REGS_R13(regs) = 0; \ 14562306a36Sopenharmony_ci PT_REGS_R14(regs) = 0; \ 14662306a36Sopenharmony_ci PT_REGS_R15(regs) = 0; \ 14762306a36Sopenharmony_ci} while (0) 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci#define ELF_CORE_COPY_REGS(pr_reg, _regs) \ 15062306a36Sopenharmony_ci (pr_reg)[0] = (_regs)->regs.gp[0]; \ 15162306a36Sopenharmony_ci (pr_reg)[1] = (_regs)->regs.gp[1]; \ 15262306a36Sopenharmony_ci (pr_reg)[2] = (_regs)->regs.gp[2]; \ 15362306a36Sopenharmony_ci (pr_reg)[3] = (_regs)->regs.gp[3]; \ 15462306a36Sopenharmony_ci (pr_reg)[4] = (_regs)->regs.gp[4]; \ 15562306a36Sopenharmony_ci (pr_reg)[5] = (_regs)->regs.gp[5]; \ 15662306a36Sopenharmony_ci (pr_reg)[6] = (_regs)->regs.gp[6]; \ 15762306a36Sopenharmony_ci (pr_reg)[7] = (_regs)->regs.gp[7]; \ 15862306a36Sopenharmony_ci (pr_reg)[8] = (_regs)->regs.gp[8]; \ 15962306a36Sopenharmony_ci (pr_reg)[9] = (_regs)->regs.gp[9]; \ 16062306a36Sopenharmony_ci (pr_reg)[10] = (_regs)->regs.gp[10]; \ 16162306a36Sopenharmony_ci (pr_reg)[11] = (_regs)->regs.gp[11]; \ 16262306a36Sopenharmony_ci (pr_reg)[12] = (_regs)->regs.gp[12]; \ 16362306a36Sopenharmony_ci (pr_reg)[13] = (_regs)->regs.gp[13]; \ 16462306a36Sopenharmony_ci (pr_reg)[14] = (_regs)->regs.gp[14]; \ 16562306a36Sopenharmony_ci (pr_reg)[15] = (_regs)->regs.gp[15]; \ 16662306a36Sopenharmony_ci (pr_reg)[16] = (_regs)->regs.gp[16]; \ 16762306a36Sopenharmony_ci (pr_reg)[17] = (_regs)->regs.gp[17]; \ 16862306a36Sopenharmony_ci (pr_reg)[18] = (_regs)->regs.gp[18]; \ 16962306a36Sopenharmony_ci (pr_reg)[19] = (_regs)->regs.gp[19]; \ 17062306a36Sopenharmony_ci (pr_reg)[20] = (_regs)->regs.gp[20]; \ 17162306a36Sopenharmony_ci (pr_reg)[21] = current->thread.arch.fs; \ 17262306a36Sopenharmony_ci (pr_reg)[22] = 0; \ 17362306a36Sopenharmony_ci (pr_reg)[23] = 0; \ 17462306a36Sopenharmony_ci (pr_reg)[24] = 0; \ 17562306a36Sopenharmony_ci (pr_reg)[25] = 0; \ 17662306a36Sopenharmony_ci (pr_reg)[26] = 0; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci#define ELF_PLATFORM "x86_64" 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci/* No user-accessible fixmap addresses, i.e. vsyscall */ 18162306a36Sopenharmony_ci#define FIXADDR_USER_START 0 18262306a36Sopenharmony_ci#define FIXADDR_USER_END 0 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 18562306a36Sopenharmony_cistruct linux_binprm; 18662306a36Sopenharmony_ciextern int arch_setup_additional_pages(struct linux_binprm *bprm, 18762306a36Sopenharmony_ci int uses_interp); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ciextern unsigned long um_vdso_addr; 19062306a36Sopenharmony_ci#define AT_SYSINFO_EHDR 33 19162306a36Sopenharmony_ci#define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO_EHDR, um_vdso_addr) 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci#endif 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_citypedef unsigned long elf_greg_t; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) 19862306a36Sopenharmony_citypedef elf_greg_t elf_gregset_t[ELF_NGREG]; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_citypedef struct user_i387_struct elf_fpregset_t; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_cistruct task_struct; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci#define ELF_EXEC_PAGESIZE 4096 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ciextern long elf_aux_hwcap; 20962306a36Sopenharmony_ci#define ELF_HWCAP (elf_aux_hwcap) 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci#define SET_PERSONALITY(ex) do {} while(0) 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci#endif 214