Commit 7fa30315 authored by David Howells's avatar David Howells Committed by Linus Torvalds

aout: suppress A.OUT library support if !CONFIG_ARCH_SUPPORTS_AOUT

Suppress A.OUT library support if CONFIG_ARCH_SUPPORTS_AOUT is not set.

Not all architectures support the A.OUT binfmt, so the ELF binfmt should not
be permitted to go looking for A.OUT libraries to load in such a case.  Not
only that, but under such conditions A.OUT core dumps are not produced either.

To make this work, this patch also does the following:

 (1) Makes the existence of the contents of linux/a.out.h contingent on
     CONFIG_ARCH_SUPPORTS_AOUT.

 (2) Renames dump_thread() to aout_dump_thread() as it's only called by A.OUT
     core dumping code.

 (3) Moves aout_dump_thread() into asm/a.out-core.h and makes it inline.  This
     is then included only where needed.  This means that this bit of arch
     code will be stored in the appropriate A.OUT binfmt module rather than
     the core kernel.

 (4) Drops A.OUT support for Blackfin (according to Mike Frysinger it's not
     needed) and FRV.

This patch depends on the previous patch to move STACK_TOP[_MAX] out of
asm/a.out.h and into asm/processor.h as they're required whether or not A.OUT
format is available.

[jdike@addtoit.com: uml: re-remove accidentally restored code]
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: default avatarJeff Dike <jdike@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b0b933c0
...@@ -317,68 +317,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -317,68 +317,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
return 0; return 0;
} }
/*
* Fill in the user structure for an ECOFF core dump.
*/
void
dump_thread(struct pt_regs * pt, struct user * dump)
{
/* switch stack follows right below pt_regs: */
struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
dump->magic = CMAGIC;
dump->start_code = current->mm->start_code;
dump->start_data = current->mm->start_data;
dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
dump->u_tsize = ((current->mm->end_code - dump->start_code)
>> PAGE_SHIFT);
dump->u_dsize = ((current->mm->brk + PAGE_SIZE-1 - dump->start_data)
>> PAGE_SHIFT);
dump->u_ssize = (current->mm->start_stack - dump->start_stack
+ PAGE_SIZE-1) >> PAGE_SHIFT;
/*
* We store the registers in an order/format that is
* compatible with DEC Unix/OSF/1 as this makes life easier
* for gdb.
*/
dump->regs[EF_V0] = pt->r0;
dump->regs[EF_T0] = pt->r1;
dump->regs[EF_T1] = pt->r2;
dump->regs[EF_T2] = pt->r3;
dump->regs[EF_T3] = pt->r4;
dump->regs[EF_T4] = pt->r5;
dump->regs[EF_T5] = pt->r6;
dump->regs[EF_T6] = pt->r7;
dump->regs[EF_T7] = pt->r8;
dump->regs[EF_S0] = sw->r9;
dump->regs[EF_S1] = sw->r10;
dump->regs[EF_S2] = sw->r11;
dump->regs[EF_S3] = sw->r12;
dump->regs[EF_S4] = sw->r13;
dump->regs[EF_S5] = sw->r14;
dump->regs[EF_S6] = sw->r15;
dump->regs[EF_A3] = pt->r19;
dump->regs[EF_A4] = pt->r20;
dump->regs[EF_A5] = pt->r21;
dump->regs[EF_T8] = pt->r22;
dump->regs[EF_T9] = pt->r23;
dump->regs[EF_T10] = pt->r24;
dump->regs[EF_T11] = pt->r25;
dump->regs[EF_RA] = pt->r26;
dump->regs[EF_T12] = pt->r27;
dump->regs[EF_AT] = pt->r28;
dump->regs[EF_SP] = rdusp();
dump->regs[EF_PS] = pt->ps;
dump->regs[EF_PC] = pt->pc;
dump->regs[EF_GP] = pt->gp;
dump->regs[EF_A0] = pt->r16;
dump->regs[EF_A1] = pt->r17;
dump->regs[EF_A2] = pt->r18;
memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
}
EXPORT_SYMBOL(dump_thread);
/* /*
* Fill in the user structure for a ELF core dump. * Fill in the user structure for a ELF core dump.
*/ */
......
...@@ -367,35 +367,6 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp) ...@@ -367,35 +367,6 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
} }
EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(dump_fpu);
/*
* fill in the user structure for a core dump..
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
struct task_struct *tsk = current;
dump->magic = CMAGIC;
dump->start_code = tsk->mm->start_code;
dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
dump->u_ssize = 0;
dump->u_debugreg[0] = tsk->thread.debug.bp[0].address;
dump->u_debugreg[1] = tsk->thread.debug.bp[1].address;
dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn.arm;
dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn.arm;
dump->u_debugreg[4] = tsk->thread.debug.nsaved;
if (dump->start_stack < 0x04000000)
dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
dump->regs = *regs;
dump->u_fpvalid = dump_fpu (regs, &dump->u_fp);
}
EXPORT_SYMBOL(dump_thread);
/* /*
* Shuffle the argument into the correct register before calling the * Shuffle the argument into the correct register before calling the
* thread function. r1 is the thread argument, r2 is the pointer to * thread function. r1 is the thread argument, r2 is the pointer to
......
...@@ -315,53 +315,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) ...@@ -315,53 +315,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
} }
EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(dump_fpu);
/*
* fill in the user structure for a core dump..
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
struct switch_stack *sw;
/* changed the size calculations - should hopefully work better. lbt */
dump->magic = CMAGIC;
dump->start_code = 0;
dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
dump->u_dsize = ((unsigned long) (current->mm->brk +
(PAGE_SIZE-1))) >> PAGE_SHIFT;
dump->u_dsize -= dump->u_tsize;
dump->u_ssize = 0;
if (dump->start_stack < TASK_SIZE)
dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
dump->u_ar0 = offsetof(struct user, regs);
sw = ((struct switch_stack *)regs) - 1;
dump->regs.d1 = regs->d1;
dump->regs.d2 = regs->d2;
dump->regs.d3 = regs->d3;
dump->regs.d4 = regs->d4;
dump->regs.d5 = regs->d5;
dump->regs.d6 = sw->d6;
dump->regs.d7 = sw->d7;
dump->regs.a0 = regs->a0;
dump->regs.a1 = regs->a1;
dump->regs.a2 = regs->a2;
dump->regs.a3 = sw->a3;
dump->regs.a4 = sw->a4;
dump->regs.a5 = sw->a5;
dump->regs.a6 = sw->a6;
dump->regs.d0 = regs->d0;
dump->regs.orig_d0 = regs->orig_d0;
dump->regs.stkadj = regs->stkadj;
dump->regs.sr = regs->sr;
dump->regs.pc = regs->pc;
dump->regs.fmtvec = (regs->format << 12) | regs->vector;
/* dump floating point stuff */
dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp);
}
EXPORT_SYMBOL(dump_thread);
/* /*
* sys_execve() executes a new program. * sys_execve() executes a new program.
*/ */
......
...@@ -566,38 +566,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -566,38 +566,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
return 0; return 0;
} }
/*
* fill in the user structure for a core dump..
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
unsigned long first_stack_page;
dump->magic = SUNOS_CORE_MAGIC;
dump->len = sizeof(struct user);
dump->regs.psr = regs->psr;
dump->regs.pc = regs->pc;
dump->regs.npc = regs->npc;
dump->regs.y = regs->y;
/* fuck me plenty */
memcpy(&dump->regs.regs[0], &regs->u_regs[1], (sizeof(unsigned long) * 15));
dump->uexec = current->thread.core_exec;
dump->u_tsize = (((unsigned long) current->mm->end_code) -
((unsigned long) current->mm->start_code)) & ~(PAGE_SIZE - 1);
dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1)));
dump->u_dsize -= dump->u_tsize;
dump->u_dsize &= ~(PAGE_SIZE - 1);
first_stack_page = (regs->u_regs[UREG_FP] & ~(PAGE_SIZE - 1));
dump->u_ssize = (TASK_SIZE - first_stack_page) & ~(PAGE_SIZE - 1);
memcpy(&dump->fpu.fpstatus.fregs.regs[0], &current->thread.float_regs[0], (sizeof(unsigned long) * 32));
dump->fpu.fpstatus.fsr = current->thread.fsr;
dump->fpu.fpstatus.flags = dump->fpu.fpstatus.extra = 0;
dump->fpu.fpstatus.fpq_count = current->thread.fpqdepth;
memcpy(&dump->fpu.fpstatus.fpq[0], &current->thread.fpqueue[0],
((sizeof(unsigned long) * 2) * 16));
dump->sigcode = 0;
}
/* /*
* fill in the fpu structure for a core dump. * fill in the fpu structure for a core dump.
*/ */
......
...@@ -214,8 +214,6 @@ EXPORT_SYMBOL(kunmap_atomic); ...@@ -214,8 +214,6 @@ EXPORT_SYMBOL(kunmap_atomic);
EXPORT_SYMBOL(svr4_setcontext); EXPORT_SYMBOL(svr4_setcontext);
EXPORT_SYMBOL(svr4_getcontext); EXPORT_SYMBOL(svr4_getcontext);
EXPORT_SYMBOL(dump_thread);
/* prom symbols */ /* prom symbols */
EXPORT_SYMBOL(idprom); EXPORT_SYMBOL(idprom);
EXPORT_SYMBOL(prom_root_node); EXPORT_SYMBOL(prom_root_node);
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/a.out-core.h>
static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs); static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs);
static int load_aout32_library(struct file*); static int load_aout32_library(struct file*);
...@@ -101,7 +102,7 @@ static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, ...@@ -101,7 +102,7 @@ static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file,
current->flags |= PF_DUMPCORE; current->flags |= PF_DUMPCORE;
strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm));
dump.signal = signr; dump.signal = signr;
dump_thread(regs, &dump); aout_dump_thread(regs, &dump);
/* If the size of the dump file exceeds the rlimit, then see what would happen /* If the size of the dump file exceeds the rlimit, then see what would happen
if we wrote the stack, but not the data area. */ if we wrote the stack, but not the data area. */
......
...@@ -725,17 +725,6 @@ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) ...@@ -725,17 +725,6 @@ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
return retval; return retval;
} }
/*
* fill in the user structure for a core dump..
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
/* Only should be used for SunOS and ancient a.out
* SparcLinux binaries... Not worth implementing.
*/
memset(dump, 0, sizeof(struct user));
}
typedef struct { typedef struct {
union { union {
unsigned int pr_regs[32]; unsigned int pr_regs[32];
......
...@@ -60,7 +60,6 @@ EXPORT_SYMBOL(os_accept_connection); ...@@ -60,7 +60,6 @@ EXPORT_SYMBOL(os_accept_connection);
EXPORT_SYMBOL(os_rcv_fd); EXPORT_SYMBOL(os_rcv_fd);
EXPORT_SYMBOL(run_helper); EXPORT_SYMBOL(run_helper);
EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(dump_thread);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
......
...@@ -258,10 +258,6 @@ void cpu_idle(void) ...@@ -258,10 +258,6 @@ void cpu_idle(void)
default_idle(); default_idle();
} }
void dump_thread(struct pt_regs *regs, struct user *u)
{
}
int __cant_sleep(void) { int __cant_sleep(void) {
return in_atomic() || irqs_disabled() || in_interrupt(); return in_atomic() || irqs_disabled() || in_interrupt();
/* Is in_interrupt() really needed? */ /* Is in_interrupt() really needed? */
......
...@@ -539,55 +539,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -539,55 +539,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
return err; return err;
} }
/*
* fill in the user structure for a core dump..
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
u16 gs;
/* changed the size calculations - should hopefully work better. lbt */
dump->magic = CMAGIC;
dump->start_code = 0;
dump->start_stack = regs->sp & ~(PAGE_SIZE - 1);
dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
dump->u_dsize -= dump->u_tsize;
dump->u_ssize = 0;
dump->u_debugreg[0] = current->thread.debugreg0;
dump->u_debugreg[1] = current->thread.debugreg1;
dump->u_debugreg[2] = current->thread.debugreg2;
dump->u_debugreg[3] = current->thread.debugreg3;
dump->u_debugreg[4] = 0;
dump->u_debugreg[5] = 0;
dump->u_debugreg[6] = current->thread.debugreg6;
dump->u_debugreg[7] = current->thread.debugreg7;
if (dump->start_stack < TASK_SIZE)
dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
dump->regs.bx = regs->bx;
dump->regs.cx = regs->cx;
dump->regs.dx = regs->dx;
dump->regs.si = regs->si;
dump->regs.di = regs->di;
dump->regs.bp = regs->bp;
dump->regs.ax = regs->ax;
dump->regs.ds = (u16)regs->ds;
dump->regs.es = (u16)regs->es;
dump->regs.fs = (u16)regs->fs;
savesegment(gs,gs);
dump->regs.orig_ax = regs->orig_ax;
dump->regs.ip = regs->ip;
dump->regs.cs = (u16)regs->cs;
dump->regs.flags = regs->flags;
dump->regs.sp = regs->sp;
dump->regs.ss = (u16)regs->ss;
dump->u_fpvalid = dump_fpu (regs, &dump->i387);
}
EXPORT_SYMBOL(dump_thread);
#ifdef CONFIG_SECCOMP #ifdef CONFIG_SECCOMP
static void hard_disable_TSC(void) static void hard_disable_TSC(void)
{ {
......
...@@ -61,7 +61,8 @@ config BINFMT_SHARED_FLAT ...@@ -61,7 +61,8 @@ config BINFMT_SHARED_FLAT
config BINFMT_AOUT config BINFMT_AOUT
tristate "Kernel support for a.out and ECOFF binaries" tristate "Kernel support for a.out and ECOFF binaries"
depends on X86_32 || ALPHA || ARM || M68K || SPARC32 depends on ARCH_SUPPORTS_AOUT && \
(X86_32 || ALPHA || ARM || M68K || SPARC32)
---help--- ---help---
A.out (Assembler.OUTput) is a set of formats for libraries and A.out (Assembler.OUTput) is a set of formats for libraries and
executables used in the earliest versions of UNIX. Linux used executables used in the earliest versions of UNIX. Linux used
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/a.out-core.h>
static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
static int load_aout_library(struct file*); static int load_aout_library(struct file*);
...@@ -118,7 +119,7 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, u ...@@ -118,7 +119,7 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, u
dump.u_ar0 = offsetof(struct user, regs); dump.u_ar0 = offsetof(struct user, regs);
#endif #endif
dump.signal = signr; dump.signal = signr;
dump_thread(regs, &dump); aout_dump_thread(regs, &dump);
/* If the size of the dump file exceeds the rlimit, then see what would happen /* If the size of the dump file exceeds the rlimit, then see what would happen
if we wrote the stack, but not the data area. */ if we wrote the stack, but not the data area. */
......
...@@ -513,6 +513,7 @@ out: ...@@ -513,6 +513,7 @@ out:
return error; return error;
} }
#ifdef CONFIG_ARCH_SUPPORTS_AOUT
static unsigned long load_aout_interp(struct exec *interp_ex, static unsigned long load_aout_interp(struct exec *interp_ex,
struct file *interpreter) struct file *interpreter)
{ {
...@@ -558,6 +559,14 @@ static unsigned long load_aout_interp(struct exec *interp_ex, ...@@ -558,6 +559,14 @@ static unsigned long load_aout_interp(struct exec *interp_ex,
out: out:
return elf_entry; return elf_entry;
} }
#else
/* dummy extern - the function should never be called if !CONFIG_AOUT_BINFMT */
static inline unsigned long load_aout_interp(struct exec *interp_ex,
struct file *interpreter)
{
return -ELIBACC;
}
#endif
/* /*
* These are the functions used to load ELF style executables and shared * These are the functions used to load ELF style executables and shared
...@@ -565,9 +574,15 @@ out: ...@@ -565,9 +574,15 @@ out:
*/ */
#define INTERPRETER_NONE 0 #define INTERPRETER_NONE 0
#define INTERPRETER_AOUT 1
#define INTERPRETER_ELF 2 #define INTERPRETER_ELF 2
#ifdef CONFIG_ARCH_SUPPORTS_AOUT
#define INTERPRETER_AOUT 1
#define IS_AOUT_INTERP(x) ((x) == INTERPRETER_AOUT)
#else
#define IS_AOUT_INTERP(x) (0)
#endif
#ifndef STACK_RND_MASK #ifndef STACK_RND_MASK
#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */ #define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
#endif #endif
...@@ -775,6 +790,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -775,6 +790,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
/* Some simple consistency checks for the interpreter */ /* Some simple consistency checks for the interpreter */
if (elf_interpreter) { if (elf_interpreter) {
static int warn; static int warn;
#ifdef CONFIG_ARCH_SUPPORTS_AOUT
interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT; interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
/* Now figure out which format our binary is */ /* Now figure out which format our binary is */
...@@ -782,11 +798,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -782,11 +798,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
(N_MAGIC(loc->interp_ex) != ZMAGIC) && (N_MAGIC(loc->interp_ex) != ZMAGIC) &&
(N_MAGIC(loc->interp_ex) != QMAGIC)) (N_MAGIC(loc->interp_ex) != QMAGIC))
interpreter_type = INTERPRETER_ELF; interpreter_type = INTERPRETER_ELF;
#else
interpreter_type = INTERPRETER_ELF;
#endif
if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0) if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
interpreter_type &= ~INTERPRETER_ELF; interpreter_type &= ~INTERPRETER_ELF;
if (interpreter_type == INTERPRETER_AOUT && warn < 10) { if (IS_AOUT_INTERP(interpreter_type) && warn < 10) {
printk(KERN_WARNING "a.out ELF interpreter %s is " printk(KERN_WARNING "a.out ELF interpreter %s is "
"deprecated and will not be supported " "deprecated and will not be supported "
"after Linux 2.6.25\n", elf_interpreter); "after Linux 2.6.25\n", elf_interpreter);
...@@ -815,7 +833,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -815,7 +833,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
/* OK, we are done with that, now set up the arg stuff, /* OK, we are done with that, now set up the arg stuff,
and then start this sucker up */ and then start this sucker up */
if ((!bprm->sh_bang) && (interpreter_type == INTERPRETER_AOUT)) { if (IS_AOUT_INTERP(interpreter_type) && !bprm->sh_bang) {
char *passed_p = passed_fileno; char *passed_p = passed_fileno;
sprintf(passed_fileno, "%d", elf_exec_fileno); sprintf(passed_fileno, "%d", elf_exec_fileno);
...@@ -1004,7 +1022,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -1004,7 +1022,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
} }
if (elf_interpreter) { if (elf_interpreter) {
if (interpreter_type == INTERPRETER_AOUT) { if (IS_AOUT_INTERP(interpreter_type)) {
elf_entry = load_aout_interp(&loc->interp_ex, elf_entry = load_aout_interp(&loc->interp_ex,
interpreter); interpreter);
} else { } else {
...@@ -1045,7 +1063,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -1045,7 +1063,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
kfree(elf_phdata); kfree(elf_phdata);
if (interpreter_type != INTERPRETER_AOUT) if (!IS_AOUT_INTERP(interpreter_type))
sys_close(elf_exec_fileno); sys_close(elf_exec_fileno);
set_binfmt(&elf_format); set_binfmt(&elf_format);
...@@ -1061,14 +1079,14 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -1061,14 +1079,14 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
compute_creds(bprm); compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC; current->flags &= ~PF_FORKNOEXEC;
retval = create_elf_tables(bprm, &loc->elf_ex, retval = create_elf_tables(bprm, &loc->elf_ex,
(interpreter_type == INTERPRETER_AOUT), IS_AOUT_INTERP(interpreter_type),
load_addr, interp_load_addr); load_addr, interp_load_addr);
if (retval < 0) { if (retval < 0) {
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
goto out; goto out;
} }
/* N.B. passed_fileno might not be initialized? */ /* N.B. passed_fileno might not be initialized? */
if (interpreter_type == INTERPRETER_AOUT) if (IS_AOUT_INTERP(interpreter_type))
current->mm->arg_start += strlen(passed_fileno) + 1; current->mm->arg_start += strlen(passed_fileno) + 1;
current->mm->end_code = end_code; current->mm->end_code = end_code;
current->mm->start_code = start_code; current->mm->start_code = start_code;
......
...@@ -1166,7 +1166,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) ...@@ -1166,7 +1166,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
{ {
int try,retval; int try,retval;
struct linux_binfmt *fmt; struct linux_binfmt *fmt;
#ifdef __alpha__ #if defined(__alpha__) && defined(CONFIG_ARCH_SUPPORTS_AOUT)
/* handle /sbin/loader.. */ /* handle /sbin/loader.. */
{ {
struct exec * eh = (struct exec *) bprm->buf; struct exec * eh = (struct exec *) bprm->buf;
......
/* a.out coredump register dumper
*
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#ifndef _ASM_A_OUT_CORE_H
#define _ASM_A_OUT_CORE_H
#ifdef __KERNEL__
#include <linux/user.h>
/*
* Fill in the user structure for an ECOFF core dump.
*/
static inline void aout_dump_thread(struct pt_regs *pt, struct user *dump)
{
/* switch stack follows right below pt_regs: */
struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
dump->magic = CMAGIC;
dump->start_code = current->mm->start_code;
dump->start_data = current->mm->start_data;
dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
dump->u_tsize = ((current->mm->end_code - dump->start_code)
>> PAGE_SHIFT);
dump->u_dsize = ((current->mm->brk + PAGE_SIZE-1 - dump->start_data)
>> PAGE_SHIFT);
dump->u_ssize = (current->mm->start_stack - dump->start_stack
+ PAGE_SIZE-1) >> PAGE_SHIFT;
/*
* We store the registers in an order/format that is
* compatible with DEC Unix/OSF/1 as this makes life easier
* for gdb.
*/
dump->regs[EF_V0] = pt->r0;
dump->regs[EF_T0] = pt->r1;
dump->regs[EF_T1] = pt->r2;
dump->regs[EF_T2] = pt->r3;
dump->regs[EF_T3] = pt->r4;
dump->regs[EF_T4] = pt->r5;
dump->regs[EF_T5] = pt->r6;
dump->regs[EF_T6] = pt->r7;
dump->regs[EF_T7] = pt->r8;
dump->regs[EF_S0] = sw->r9;
dump->regs[EF_S1] = sw->r10;
dump->regs[EF_S2] = sw->r11;
dump->regs[EF_S3] = sw->r12;
dump->regs[EF_S4] = sw->r13;
dump->regs[EF_S5] = sw->r14;
dump->regs[EF_S6] = sw->r15;
dump->regs[EF_A3] = pt->r19;
dump->regs[EF_A4] = pt->r20;
dump->regs[EF_A5] = pt->r21;
dump->regs[EF_T8] = pt->r22;
dump->regs[EF_T9] = pt->r23;
dump->regs[EF_T10] = pt->r24;
dump->regs[EF_T11] = pt->r25;
dump->regs[EF_RA] = pt->r26;
dump->regs[EF_T12] = pt->r27;
dump->regs[EF_AT] = pt->r28;
dump->regs[EF_SP] = rdusp();
dump->regs[EF_PS] = pt->ps;
dump->regs[EF_PC] = pt->pc;
dump->regs[EF_GP] = pt->gp;
dump->regs[EF_A0] = pt->r16;
dump->regs[EF_A1] = pt->r17;
dump->regs[EF_A2] = pt->r18;
memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
}
#endif /* __KERNEL__ */
#endif /* _ASM_A_OUT_CORE_H */
/* a.out coredump register dumper
*
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#ifndef _ASM_A_OUT_CORE_H
#define _ASM_A_OUT_CORE_H
#ifdef __KERNEL__
#include <linux/user.h>
#include <linux/elfcore.h>
/*
* fill in the user structure for an a.out core dump
*/
static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
{
struct task_struct *tsk = current;
dump->magic = CMAGIC;
dump->start_code = tsk->mm->start_code;
dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
dump->u_ssize = 0;
dump->u_debugreg[0] = tsk->thread.debug.bp[0].address;
dump->u_debugreg[1] = tsk->thread.debug.bp[1].address;
dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn.arm;
dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn.arm;
dump->u_debugreg[4] = tsk->thread.debug.nsaved;
if (dump->start_stack < 0x04000000)
dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
dump->