LCOV - code coverage report
Current view: top level - arch/x86/include/asm - elf.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 10 10 100.0 %
Date: 2022-04-01 14:35:51 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: GPL-2.0 */
       2                 :            : #ifndef _ASM_X86_ELF_H
       3                 :            : #define _ASM_X86_ELF_H
       4                 :            : 
       5                 :            : /*
       6                 :            :  * ELF register definitions..
       7                 :            :  */
       8                 :            : #include <linux/thread_info.h>
       9                 :            : 
      10                 :            : #include <asm/ptrace.h>
      11                 :            : #include <asm/user.h>
      12                 :            : #include <asm/auxvec.h>
      13                 :            : #include <asm/fsgsbase.h>
      14                 :            : 
      15                 :            : typedef unsigned long elf_greg_t;
      16                 :            : 
      17                 :            : #define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
      18                 :            : typedef elf_greg_t elf_gregset_t[ELF_NGREG];
      19                 :            : 
      20                 :            : typedef struct user_i387_struct elf_fpregset_t;
      21                 :            : 
      22                 :            : #ifdef __i386__
      23                 :            : 
      24                 :            : typedef struct user_fxsr_struct elf_fpxregset_t;
      25                 :            : 
      26                 :            : #define R_386_NONE      0
      27                 :            : #define R_386_32        1
      28                 :            : #define R_386_PC32      2
      29                 :            : #define R_386_GOT32     3
      30                 :            : #define R_386_PLT32     4
      31                 :            : #define R_386_COPY      5
      32                 :            : #define R_386_GLOB_DAT  6
      33                 :            : #define R_386_JMP_SLOT  7
      34                 :            : #define R_386_RELATIVE  8
      35                 :            : #define R_386_GOTOFF    9
      36                 :            : #define R_386_GOTPC     10
      37                 :            : #define R_386_NUM       11
      38                 :            : 
      39                 :            : /*
      40                 :            :  * These are used to set parameters in the core dumps.
      41                 :            :  */
      42                 :            : #define ELF_CLASS       ELFCLASS32
      43                 :            : #define ELF_DATA        ELFDATA2LSB
      44                 :            : #define ELF_ARCH        EM_386
      45                 :            : 
      46                 :            : #else
      47                 :            : 
      48                 :            : /* x86-64 relocation types */
      49                 :            : #define R_X86_64_NONE           0       /* No reloc */
      50                 :            : #define R_X86_64_64             1       /* Direct 64 bit  */
      51                 :            : #define R_X86_64_PC32           2       /* PC relative 32 bit signed */
      52                 :            : #define R_X86_64_GOT32          3       /* 32 bit GOT entry */
      53                 :            : #define R_X86_64_PLT32          4       /* 32 bit PLT address */
      54                 :            : #define R_X86_64_COPY           5       /* Copy symbol at runtime */
      55                 :            : #define R_X86_64_GLOB_DAT       6       /* Create GOT entry */
      56                 :            : #define R_X86_64_JUMP_SLOT      7       /* Create PLT entry */
      57                 :            : #define R_X86_64_RELATIVE       8       /* Adjust by program base */
      58                 :            : #define R_X86_64_GOTPCREL       9       /* 32 bit signed pc relative
      59                 :            :                                            offset to GOT */
      60                 :            : #define R_X86_64_32             10      /* Direct 32 bit zero extended */
      61                 :            : #define R_X86_64_32S            11      /* Direct 32 bit sign extended */
      62                 :            : #define R_X86_64_16             12      /* Direct 16 bit zero extended */
      63                 :            : #define R_X86_64_PC16           13      /* 16 bit sign extended pc relative */
      64                 :            : #define R_X86_64_8              14      /* Direct 8 bit sign extended  */
      65                 :            : #define R_X86_64_PC8            15      /* 8 bit sign extended pc relative */
      66                 :            : #define R_X86_64_PC64           24      /* Place relative 64-bit signed */
      67                 :            : 
      68                 :            : /*
      69                 :            :  * These are used to set parameters in the core dumps.
      70                 :            :  */
      71                 :            : #define ELF_CLASS       ELFCLASS64
      72                 :            : #define ELF_DATA        ELFDATA2LSB
      73                 :            : #define ELF_ARCH        EM_X86_64
      74                 :            : 
      75                 :            : #endif
      76                 :            : 
      77                 :            : #include <asm/vdso.h>
      78                 :            : 
      79                 :            : #ifdef CONFIG_X86_64
      80                 :            : extern unsigned int vdso64_enabled;
      81                 :            : #endif
      82                 :            : #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
      83                 :            : extern unsigned int vdso32_enabled;
      84                 :            : #endif
      85                 :            : 
      86                 :            : /*
      87                 :            :  * This is used to ensure we don't load something for the wrong architecture.
      88                 :            :  */
      89                 :            : #define elf_check_arch_ia32(x) \
      90                 :            :         (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486))
      91                 :            : 
      92                 :            : #include <asm/processor.h>
      93                 :            : 
      94                 :            : #ifdef CONFIG_X86_32
      95                 :            : #include <asm/desc.h>
      96                 :            : 
      97                 :            : #define elf_check_arch(x)       elf_check_arch_ia32(x)
      98                 :            : 
      99                 :            : /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx
     100                 :            :    contains a pointer to a function which might be registered using `atexit'.
     101                 :            :    This provides a mean for the dynamic linker to call DT_FINI functions for
     102                 :            :    shared libraries that have been loaded before the code runs.
     103                 :            : 
     104                 :            :    A value of 0 tells we have no such handler.
     105                 :            : 
     106                 :            :    We might as well make sure everything else is cleared too (except for %esp),
     107                 :            :    just to make things more deterministic.
     108                 :            :  */
     109                 :            : #define ELF_PLAT_INIT(_r, load_addr)            \
     110                 :            :         do {                                    \
     111                 :            :         _r->bx = 0; _r->cx = 0; _r->dx = 0;    \
     112                 :            :         _r->si = 0; _r->di = 0; _r->bp = 0;    \
     113                 :            :         _r->ax = 0;                          \
     114                 :            : } while (0)
     115                 :            : 
     116                 :            : /*
     117                 :            :  * regs is struct pt_regs, pr_reg is elf_gregset_t (which is
     118                 :            :  * now struct_user_regs, they are different)
     119                 :            :  */
     120                 :            : 
     121                 :            : #define ELF_CORE_COPY_REGS_COMMON(pr_reg, regs) \
     122                 :            : do {                                            \
     123                 :            :         pr_reg[0] = regs->bx;                        \
     124                 :            :         pr_reg[1] = regs->cx;                        \
     125                 :            :         pr_reg[2] = regs->dx;                        \
     126                 :            :         pr_reg[3] = regs->si;                        \
     127                 :            :         pr_reg[4] = regs->di;                        \
     128                 :            :         pr_reg[5] = regs->bp;                        \
     129                 :            :         pr_reg[6] = regs->ax;                        \
     130                 :            :         pr_reg[7] = regs->ds;                        \
     131                 :            :         pr_reg[8] = regs->es;                        \
     132                 :            :         pr_reg[9] = regs->fs;                        \
     133                 :            :         pr_reg[11] = regs->orig_ax;          \
     134                 :            :         pr_reg[12] = regs->ip;                       \
     135                 :            :         pr_reg[13] = regs->cs;                       \
     136                 :            :         pr_reg[14] = regs->flags;            \
     137                 :            :         pr_reg[15] = regs->sp;                       \
     138                 :            :         pr_reg[16] = regs->ss;                       \
     139                 :            : } while (0);
     140                 :            : 
     141                 :            : #define ELF_CORE_COPY_REGS(pr_reg, regs)        \
     142                 :            : do {                                            \
     143                 :            :         ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
     144                 :            :         pr_reg[10] = get_user_gs(regs);         \
     145                 :            : } while (0);
     146                 :            : 
     147                 :            : #define ELF_CORE_COPY_KERNEL_REGS(pr_reg, regs) \
     148                 :            : do {                                            \
     149                 :            :         ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
     150                 :            :         savesegment(gs, pr_reg[10]);            \
     151                 :            : } while (0);
     152                 :            : 
     153                 :            : #define ELF_PLATFORM    (utsname()->machine)
     154                 :            : #define set_personality_64bit() do { } while (0)
     155                 :            : 
     156                 :            : #else /* CONFIG_X86_32 */
     157                 :            : 
     158                 :            : /*
     159                 :            :  * This is used to ensure we don't load something for the wrong architecture.
     160                 :            :  */
     161                 :            : #define elf_check_arch(x)                       \
     162                 :            :         ((x)->e_machine == EM_X86_64)
     163                 :            : 
     164                 :            : #define compat_elf_check_arch(x)                                        \
     165                 :            :         (elf_check_arch_ia32(x) ||                                      \
     166                 :            :          (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64))
     167                 :            : 
     168                 :            : #if __USER32_DS != __USER_DS
     169                 :            : # error "The following code assumes __USER32_DS == __USER_DS"
     170                 :            : #endif
     171                 :            : 
     172                 :      22071 : static inline void elf_common_init(struct thread_struct *t,
     173                 :            :                                    struct pt_regs *regs, const u16 ds)
     174                 :            : {
     175                 :            :         /* ax gets execve's return value. */
     176                 :      22071 :         /*regs->ax = */ regs->bx = regs->cx = regs->dx = 0;
     177                 :      22071 :         regs->si = regs->di = regs->bp = 0;
     178                 :      22071 :         regs->r8 = regs->r9 = regs->r10 = regs->r11 = 0;
     179                 :      22071 :         regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;
     180                 :      22071 :         t->fsbase = t->gsbase = 0;
     181                 :      22071 :         t->fsindex = t->gsindex = 0;
     182                 :      22071 :         t->ds = t->es = ds;
     183                 :            : }
     184                 :            : 
     185                 :            : #define ELF_PLAT_INIT(_r, load_addr)                    \
     186                 :            :         elf_common_init(&current->thread, _r, 0)
     187                 :            : 
     188                 :            : #define COMPAT_ELF_PLAT_INIT(regs, load_addr)           \
     189                 :            :         elf_common_init(&current->thread, regs, __USER_DS)
     190                 :            : 
     191                 :            : void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp);
     192                 :            : #define compat_start_thread compat_start_thread
     193                 :            : 
     194                 :            : void set_personality_ia32(bool);
     195                 :            : #define COMPAT_SET_PERSONALITY(ex)                      \
     196                 :            :         set_personality_ia32((ex).e_machine == EM_X86_64)
     197                 :            : 
     198                 :            : #define COMPAT_ELF_PLATFORM                     ("i686")
     199                 :            : 
     200                 :            : /*
     201                 :            :  * regs is struct pt_regs, pr_reg is elf_gregset_t (which is
     202                 :            :  * now struct_user_regs, they are different). Assumes current is the process
     203                 :            :  * getting dumped.
     204                 :            :  */
     205                 :            : 
     206                 :            : #define ELF_CORE_COPY_REGS(pr_reg, regs)                        \
     207                 :            : do {                                                            \
     208                 :            :         unsigned v;                                             \
     209                 :            :         (pr_reg)[0] = (regs)->r15;                           \
     210                 :            :         (pr_reg)[1] = (regs)->r14;                           \
     211                 :            :         (pr_reg)[2] = (regs)->r13;                           \
     212                 :            :         (pr_reg)[3] = (regs)->r12;                           \
     213                 :            :         (pr_reg)[4] = (regs)->bp;                            \
     214                 :            :         (pr_reg)[5] = (regs)->bx;                            \
     215                 :            :         (pr_reg)[6] = (regs)->r11;                           \
     216                 :            :         (pr_reg)[7] = (regs)->r10;                           \
     217                 :            :         (pr_reg)[8] = (regs)->r9;                            \
     218                 :            :         (pr_reg)[9] = (regs)->r8;                            \
     219                 :            :         (pr_reg)[10] = (regs)->ax;                           \
     220                 :            :         (pr_reg)[11] = (regs)->cx;                           \
     221                 :            :         (pr_reg)[12] = (regs)->dx;                           \
     222                 :            :         (pr_reg)[13] = (regs)->si;                           \
     223                 :            :         (pr_reg)[14] = (regs)->di;                           \
     224                 :            :         (pr_reg)[15] = (regs)->orig_ax;                              \
     225                 :            :         (pr_reg)[16] = (regs)->ip;                           \
     226                 :            :         (pr_reg)[17] = (regs)->cs;                           \
     227                 :            :         (pr_reg)[18] = (regs)->flags;                                \
     228                 :            :         (pr_reg)[19] = (regs)->sp;                           \
     229                 :            :         (pr_reg)[20] = (regs)->ss;                           \
     230                 :            :         (pr_reg)[21] = x86_fsbase_read_cpu();                   \
     231                 :            :         (pr_reg)[22] = x86_gsbase_read_cpu_inactive();          \
     232                 :            :         asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v;   \
     233                 :            :         asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v;   \
     234                 :            :         asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v;   \
     235                 :            :         asm("movl %%gs,%0" : "=r" (v)); (pr_reg)[26] = v;   \
     236                 :            : } while (0);
     237                 :            : 
     238                 :            : /* I'm not sure if we can use '-' here */
     239                 :            : #define ELF_PLATFORM       ("x86_64")
     240                 :            : extern void set_personality_64bit(void);
     241                 :            : extern unsigned int sysctl_vsyscall32;
     242                 :            : extern int force_personality32;
     243                 :            : 
     244                 :            : #endif /* !CONFIG_X86_32 */
     245                 :            : 
     246                 :            : #define CORE_DUMP_USE_REGSET
     247                 :            : #define ELF_EXEC_PAGESIZE       4096
     248                 :            : 
     249                 :            : /*
     250                 :            :  * This is the base location for PIE (ET_DYN with INTERP) loads. On
     251                 :            :  * 64-bit, this is above 4GB to leave the entire 32-bit address
     252                 :            :  * space open for things that want to use the area for 32-bit pointers.
     253                 :            :  */
     254                 :            : #define ELF_ET_DYN_BASE         (mmap_is_ia32() ? 0x000400000UL : \
     255                 :            :                                                   (DEFAULT_MAP_WINDOW / 3 * 2))
     256                 :            : 
     257                 :            : /* This yields a mask that user programs can use to figure out what
     258                 :            :    instruction set this CPU supports.  This could be done in user space,
     259                 :            :    but it's not easy, and we've already done it here.  */
     260                 :            : 
     261                 :            : #define ELF_HWCAP               (boot_cpu_data.x86_capability[CPUID_1_EDX])
     262                 :            : 
     263                 :            : extern u32 elf_hwcap2;
     264                 :            : 
     265                 :            : /*
     266                 :            :  * HWCAP2 supplies mask with kernel enabled CPU features, so that
     267                 :            :  * the application can discover that it can safely use them.
     268                 :            :  * The bits are defined in uapi/asm/hwcap2.h.
     269                 :            :  */
     270                 :            : #define ELF_HWCAP2              (elf_hwcap2)
     271                 :            : 
     272                 :            : /* This yields a string that ld.so will use to load implementation
     273                 :            :    specific libraries for optimization.  This is more specific in
     274                 :            :    intent than poking at uname or /proc/cpuinfo.
     275                 :            : 
     276                 :            :    For the moment, we have only optimizations for the Intel generations,
     277                 :            :    but that could change... */
     278                 :            : 
     279                 :            : #define SET_PERSONALITY(ex) set_personality_64bit()
     280                 :            : 
     281                 :            : /*
     282                 :            :  * An executable for which elf_read_implies_exec() returns TRUE will
     283                 :            :  * have the READ_IMPLIES_EXEC personality flag set automatically.
     284                 :            :  */
     285                 :            : #define elf_read_implies_exec(ex, executable_stack)     \
     286                 :            :         (executable_stack != EXSTACK_DISABLE_X)
     287                 :            : 
     288                 :            : struct task_struct;
     289                 :            : 
     290                 :            : #define ARCH_DLINFO_IA32                                                \
     291                 :            : do {                                                                    \
     292                 :            :         if (VDSO_CURRENT_BASE) {                                        \
     293                 :            :                 NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY);                    \
     294                 :            :                 NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE);        \
     295                 :            :         }                                                               \
     296                 :            : } while (0)
     297                 :            : 
     298                 :            : /*
     299                 :            :  * True on X86_32 or when emulating IA32 on X86_64
     300                 :            :  */
     301                 :     151347 : static inline int mmap_is_ia32(void)
     302                 :            : {
     303                 :     151347 :         return IS_ENABLED(CONFIG_X86_32) ||
     304                 :            :                (IS_ENABLED(CONFIG_COMPAT) &&
     305                 :            :                 test_thread_flag(TIF_ADDR32));
     306                 :            : }
     307                 :            : 
     308                 :            : extern unsigned long task_size_32bit(void);
     309                 :            : extern unsigned long task_size_64bit(int full_addr_space);
     310                 :            : extern unsigned long get_mmap_base(int is_legacy);
     311                 :            : extern bool mmap_address_hint_valid(unsigned long addr, unsigned long len);
     312                 :            : 
     313                 :            : #ifdef CONFIG_X86_32
     314                 :            : 
     315                 :            : #define __STACK_RND_MASK(is32bit) (0x7ff)
     316                 :            : #define STACK_RND_MASK (0x7ff)
     317                 :            : 
     318                 :            : #define ARCH_DLINFO             ARCH_DLINFO_IA32
     319                 :            : 
     320                 :            : /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
     321                 :            : 
     322                 :            : #else /* CONFIG_X86_32 */
     323                 :            : 
     324                 :            : /* 1GB for 64bit, 8MB for 32bit */
     325                 :            : #define __STACK_RND_MASK(is32bit) ((is32bit) ? 0x7ff : 0x3fffff)
     326                 :            : #define STACK_RND_MASK __STACK_RND_MASK(mmap_is_ia32())
     327                 :            : 
     328                 :            : #define ARCH_DLINFO                                                     \
     329                 :            : do {                                                                    \
     330                 :            :         if (vdso64_enabled)                                             \
     331                 :            :                 NEW_AUX_ENT(AT_SYSINFO_EHDR,                            \
     332                 :            :                             (unsigned long __force)current->mm->context.vdso); \
     333                 :            : } while (0)
     334                 :            : 
     335                 :            : /* As a historical oddity, the x32 and x86_64 vDSOs are controlled together. */
     336                 :            : #define ARCH_DLINFO_X32                                                 \
     337                 :            : do {                                                                    \
     338                 :            :         if (vdso64_enabled)                                             \
     339                 :            :                 NEW_AUX_ENT(AT_SYSINFO_EHDR,                            \
     340                 :            :                             (unsigned long __force)current->mm->context.vdso); \
     341                 :            : } while (0)
     342                 :            : 
     343                 :            : #define AT_SYSINFO              32
     344                 :            : 
     345                 :            : #define COMPAT_ARCH_DLINFO                                              \
     346                 :            : if (test_thread_flag(TIF_X32))                                          \
     347                 :            :         ARCH_DLINFO_X32;                                                \
     348                 :            : else                                                                    \
     349                 :            :         ARCH_DLINFO_IA32
     350                 :            : 
     351                 :            : #define COMPAT_ELF_ET_DYN_BASE  (TASK_UNMAPPED_BASE + 0x1000000)
     352                 :            : 
     353                 :            : #endif /* !CONFIG_X86_32 */
     354                 :            : 
     355                 :            : #define VDSO_CURRENT_BASE       ((unsigned long)current->mm->context.vdso)
     356                 :            : 
     357                 :            : #define VDSO_ENTRY                                                      \
     358                 :            :         ((unsigned long)current->mm->context.vdso +                       \
     359                 :            :          vdso_image_32.sym___kernel_vsyscall)
     360                 :            : 
     361                 :            : struct linux_binprm;
     362                 :            : 
     363                 :            : #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
     364                 :            : extern int arch_setup_additional_pages(struct linux_binprm *bprm,
     365                 :            :                                        int uses_interp);
     366                 :            : extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
     367                 :            :                                               int uses_interp);
     368                 :            : #define compat_arch_setup_additional_pages compat_arch_setup_additional_pages
     369                 :            : 
     370                 :            : /* Do not change the values. See get_align_mask() */
     371                 :            : enum align_flags {
     372                 :            :         ALIGN_VA_32     = BIT(0),
     373                 :            :         ALIGN_VA_64     = BIT(1),
     374                 :            : };
     375                 :            : 
     376                 :            : struct va_alignment {
     377                 :            :         int flags;
     378                 :            :         unsigned long mask;
     379                 :            :         unsigned long bits;
     380                 :            : } ____cacheline_aligned;
     381                 :            : 
     382                 :            : extern struct va_alignment va_align;
     383                 :            : extern unsigned long align_vdso_addr(unsigned long);
     384                 :            : #endif /* _ASM_X86_ELF_H */

Generated by: LCOV version 1.14