Skip to content

Commit

Permalink
aout: suppress A.OUT library support if !CONFIG_ARCH_SUPPORTS_AOUT
Browse files Browse the repository at this point in the history
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: David Howells <dhowells@redhat.com>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
dhowells authored and Linus Torvalds committed Feb 8, 2008
1 parent b0b933c commit 7fa3031
Show file tree
Hide file tree
Showing 25 changed files with 423 additions and 257 deletions.
62 changes: 0 additions & 62 deletions arch/alpha/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,68 +317,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
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.
*/
Expand Down
29 changes: 0 additions & 29 deletions arch/arm/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,35 +367,6 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
}
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
* thread function. r1 is the thread argument, r2 is the pointer to
Expand Down
47 changes: 0 additions & 47 deletions arch/m68k/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,53 +315,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *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.
*/
Expand Down
32 changes: 0 additions & 32 deletions arch/sparc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,38 +566,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
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.
*/
Expand Down
2 changes: 0 additions & 2 deletions arch/sparc/kernel/sparc_ksyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,6 @@ EXPORT_SYMBOL(kunmap_atomic);
EXPORT_SYMBOL(svr4_setcontext);
EXPORT_SYMBOL(svr4_getcontext);

EXPORT_SYMBOL(dump_thread);

/* prom symbols */
EXPORT_SYMBOL(idprom);
EXPORT_SYMBOL(prom_root_node);
Expand Down
3 changes: 2 additions & 1 deletion arch/sparc64/kernel/binfmt_aout32.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <asm/uaccess.h>
#include <asm/pgalloc.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_library(struct file*);
Expand Down Expand Up @@ -101,7 +102,7 @@ static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file,
current->flags |= PF_DUMPCORE;
strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm));
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 we wrote the stack, but not the data area. */
Expand Down
11 changes: 0 additions & 11 deletions arch/sparc64/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,17 +725,6 @@ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
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 {
union {
unsigned int pr_regs[32];
Expand Down
1 change: 0 additions & 1 deletion arch/um/kernel/ksyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ EXPORT_SYMBOL(os_accept_connection);
EXPORT_SYMBOL(os_rcv_fd);
EXPORT_SYMBOL(run_helper);
EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(dump_thread);

#ifdef CONFIG_SMP

Expand Down
4 changes: 0 additions & 4 deletions arch/um/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,6 @@ void cpu_idle(void)
default_idle();
}

void dump_thread(struct pt_regs *regs, struct user *u)
{
}

int __cant_sleep(void) {
return in_atomic() || irqs_disabled() || in_interrupt();
/* Is in_interrupt() really needed? */
Expand Down
49 changes: 0 additions & 49 deletions arch/x86/kernel/process_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,55 +539,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
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
static void hard_disable_TSC(void)
{
Expand Down
3 changes: 2 additions & 1 deletion fs/Kconfig.binfmt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ config BINFMT_SHARED_FLAT

config BINFMT_AOUT
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---
A.out (Assembler.OUTput) is a set of formats for libraries and
executables used in the earliest versions of UNIX. Linux used
Expand Down
3 changes: 2 additions & 1 deletion fs/binfmt_aout.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <asm/system.h>
#include <asm/uaccess.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_library(struct file*);
Expand Down Expand Up @@ -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);
#endif
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 we wrote the stack, but not the data area. */
Expand Down
Loading

0 comments on commit 7fa3031

Please sign in to comment.