Commit c3dc5bec authored by Oskar Schirmer's avatar Oskar Schirmer Committed by Linus Torvalds

flat: fix data sections alignment

The flat loader uses an architecture's flat_stack_align() to align the
stack but assumes word-alignment is enough for the data sections.

However, on the Xtensa S6000 we have registers up to 128bit width
which can be used from userspace and therefor need userspace stack and
data-section alignment of at least this size.

This patch drops flat_stack_align() and uses the same alignment that
is required for slab caches, ARCH_SLAB_MINALIGN, or wordsize if it's
not defined by the architecture.

It also fixes m32r which was obviously kaput, aligning an
uninitialized stack entry instead of the stack pointer.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: default avatarOskar Schirmer <os@emlix.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Bryan Wu <cooloney@kernel.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: default avatarPaul Mundt <lethal@linux-sh.org>
Cc: Greg Ungerer <gerg@uclinux.org>
Signed-off-by: default avatarJohannes Weiner <jw@emlix.com>
Acked-by: default avatarMike Frysinger <vapier.adi@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ba944719
...@@ -5,9 +5,6 @@ ...@@ -5,9 +5,6 @@
#ifndef __ARM_FLAT_H__ #ifndef __ARM_FLAT_H__
#define __ARM_FLAT_H__ #define __ARM_FLAT_H__
/* An odd number of words will be pushed after this alignment, so
deliberately misalign the value. */
#define flat_stack_align(sp) sp = (void *)(((unsigned long)(sp) - 4) | 4)
#define flat_argvp_envp_on_stack() 1 #define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) (flags) #define flat_old_ram_flag(flags) (flags)
#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#define flat_stack_align(sp) /* nothing needed */
#define flat_argvp_envp_on_stack() 0 #define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags) #define flat_old_ram_flag(flags) (flags)
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#ifndef __H8300_FLAT_H__ #ifndef __H8300_FLAT_H__
#define __H8300_FLAT_H__ #define __H8300_FLAT_H__
#define flat_stack_align(sp) /* nothing needed */
#define flat_argvp_envp_on_stack() 1 #define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) 1 #define flat_old_ram_flag(flags) 1
#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#ifndef __ASM_M32R_FLAT_H #ifndef __ASM_M32R_FLAT_H
#define __ASM_M32R_FLAT_H #define __ASM_M32R_FLAT_H
#define flat_stack_align(sp) (*sp += (*sp & 3 ? (4 - (*sp & 3)): 0))
#define flat_argvp_envp_on_stack() 0 #define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags) #define flat_old_ram_flag(flags) (flags)
#define flat_set_persistent(relval, p) 0 #define flat_set_persistent(relval, p) 0
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#ifndef __M68KNOMMU_FLAT_H__ #ifndef __M68KNOMMU_FLAT_H__
#define __M68KNOMMU_FLAT_H__ #define __M68KNOMMU_FLAT_H__
#define flat_stack_align(sp) /* nothing needed */
#define flat_argvp_envp_on_stack() 1 #define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) (flags) #define flat_old_ram_flag(flags) (flags)
#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#ifndef __ASM_SH_FLAT_H #ifndef __ASM_SH_FLAT_H
#define __ASM_SH_FLAT_H #define __ASM_SH_FLAT_H
#define flat_stack_align(sp) /* nothing needed */
#define flat_argvp_envp_on_stack() 0 #define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags) #define flat_old_ram_flag(flags) (flags)
#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/page.h>
/****************************************************************************/ /****************************************************************************/
...@@ -54,6 +55,18 @@ ...@@ -54,6 +55,18 @@
#define DBG_FLT(a...) #define DBG_FLT(a...)
#endif #endif
/*
* User data (stack, data section and bss) needs to be aligned
* for the same reasons as SLAB memory is, and to the same amount.
* Avoid duplicating architecture specific code by using the same
* macro as with SLAB allocation:
*/
#ifdef ARCH_SLAB_MINALIGN
#define FLAT_DATA_ALIGN (ARCH_SLAB_MINALIGN)
#else
#define FLAT_DATA_ALIGN (sizeof(void *))
#endif
#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
#define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */ #define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
...@@ -114,20 +127,18 @@ static unsigned long create_flat_tables( ...@@ -114,20 +127,18 @@ static unsigned long create_flat_tables(
int envc = bprm->envc; int envc = bprm->envc;
char uninitialized_var(dummy); char uninitialized_var(dummy);
sp = (unsigned long *) ((-(unsigned long)sizeof(char *))&(unsigned long) p); sp = (unsigned long *)p;
sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0);
sp = (unsigned long *) ((unsigned long)sp & -FLAT_DATA_ALIGN);
argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0);
envp = argv + (argc + 1);
sp -= envc+1;
envp = sp;
sp -= argc+1;
argv = sp;
flat_stack_align(sp);
if (flat_argvp_envp_on_stack()) { if (flat_argvp_envp_on_stack()) {
--sp; put_user((unsigned long) envp, sp); put_user((unsigned long) envp, sp + 2);
--sp; put_user((unsigned long) argv, sp); put_user((unsigned long) argv, sp + 1);
} }
put_user(argc,--sp); put_user(argc, sp);
current->mm->arg_start = (unsigned long) p; current->mm->arg_start = (unsigned long) p;
while (argc-->0) { while (argc-->0) {
put_user((unsigned long) p, argv++); put_user((unsigned long) p, argv++);
...@@ -558,7 +569,9 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -558,7 +569,9 @@ static int load_flat_file(struct linux_binprm * bprm,
ret = realdatastart; ret = realdatastart;
goto err; goto err;
} }
datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); datapos = ALIGN(realdatastart +
MAX_SHARED_LIBS * sizeof(unsigned long),
FLAT_DATA_ALIGN);
DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n", DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",
(int)(data_len + bss_len + stack_len), (int)datapos); (int)(data_len + bss_len + stack_len), (int)datapos);
...@@ -604,9 +617,12 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -604,9 +617,12 @@ static int load_flat_file(struct linux_binprm * bprm,
} }
realdatastart = textpos + ntohl(hdr->data_start); realdatastart = textpos + ntohl(hdr->data_start);
datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); datapos = ALIGN(realdatastart +
reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) + MAX_SHARED_LIBS * sizeof(unsigned long),
MAX_SHARED_LIBS * sizeof(unsigned long)); FLAT_DATA_ALIGN);
reloc = (unsigned long *)
(datapos + (ntohl(hdr->reloc_start) - text_len));
memp = textpos; memp = textpos;
memp_size = len; memp_size = len;
#ifdef CONFIG_BINFMT_ZFLAT #ifdef CONFIG_BINFMT_ZFLAT
...@@ -854,7 +870,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -854,7 +870,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
stack_len = TOP_OF_ARGS - bprm->p; /* the strings */ stack_len = TOP_OF_ARGS - bprm->p; /* the strings */
stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */
stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */
stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */
res = load_flat_file(bprm, &libinfo, 0, &stack_len); res = load_flat_file(bprm, &libinfo, 0, &stack_len);
if (res > (unsigned long)-4096) if (res > (unsigned long)-4096)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment