diff options
Diffstat (limited to 'arch/mips/include/asm/elf.h')
-rw-r--r-- | arch/mips/include/asm/elf.h | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index a66359ef4ece..d4144056e928 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #define EF_MIPS_ABI2 0x00000020 | 36 | #define EF_MIPS_ABI2 0x00000020 |
37 | #define EF_MIPS_OPTIONS_FIRST 0x00000080 | 37 | #define EF_MIPS_OPTIONS_FIRST 0x00000080 |
38 | #define EF_MIPS_32BITMODE 0x00000100 | 38 | #define EF_MIPS_32BITMODE 0x00000100 |
39 | #define EF_MIPS_FP64 0x00000200 | ||
39 | #define EF_MIPS_ABI 0x0000f000 | 40 | #define EF_MIPS_ABI 0x0000f000 |
40 | #define EF_MIPS_ARCH 0xf0000000 | 41 | #define EF_MIPS_ARCH 0xf0000000 |
41 | 42 | ||
@@ -176,6 +177,18 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | |||
176 | #ifdef CONFIG_32BIT | 177 | #ifdef CONFIG_32BIT |
177 | 178 | ||
178 | /* | 179 | /* |
180 | * In order to be sure that we don't attempt to execute an O32 binary which | ||
181 | * requires 64 bit FP (FR=1) on a system which does not support it we refuse | ||
182 | * to execute any binary which has bits specified by the following macro set | ||
183 | * in its ELF header flags. | ||
184 | */ | ||
185 | #ifdef CONFIG_MIPS_O32_FP64_SUPPORT | ||
186 | # define __MIPS_O32_FP64_MUST_BE_ZERO 0 | ||
187 | #else | ||
188 | # define __MIPS_O32_FP64_MUST_BE_ZERO EF_MIPS_FP64 | ||
189 | #endif | ||
190 | |||
191 | /* | ||
179 | * This is used to ensure we don't load something for the wrong architecture. | 192 | * This is used to ensure we don't load something for the wrong architecture. |
180 | */ | 193 | */ |
181 | #define elf_check_arch(hdr) \ | 194 | #define elf_check_arch(hdr) \ |
@@ -192,6 +205,8 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | |||
192 | if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ | 205 | if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ |
193 | ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ | 206 | ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ |
194 | __res = 0; \ | 207 | __res = 0; \ |
208 | if (__h->e_flags & __MIPS_O32_FP64_MUST_BE_ZERO) \ | ||
209 | __res = 0; \ | ||
195 | \ | 210 | \ |
196 | __res; \ | 211 | __res; \ |
197 | }) | 212 | }) |
@@ -249,6 +264,11 @@ extern struct mips_abi mips_abi_n32; | |||
249 | 264 | ||
250 | #define SET_PERSONALITY(ex) \ | 265 | #define SET_PERSONALITY(ex) \ |
251 | do { \ | 266 | 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 | \ | ||
252 | if (personality(current->personality) != PER_LINUX) \ | 272 | if (personality(current->personality) != PER_LINUX) \ |
253 | set_personality(PER_LINUX); \ | 273 | set_personality(PER_LINUX); \ |
254 | \ | 274 | \ |
@@ -271,14 +291,18 @@ do { \ | |||
271 | #endif | 291 | #endif |
272 | 292 | ||
273 | #ifdef CONFIG_MIPS32_O32 | 293 | #ifdef CONFIG_MIPS32_O32 |
274 | #define __SET_PERSONALITY32_O32() \ | 294 | #define __SET_PERSONALITY32_O32(ex) \ |
275 | do { \ | 295 | do { \ |
276 | set_thread_flag(TIF_32BIT_REGS); \ | 296 | set_thread_flag(TIF_32BIT_REGS); \ |
277 | set_thread_flag(TIF_32BIT_ADDR); \ | 297 | set_thread_flag(TIF_32BIT_ADDR); \ |
298 | \ | ||
299 | if (!((ex).e_flags & EF_MIPS_FP64)) \ | ||
300 | set_thread_flag(TIF_32BIT_FPREGS); \ | ||
301 | \ | ||
278 | current->thread.abi = &mips_abi_32; \ | 302 | current->thread.abi = &mips_abi_32; \ |
279 | } while (0) | 303 | } while (0) |
280 | #else | 304 | #else |
281 | #define __SET_PERSONALITY32_O32() \ | 305 | #define __SET_PERSONALITY32_O32(ex) \ |
282 | do { } while (0) | 306 | do { } while (0) |
283 | #endif | 307 | #endif |
284 | 308 | ||
@@ -289,7 +313,7 @@ do { \ | |||
289 | ((ex).e_flags & EF_MIPS_ABI) == 0) \ | 313 | ((ex).e_flags & EF_MIPS_ABI) == 0) \ |
290 | __SET_PERSONALITY32_N32(); \ | 314 | __SET_PERSONALITY32_N32(); \ |
291 | else \ | 315 | else \ |
292 | __SET_PERSONALITY32_O32(); \ | 316 | __SET_PERSONALITY32_O32(ex); \ |
293 | } while (0) | 317 | } while (0) |
294 | #else | 318 | #else |
295 | #define __SET_PERSONALITY32(ex) do { } while (0) | 319 | #define __SET_PERSONALITY32(ex) do { } while (0) |
@@ -300,6 +324,7 @@ do { \ | |||
300 | unsigned int p; \ | 324 | unsigned int p; \ |
301 | \ | 325 | \ |
302 | clear_thread_flag(TIF_32BIT_REGS); \ | 326 | clear_thread_flag(TIF_32BIT_REGS); \ |
327 | clear_thread_flag(TIF_32BIT_FPREGS); \ | ||
303 | clear_thread_flag(TIF_32BIT_ADDR); \ | 328 | clear_thread_flag(TIF_32BIT_ADDR); \ |
304 | \ | 329 | \ |
305 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ | 330 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ |