diff options
Diffstat (limited to 'arch/mips/include/asm/elf.h')
-rw-r--r-- | arch/mips/include/asm/elf.h | 74 |
1 files changed, 59 insertions, 15 deletions
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index 1d38fe0edd2d..eb4d95de619c 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
@@ -8,6 +8,8 @@ | |||
8 | #ifndef _ASM_ELF_H | 8 | #ifndef _ASM_ELF_H |
9 | #define _ASM_ELF_H | 9 | #define _ASM_ELF_H |
10 | 10 | ||
11 | #include <linux/fs.h> | ||
12 | #include <uapi/linux/elf.h> | ||
11 | 13 | ||
12 | /* ELF header e_flags defines. */ | 14 | /* ELF header e_flags defines. */ |
13 | /* MIPS architecture level. */ | 15 | /* MIPS architecture level. */ |
@@ -28,6 +30,7 @@ | |||
28 | #define PT_MIPS_REGINFO 0x70000000 | 30 | #define PT_MIPS_REGINFO 0x70000000 |
29 | #define PT_MIPS_RTPROC 0x70000001 | 31 | #define PT_MIPS_RTPROC 0x70000001 |
30 | #define PT_MIPS_OPTIONS 0x70000002 | 32 | #define PT_MIPS_OPTIONS 0x70000002 |
33 | #define PT_MIPS_ABIFLAGS 0x70000003 | ||
31 | 34 | ||
32 | /* Flags in the e_flags field of the header */ | 35 | /* Flags in the e_flags field of the header */ |
33 | #define EF_MIPS_NOREORDER 0x00000001 | 36 | #define EF_MIPS_NOREORDER 0x00000001 |
@@ -174,6 +177,30 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | |||
174 | typedef double elf_fpreg_t; | 177 | typedef double elf_fpreg_t; |
175 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | 178 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; |
176 | 179 | ||
180 | struct mips_elf_abiflags_v0 { | ||
181 | uint16_t version; /* Version of flags structure */ | ||
182 | uint8_t isa_level; /* The level of the ISA: 1-5, 32, 64 */ | ||
183 | uint8_t isa_rev; /* The revision of ISA: 0 for MIPS V and below, | ||
184 | 1-n otherwise */ | ||
185 | uint8_t gpr_size; /* The size of general purpose registers */ | ||
186 | uint8_t cpr1_size; /* The size of co-processor 1 registers */ | ||
187 | uint8_t cpr2_size; /* The size of co-processor 2 registers */ | ||
188 | uint8_t fp_abi; /* The floating-point ABI */ | ||
189 | uint32_t isa_ext; /* Mask of processor-specific extensions */ | ||
190 | uint32_t ases; /* Mask of ASEs used */ | ||
191 | uint32_t flags1; /* Mask of general flags */ | ||
192 | uint32_t flags2; | ||
193 | }; | ||
194 | |||
195 | #define MIPS_ABI_FP_ANY 0 /* FP ABI doesn't matter */ | ||
196 | #define MIPS_ABI_FP_DOUBLE 1 /* -mdouble-float */ | ||
197 | #define MIPS_ABI_FP_SINGLE 2 /* -msingle-float */ | ||
198 | #define MIPS_ABI_FP_SOFT 3 /* -msoft-float */ | ||
199 | #define MIPS_ABI_FP_OLD_64 4 /* -mips32r2 -mfp64 */ | ||
200 | #define MIPS_ABI_FP_XX 5 /* -mfpxx */ | ||
201 | #define MIPS_ABI_FP_64 6 /* -mips32r2 -mfp64 */ | ||
202 | #define MIPS_ABI_FP_64A 7 /* -mips32r2 -mfp64 -mno-odd-spreg */ | ||
203 | |||
177 | #ifdef CONFIG_32BIT | 204 | #ifdef CONFIG_32BIT |
178 | 205 | ||
179 | /* | 206 | /* |
@@ -262,16 +289,13 @@ extern struct mips_abi mips_abi_n32; | |||
262 | 289 | ||
263 | #ifdef CONFIG_32BIT | 290 | #ifdef CONFIG_32BIT |
264 | 291 | ||
265 | #define SET_PERSONALITY(ex) \ | 292 | #define SET_PERSONALITY2(ex, state) \ |
266 | do { \ | 293 | do { \ |
267 | if ((ex).e_flags & EF_MIPS_FP64) \ | ||
268 | clear_thread_flag(TIF_32BIT_FPREGS); \ | ||
269 | else \ | ||
270 | set_thread_flag(TIF_32BIT_FPREGS); \ | ||
271 | \ | ||
272 | if (personality(current->personality) != PER_LINUX) \ | 294 | if (personality(current->personality) != PER_LINUX) \ |
273 | set_personality(PER_LINUX); \ | 295 | set_personality(PER_LINUX); \ |
274 | \ | 296 | \ |
297 | mips_set_personality_fp(state); \ | ||
298 | \ | ||
275 | current->thread.abi = &mips_abi; \ | 299 | current->thread.abi = &mips_abi; \ |
276 | } while (0) | 300 | } while (0) |
277 | 301 | ||
@@ -291,44 +315,44 @@ do { \ | |||
291 | #endif | 315 | #endif |
292 | 316 | ||
293 | #ifdef CONFIG_MIPS32_O32 | 317 | #ifdef CONFIG_MIPS32_O32 |
294 | #define __SET_PERSONALITY32_O32(ex) \ | 318 | #define __SET_PERSONALITY32_O32(ex, state) \ |
295 | do { \ | 319 | do { \ |
296 | set_thread_flag(TIF_32BIT_REGS); \ | 320 | set_thread_flag(TIF_32BIT_REGS); \ |
297 | set_thread_flag(TIF_32BIT_ADDR); \ | 321 | set_thread_flag(TIF_32BIT_ADDR); \ |
298 | \ | 322 | \ |
299 | if (!((ex).e_flags & EF_MIPS_FP64)) \ | 323 | mips_set_personality_fp(state); \ |
300 | set_thread_flag(TIF_32BIT_FPREGS); \ | ||
301 | \ | 324 | \ |
302 | current->thread.abi = &mips_abi_32; \ | 325 | current->thread.abi = &mips_abi_32; \ |
303 | } while (0) | 326 | } while (0) |
304 | #else | 327 | #else |
305 | #define __SET_PERSONALITY32_O32(ex) \ | 328 | #define __SET_PERSONALITY32_O32(ex, state) \ |
306 | do { } while (0) | 329 | do { } while (0) |
307 | #endif | 330 | #endif |
308 | 331 | ||
309 | #ifdef CONFIG_MIPS32_COMPAT | 332 | #ifdef CONFIG_MIPS32_COMPAT |
310 | #define __SET_PERSONALITY32(ex) \ | 333 | #define __SET_PERSONALITY32(ex, state) \ |
311 | do { \ | 334 | do { \ |
312 | if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ | 335 | if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ |
313 | ((ex).e_flags & EF_MIPS_ABI) == 0) \ | 336 | ((ex).e_flags & EF_MIPS_ABI) == 0) \ |
314 | __SET_PERSONALITY32_N32(); \ | 337 | __SET_PERSONALITY32_N32(); \ |
315 | else \ | 338 | else \ |
316 | __SET_PERSONALITY32_O32(ex); \ | 339 | __SET_PERSONALITY32_O32(ex, state); \ |
317 | } while (0) | 340 | } while (0) |
318 | #else | 341 | #else |
319 | #define __SET_PERSONALITY32(ex) do { } while (0) | 342 | #define __SET_PERSONALITY32(ex, state) do { } while (0) |
320 | #endif | 343 | #endif |
321 | 344 | ||
322 | #define SET_PERSONALITY(ex) \ | 345 | #define SET_PERSONALITY2(ex, state) \ |
323 | do { \ | 346 | do { \ |
324 | unsigned int p; \ | 347 | unsigned int p; \ |
325 | \ | 348 | \ |
326 | clear_thread_flag(TIF_32BIT_REGS); \ | 349 | clear_thread_flag(TIF_32BIT_REGS); \ |
327 | clear_thread_flag(TIF_32BIT_FPREGS); \ | 350 | clear_thread_flag(TIF_32BIT_FPREGS); \ |
351 | clear_thread_flag(TIF_HYBRID_FPREGS); \ | ||
328 | clear_thread_flag(TIF_32BIT_ADDR); \ | 352 | clear_thread_flag(TIF_32BIT_ADDR); \ |
329 | \ | 353 | \ |
330 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ | 354 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ |
331 | __SET_PERSONALITY32(ex); \ | 355 | __SET_PERSONALITY32(ex, state); \ |
332 | else \ | 356 | else \ |
333 | current->thread.abi = &mips_abi; \ | 357 | current->thread.abi = &mips_abi; \ |
334 | \ | 358 | \ |
@@ -390,4 +414,24 @@ struct mm_struct; | |||
390 | extern unsigned long arch_randomize_brk(struct mm_struct *mm); | 414 | extern unsigned long arch_randomize_brk(struct mm_struct *mm); |
391 | #define arch_randomize_brk arch_randomize_brk | 415 | #define arch_randomize_brk arch_randomize_brk |
392 | 416 | ||
417 | struct arch_elf_state { | ||
418 | int fp_abi; | ||
419 | int interp_fp_abi; | ||
420 | int overall_abi; | ||
421 | }; | ||
422 | |||
423 | #define INIT_ARCH_ELF_STATE { \ | ||
424 | .fp_abi = -1, \ | ||
425 | .interp_fp_abi = -1, \ | ||
426 | .overall_abi = -1, \ | ||
427 | } | ||
428 | |||
429 | extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, | ||
430 | bool is_interp, struct arch_elf_state *state); | ||
431 | |||
432 | extern int arch_check_elf(void *ehdr, bool has_interpreter, | ||
433 | struct arch_elf_state *state); | ||
434 | |||
435 | extern void mips_set_personality_fp(struct arch_elf_state *state); | ||
436 | |||
393 | #endif /* _ASM_ELF_H */ | 437 | #endif /* _ASM_ELF_H */ |