xref: /linux/arch/alpha/include/asm/elf.h (revision 621cde16e49b3ecf7d59a8106a20aaebfb4a59a9)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2024b246eSLinus Torvalds #ifndef __ASM_ALPHA_ELF_H
3024b246eSLinus Torvalds #define __ASM_ALPHA_ELF_H
4024b246eSLinus Torvalds 
5024b246eSLinus Torvalds #include <asm/auxvec.h>
6ec221208SDavid Howells #include <asm/special_insns.h>
7024b246eSLinus Torvalds 
8024b246eSLinus Torvalds /* Special values for the st_other field in the symbol table.  */
9024b246eSLinus Torvalds 
10024b246eSLinus Torvalds #define STO_ALPHA_NOPV		0x80
11024b246eSLinus Torvalds #define STO_ALPHA_STD_GPLOAD	0x88
12024b246eSLinus Torvalds 
13024b246eSLinus Torvalds /*
14024b246eSLinus Torvalds  * Alpha ELF relocation types
15024b246eSLinus Torvalds  */
16024b246eSLinus Torvalds #define R_ALPHA_NONE            0       /* No reloc */
17024b246eSLinus Torvalds #define R_ALPHA_REFLONG         1       /* Direct 32 bit */
18024b246eSLinus Torvalds #define R_ALPHA_REFQUAD         2       /* Direct 64 bit */
19024b246eSLinus Torvalds #define R_ALPHA_GPREL32         3       /* GP relative 32 bit */
20024b246eSLinus Torvalds #define R_ALPHA_LITERAL         4       /* GP relative 16 bit w/optimization */
21024b246eSLinus Torvalds #define R_ALPHA_LITUSE          5       /* Optimization hint for LITERAL */
22024b246eSLinus Torvalds #define R_ALPHA_GPDISP          6       /* Add displacement to GP */
23024b246eSLinus Torvalds #define R_ALPHA_BRADDR          7       /* PC+4 relative 23 bit shifted */
24024b246eSLinus Torvalds #define R_ALPHA_HINT            8       /* PC+4 relative 16 bit shifted */
25024b246eSLinus Torvalds #define R_ALPHA_SREL16          9       /* PC relative 16 bit */
26024b246eSLinus Torvalds #define R_ALPHA_SREL32          10      /* PC relative 32 bit */
27024b246eSLinus Torvalds #define R_ALPHA_SREL64          11      /* PC relative 64 bit */
28024b246eSLinus Torvalds #define R_ALPHA_GPRELHIGH       17      /* GP relative 32 bit, high 16 bits */
29024b246eSLinus Torvalds #define R_ALPHA_GPRELLOW        18      /* GP relative 32 bit, low 16 bits */
30024b246eSLinus Torvalds #define R_ALPHA_GPREL16         19      /* GP relative 16 bit */
31024b246eSLinus Torvalds #define R_ALPHA_COPY            24      /* Copy symbol at runtime */
32024b246eSLinus Torvalds #define R_ALPHA_GLOB_DAT        25      /* Create GOT entry */
33024b246eSLinus Torvalds #define R_ALPHA_JMP_SLOT        26      /* Create PLT entry */
34024b246eSLinus Torvalds #define R_ALPHA_RELATIVE        27      /* Adjust by program base */
35024b246eSLinus Torvalds #define R_ALPHA_BRSGP		28
36024b246eSLinus Torvalds #define R_ALPHA_TLSGD           29
37024b246eSLinus Torvalds #define R_ALPHA_TLS_LDM         30
38024b246eSLinus Torvalds #define R_ALPHA_DTPMOD64        31
39024b246eSLinus Torvalds #define R_ALPHA_GOTDTPREL       32
40024b246eSLinus Torvalds #define R_ALPHA_DTPREL64        33
41024b246eSLinus Torvalds #define R_ALPHA_DTPRELHI        34
42024b246eSLinus Torvalds #define R_ALPHA_DTPRELLO        35
43024b246eSLinus Torvalds #define R_ALPHA_DTPREL16        36
44024b246eSLinus Torvalds #define R_ALPHA_GOTTPREL        37
45024b246eSLinus Torvalds #define R_ALPHA_TPREL64         38
46024b246eSLinus Torvalds #define R_ALPHA_TPRELHI         39
47024b246eSLinus Torvalds #define R_ALPHA_TPRELLO         40
48024b246eSLinus Torvalds #define R_ALPHA_TPREL16         41
49024b246eSLinus Torvalds 
50024b246eSLinus Torvalds #define SHF_ALPHA_GPREL		0x10000000
51024b246eSLinus Torvalds 
52024b246eSLinus Torvalds /* Legal values for e_flags field of Elf64_Ehdr.  */
53024b246eSLinus Torvalds 
54024b246eSLinus Torvalds #define EF_ALPHA_32BIT		1	/* All addresses are below 2GB */
55024b246eSLinus Torvalds 
56024b246eSLinus Torvalds /*
57024b246eSLinus Torvalds  * ELF register definitions..
58024b246eSLinus Torvalds  */
59024b246eSLinus Torvalds 
60024b246eSLinus Torvalds /*
61024b246eSLinus Torvalds  * The OSF/1 version of <sys/procfs.h> makes gregset_t 46 entries long.
62024b246eSLinus Torvalds  * I have no idea why that is so.  For now, we just leave it at 33
63024b246eSLinus Torvalds  * (32 general regs + processor status word).
64024b246eSLinus Torvalds  */
65024b246eSLinus Torvalds #define ELF_NGREG	33
66024b246eSLinus Torvalds #define ELF_NFPREG	32
67024b246eSLinus Torvalds 
68024b246eSLinus Torvalds typedef unsigned long elf_greg_t;
69024b246eSLinus Torvalds typedef elf_greg_t elf_gregset_t[ELF_NGREG];
70024b246eSLinus Torvalds 
71024b246eSLinus Torvalds typedef double elf_fpreg_t;
72024b246eSLinus Torvalds typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
73024b246eSLinus Torvalds 
74024b246eSLinus Torvalds /*
75024b246eSLinus Torvalds  * This is used to ensure we don't load something for the wrong architecture.
76024b246eSLinus Torvalds  */
77024b246eSLinus Torvalds #define elf_check_arch(x) ((x)->e_machine == EM_ALPHA)
78024b246eSLinus Torvalds 
79024b246eSLinus Torvalds /*
80024b246eSLinus Torvalds  * These are used to set parameters in the core dumps.
81024b246eSLinus Torvalds  */
82024b246eSLinus Torvalds #define ELF_CLASS	ELFCLASS64
83024b246eSLinus Torvalds #define ELF_DATA	ELFDATA2LSB
84024b246eSLinus Torvalds #define ELF_ARCH	EM_ALPHA
85024b246eSLinus Torvalds 
86024b246eSLinus Torvalds #define ELF_EXEC_PAGESIZE	8192
87024b246eSLinus Torvalds 
88024b246eSLinus Torvalds /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
89024b246eSLinus Torvalds    use of this is to invoke "./ld.so someprog" to test out a new version of
90024b246eSLinus Torvalds    the loader.  We need to make sure that it is out of the way of the program
91024b246eSLinus Torvalds    that it will "exec", and that there is sufficient room for the brk.  */
92024b246eSLinus Torvalds 
93024b246eSLinus Torvalds #define ELF_ET_DYN_BASE		(TASK_UNMAPPED_BASE + 0x1000000)
94024b246eSLinus Torvalds 
95024b246eSLinus Torvalds /* $0 is set by ld.so to a pointer to a function which might be
96024b246eSLinus Torvalds    registered using atexit.  This provides a mean for the dynamic
97024b246eSLinus Torvalds    linker to call DT_FINI functions for shared libraries that have
98024b246eSLinus Torvalds    been loaded before the code runs.
99024b246eSLinus Torvalds 
100024b246eSLinus Torvalds    So that we can use the same startup file with static executables,
101024b246eSLinus Torvalds    we start programs with a value of 0 to indicate that there is no
102024b246eSLinus Torvalds    such function.  */
103024b246eSLinus Torvalds 
104024b246eSLinus Torvalds #define ELF_PLAT_INIT(_r, load_addr)	_r->r0 = 0
105024b246eSLinus Torvalds 
10625985edcSLucas De Marchi /* The registers are laid out in pt_regs for PAL and syscall
107024b246eSLinus Torvalds    convenience.  Re-order them for the linear elf_gregset_t.  */
108024b246eSLinus Torvalds 
109024b246eSLinus Torvalds struct pt_regs;
110024b246eSLinus Torvalds struct thread_info;
111024b246eSLinus Torvalds struct task_struct;
112024b246eSLinus Torvalds extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt,
113024b246eSLinus Torvalds 			    struct thread_info *ti);
114024b246eSLinus Torvalds #define ELF_CORE_COPY_REGS(DEST, REGS) \
115024b246eSLinus Torvalds 	dump_elf_thread(DEST, REGS, current_thread_info());
116024b246eSLinus Torvalds 
117024b246eSLinus Torvalds /* Similar, but for a thread other than current.  */
118024b246eSLinus Torvalds 
119024b246eSLinus Torvalds extern int dump_elf_task(elf_greg_t *dest, struct task_struct *task);
120024b246eSLinus Torvalds #define ELF_CORE_COPY_TASK_REGS(TASK, DEST) \
121024b246eSLinus Torvalds 	dump_elf_task(*(DEST), TASK)
122024b246eSLinus Torvalds 
123024b246eSLinus Torvalds /* This yields a mask that user programs can use to figure out what
124024b246eSLinus Torvalds    instruction set this CPU supports.  This is trivial on Alpha,
125024b246eSLinus Torvalds    but not so on other machines. */
126024b246eSLinus Torvalds 
127024b246eSLinus Torvalds #define ELF_HWCAP  (~amask(-1))
128024b246eSLinus Torvalds 
129024b246eSLinus Torvalds /* This yields a string that ld.so will use to load implementation
130024b246eSLinus Torvalds    specific libraries for optimization.  This is more specific in
131024b246eSLinus Torvalds    intent than poking at uname or /proc/cpuinfo.  */
132024b246eSLinus Torvalds 
133024b246eSLinus Torvalds #define ELF_PLATFORM				\
134024b246eSLinus Torvalds ({						\
135024b246eSLinus Torvalds 	enum implver_enum i_ = implver();	\
136*a4184174SArnd Bergmann 	( i_ == IMPLVER_EV5 ? "ev56"			\
137024b246eSLinus Torvalds 	: amask (AMASK_CIX) ? "ev6" : "ev67");	\
138024b246eSLinus Torvalds })
139024b246eSLinus Torvalds 
1400b592682SMartin Schwidefsky #define SET_PERSONALITY(EX)					\
141024b246eSLinus Torvalds 	set_personality(((EX).e_flags & EF_ALPHA_32BIT)		\
1420b592682SMartin Schwidefsky 	   ? PER_LINUX_32BIT : PER_LINUX)
143024b246eSLinus Torvalds 
144024b246eSLinus Torvalds extern int alpha_l1i_cacheshape;
145024b246eSLinus Torvalds extern int alpha_l1d_cacheshape;
146024b246eSLinus Torvalds extern int alpha_l2_cacheshape;
147024b246eSLinus Torvalds extern int alpha_l3_cacheshape;
148024b246eSLinus Torvalds 
149024b246eSLinus Torvalds /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
150024b246eSLinus Torvalds #define ARCH_DLINFO						\
151024b246eSLinus Torvalds   do {								\
152024b246eSLinus Torvalds     NEW_AUX_ENT(AT_L1I_CACHESHAPE, alpha_l1i_cacheshape);	\
153024b246eSLinus Torvalds     NEW_AUX_ENT(AT_L1D_CACHESHAPE, alpha_l1d_cacheshape);	\
154024b246eSLinus Torvalds     NEW_AUX_ENT(AT_L2_CACHESHAPE, alpha_l2_cacheshape);		\
155024b246eSLinus Torvalds     NEW_AUX_ENT(AT_L3_CACHESHAPE, alpha_l3_cacheshape);		\
156024b246eSLinus Torvalds   } while (0)
157024b246eSLinus Torvalds 
158024b246eSLinus Torvalds #endif /* __ASM_ALPHA_ELF_H */
159