Commit ea3bc13f authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Linus Torvalds

[PATCH] More support for upward growing stacks

 - remove elf_caddr_t. It's positively dangerous to #define this since
   elf_caddr_t foo, bar; creates variables of different types (foo is
   char *, bar is char).
 - rewrite large chunks of create_elf_tables(), it needed cleaning anyway.
 - add upwards-growing stack support to create_elf_tables.
 - redefine the ARCH_DLINFO stuff on powerpc -- it's tested, works.
 - add upwards-growing-stack support to exec.c too.
parent b4093e0c
......@@ -54,7 +54,6 @@ static struct linux_binfmt irix_format = {
#ifndef elf_addr_t
#define elf_addr_t unsigned long
#define elf_caddr_t char *
#endif
#ifdef DEBUG_ELF
......@@ -155,8 +154,8 @@ unsigned long * create_irix_tables(char * p, int argc, int envc,
unsigned int interp_load_addr,
struct pt_regs *regs, struct elf_phdr *ephdr)
{
elf_caddr_t *argv;
elf_caddr_t *envp;
elf_addr_t *argv;
elf_addr_t *envp;
elf_addr_t *sp, *csp;
#ifdef DEBUG_ELF
......@@ -202,20 +201,20 @@ unsigned long * create_irix_tables(char * p, int argc, int envc,
#undef NEW_AUX_ENT
sp -= envc+1;
envp = (elf_caddr_t *) sp;
envp = sp;
sp -= argc+1;
argv = (elf_caddr_t *) sp;
argv = sp;
__put_user((elf_addr_t)argc,--sp);
current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
__put_user((elf_caddr_t)(unsigned long)p,argv++);
__put_user((unsigned long)p,argv++);
p += strlen_user(p);
}
__put_user(NULL, argv);
current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
__put_user((elf_caddr_t)(unsigned long)p,envp++);
__put_user((unsigned long)p,envp++);
p += strlen_user(p);
}
__put_user(NULL, envp);
......
......@@ -80,7 +80,6 @@ struct elf_prpsinfo32
};
#define elf_addr_t u32
#define elf_caddr_t u32
#define init_elf_binfmt init_elf32_binfmt
#undef CONFIG_BINFMT_ELF
#ifdef CONFIG_BINFMT_ELF32
......
......@@ -166,7 +166,6 @@ struct elf_prpsinfo32
#define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
#define elf_addr_t u32
#define elf_caddr_t u32
/*
#define init_elf_binfmt init_elf32_binfmt
*/
......
......@@ -147,7 +147,6 @@ jiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value)
}
#define elf_addr_t u32
#define elf_caddr_t u32
#undef start_thread
#define start_thread start_thread32
#define init_elf_binfmt init_elf32_binfmt
......
......@@ -186,7 +186,6 @@ MODULE_AUTHOR("Eric Youngdale, Andi Kleen");
#undef MODULE_AUTHOR
#define elf_addr_t __u32
#define elf_caddr_t __u32
static void elf32_init(struct pt_regs *);
......
......@@ -39,19 +39,15 @@
#include <asm/param.h>
#include <asm/pgalloc.h>
#define DLINFO_ITEMS 13
#include <linux/elf.h>
static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
static int load_elf_library(struct file*);
static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
extern void dump_thread(struct pt_regs *, struct user *);
#ifndef elf_addr_t
#define elf_addr_t unsigned long
#define elf_caddr_t char *
#endif
/*
......@@ -88,9 +84,9 @@ static void set_brk(unsigned long start, unsigned long end)
{
start = ELF_PAGEALIGN(start);
end = ELF_PAGEALIGN(end);
if (end <= start)
return;
do_brk(start, end - start);
if (end > start)
do_brk(start, end - start);
current->mm->start_brk = current->mm->brk = end;
}
......@@ -111,134 +107,149 @@ static void padzero(unsigned long elf_bss)
}
}
static elf_addr_t *
create_elf_tables(char *p, int argc, int envc,
struct elfhdr * exec,
unsigned long load_addr,
unsigned long load_bias,
unsigned long interp_load_addr, int ibcs)
/* Let's use some macros to make this stack manipulation a litle clearer */
#ifdef ARCH_STACK_GROWSUP
#define STACK_ADD(sp, items) ((elf_addr_t *)(sp) + (items))
#define STACK_ROUND(sp, items) \
((15 + (unsigned long) ((sp) + (items))) &~ 15UL)
#define STACK_ALLOC(sp, len) ({ elf_addr_t old_sp = sp; sp += len; old_sp; })
#else
#define STACK_ADD(sp, items) ((elf_addr_t *)(sp) - (items))
#define STACK_ROUND(sp, items) \
(((unsigned long) (sp - items)) &~ 15UL)
#define STACK_ALLOC(sp, len) sp -= len
#endif
static void
create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
int interp_aout, unsigned long load_addr,
unsigned long interp_load_addr)
{
elf_caddr_t *argv;
elf_caddr_t *envp;
elf_addr_t *sp, *csp;
char *k_platform, *u_platform;
long hwcap;
size_t platform_len = 0;
size_t len;
unsigned long p = bprm->p;
int argc = bprm->argc;
int envc = bprm->envc;
elf_addr_t *argv, *envp;
elf_addr_t *sp, u_platform;
const char *k_platform = ELF_PLATFORM;
int items;
elf_addr_t elf_info[30];
int ei_index = 0;
/*
* Get hold of platform and hardware capabilities masks for
* the machine we are running on. In some cases (Sparc),
* this info is impossible to get, in others (i386) it is
* If this architecture has a platform capability string, copy it
* to userspace. In some cases (Sparc), this info is impossible
* for userspace to get any other way, in others (i386) it is
* merely difficult.
*/
hwcap = ELF_HWCAP;
k_platform = ELF_PLATFORM;
if (k_platform) {
platform_len = strlen(k_platform) + 1;
u_platform = p - platform_len;
__copy_to_user(u_platform, k_platform, platform_len);
} else
u_platform = p;
size_t len = strlen(k_platform) + 1;
#if defined(__i386__) && defined(CONFIG_SMP)
/*
* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
* by the processes running on the same package. One thing we can do
* is to shuffle the initial stack for them.
*
* The conditionals here are unneeded, but kept in to make the
* code behaviour the same as pre change unless we have hyperthreaded
* processors. This should be cleaned up before 2.6
*/
/*
* In some cases (e.g. Hyper-Threading), we want to avoid L1
* evictions by the processes running on the same package. One
* thing we can do is to shuffle the initial stack for them.
*
* The conditionals here are unneeded, but kept in to make the
* code behaviour the same as pre change unless we have
* hyperthreaded processors. This should be cleaned up
* before 2.6
*/
if(smp_num_siblings > 1)
u_platform = u_platform - ((current->pid % 64) << 7);
#endif
/*
* Force 16 byte _final_ alignment here for generality.
*/
sp = (elf_addr_t *)(~15UL & (unsigned long)(u_platform));
csp = sp;
csp -= (1+DLINFO_ITEMS)*2 + (k_platform ? 2 : 0);
#ifdef DLINFO_ARCH_ITEMS
csp -= DLINFO_ARCH_ITEMS*2;
if (smp_num_siblings > 1)
STACK_ALLOC(p, ((current->pid % 64) << 7));
#endif
csp -= envc+1;
csp -= argc+1;
csp -= (!ibcs ? 3 : 1); /* argc itself */
if ((unsigned long)csp & 15UL)
sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
u_platform = STACK_ALLOC(p, len);
__copy_to_user((void *)u_platform, k_platform, len);
}
/*
* Put the ELF interpreter info on the stack
*/
#define NEW_AUX_ENT(nr, id, val) \
__put_user ((id), sp+(nr*2)); \
__put_user ((val), sp+(nr*2+1)); \
/* Create the ELF interpreter info */
#define NEW_AUX_ENT(id, val) \
do { elf_info[ei_index++] = id; elf_info[ei_index++] = val; } while (0)
sp -= 2;
NEW_AUX_ENT(0, AT_NULL, 0);
if (k_platform) {
sp -= 2;
NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform);
}
sp -= DLINFO_ITEMS*2;
NEW_AUX_ENT( 0, AT_HWCAP, hwcap);
NEW_AUX_ENT( 1, AT_PAGESZ, ELF_EXEC_PAGESIZE);
NEW_AUX_ENT( 2, AT_CLKTCK, CLOCKS_PER_SEC);
NEW_AUX_ENT( 3, AT_PHDR, load_addr + exec->e_phoff);
NEW_AUX_ENT( 4, AT_PHENT, sizeof (struct elf_phdr));
NEW_AUX_ENT( 5, AT_PHNUM, exec->e_phnum);
NEW_AUX_ENT( 6, AT_BASE, interp_load_addr);
NEW_AUX_ENT( 7, AT_FLAGS, 0);
NEW_AUX_ENT( 8, AT_ENTRY, load_bias + exec->e_entry);
NEW_AUX_ENT( 9, AT_UID, (elf_addr_t) current->uid);
NEW_AUX_ENT(10, AT_EUID, (elf_addr_t) current->euid);
NEW_AUX_ENT(11, AT_GID, (elf_addr_t) current->gid);
NEW_AUX_ENT(12, AT_EGID, (elf_addr_t) current->egid);
#ifdef ARCH_DLINFO
/*
* ARCH_DLINFO must come last so platform specific code can enforce
* special alignment requirements on the AUXV if necessary (eg. PPC).
* ARCH_DLINFO must come first so PPC can do its special alignment of
* AUXV.
*/
ARCH_DLINFO;
#endif
NEW_AUX_ENT(AT_HWCAP, ELF_HWCAP);
NEW_AUX_ENT(AT_PAGESZ, ELF_EXEC_PAGESIZE);
NEW_AUX_ENT(AT_CLKTCK, CLOCKS_PER_SEC);
NEW_AUX_ENT(AT_PHDR, load_addr + exec->e_phoff);
NEW_AUX_ENT(AT_PHENT, sizeof (struct elf_phdr));
NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
NEW_AUX_ENT(AT_BASE, interp_load_addr);
NEW_AUX_ENT(AT_FLAGS, 0);
NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
NEW_AUX_ENT(AT_UID, (elf_addr_t) current->uid);
NEW_AUX_ENT(AT_EUID, (elf_addr_t) current->euid);
NEW_AUX_ENT(AT_GID, (elf_addr_t) current->gid);
NEW_AUX_ENT(AT_EGID, (elf_addr_t) current->egid);
if (k_platform) {
NEW_AUX_ENT(AT_PLATFORM, u_platform);
}
NEW_AUX_ENT(AT_NULL, 0);
#undef NEW_AUX_ENT
sp -= envc+1;
envp = (elf_caddr_t *) sp;
sp -= argc+1;
argv = (elf_caddr_t *) sp;
if (!ibcs) {
__put_user((elf_addr_t)(unsigned long) envp,--sp);
__put_user((elf_addr_t)(unsigned long) argv,--sp);
sp = STACK_ADD(p, ei_index);
items = (argc + 1) + (envc + 1);
if (interp_aout) {
items += 3; /* a.out interpreters require argv & envp too */
} else {
items += 1; /* ELF interpreters only put argc on the stack */
}
bprm->p = STACK_ROUND(sp, items);
/* Point sp at the lowest address on the stack */
#ifdef ARCH_STACK_GROWSUP
sp = (elf_addr_t *)bprm->p - items - ei_index;
bprm->exec = (unsigned long) sp; /* XXX: PARISC HACK */
#else
sp = (elf_addr_t *)bprm->p;
#endif
__put_user((elf_addr_t)argc,--sp);
current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
__put_user((elf_caddr_t)(unsigned long)p,argv++);
len = strnlen_user(p, PAGE_SIZE*MAX_ARG_PAGES);
/* Now, let's put argc (and argv, envp if appropriate) on the stack */
__put_user(argc, sp++);
if (interp_aout) {
argv = sp + 2;
envp = argv + argc + 1;
__put_user((elf_addr_t)argv, sp++);
__put_user((elf_addr_t)envp, sp++);
} else {
argv = sp;
envp = argv + argc + 1;
}
/* Populate argv and envp */
p = current->mm->arg_start;
while (argc-- > 0) {
size_t len;
__put_user((elf_addr_t)p, argv++);
len = strnlen_user((void *)p, PAGE_SIZE*MAX_ARG_PAGES);
if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
return NULL;
return;
p += len;
}
__put_user(NULL, argv);
current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
__put_user((elf_caddr_t)(unsigned long)p,envp++);
len = strnlen_user(p, PAGE_SIZE*MAX_ARG_PAGES);
current->mm->arg_end = current->mm->env_start = p;
while (envc-- > 0) {
size_t len;
__put_user((elf_addr_t)p, envp++);
len = strnlen_user((void *)p, PAGE_SIZE*MAX_ARG_PAGES);
if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
return NULL;
return;
p += len;
}
__put_user(NULL, envp);
current->mm->env_end = (unsigned long) p;
return sp;
current->mm->env_end = p;
/* Put the elf_info on the stack in the right place. */
sp = (elf_addr_t *)envp + 1;
copy_to_user(sp, elf_info, ei_index * sizeof(elf_addr_t));
}
#ifndef elf_map
......@@ -438,7 +449,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
unsigned char ibcs2_interpreter = 0;
unsigned long error;
struct elf_phdr * elf_ppnt, *elf_phdata;
unsigned long elf_bss, k, elf_brk;
unsigned long elf_bss, elf_brk;
int elf_exec_fileno;
int retval, i;
unsigned int size;
......@@ -576,19 +587,15 @@ 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,
and then start this sucker up */
if (!bprm->sh_bang) {
char * passed_p;
if ((!bprm->sh_bang) && (interpreter_type == INTERPRETER_AOUT)) {
char *passed_p = passed_fileno;
sprintf(passed_fileno, "%d", elf_exec_fileno);
if (interpreter_type == INTERPRETER_AOUT) {
sprintf(passed_fileno, "%d", elf_exec_fileno);
passed_p = passed_fileno;
if (elf_interpreter) {
retval = copy_strings_kernel(1,&passed_p,bprm);
if (elf_interpreter) {
retval = copy_strings_kernel(1, &passed_p, bprm);
if (retval)
goto out_free_dentry;
bprm->argc++;
}
bprm->argc++;
}
}
......@@ -603,7 +610,10 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->mm->end_code = 0;
current->mm->mmap = NULL;
current->flags &= ~PF_FORKNOEXEC;
elf_entry = (unsigned long) elf_ex.e_entry;
/* Do this immediately, since STACK_TOP as used in setup_arg_pages
may depend on the personality. */
SET_PERSONALITY(elf_ex, ibcs2_interpreter);
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
......@@ -623,7 +633,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
int elf_prot = 0, elf_flags;
unsigned long vaddr;
unsigned long k, vaddr;
if (elf_ppnt->p_type != PT_LOAD)
continue;
......@@ -656,7 +666,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
} else if (elf_ex.e_type == ET_DYN) {
/* Try and get dynamic programs out of the way of the default mmap
base, as well as whatever program they might try to exec. This
is because the brk will follow the loader, and is not movable. */
is because the brk will follow the loader, and is not movable. */
load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
}
......@@ -681,7 +691,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if (k > elf_bss)
elf_bss = k;
if ((elf_ppnt->p_flags & PF_X) && end_code < k)
if ((elf_ppnt->p_flags & PF_X) && end_code < k)
end_code = k;
if (end_data < k)
end_data = k;
......@@ -690,7 +700,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
elf_brk = k;
}
elf_entry += load_bias;
elf_ex.e_entry += load_bias;
elf_bss += load_bias;
elf_brk += load_bias;
start_code += load_bias;
......@@ -717,6 +727,8 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
send_sig(SIGSEGV, current, 0);
return 0;
}
} else {
elf_entry = elf_ex.e_entry;
}
kfree(elf_phdata);
......@@ -728,18 +740,11 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
bprm->p = (unsigned long)
create_elf_tables((char *)bprm->p,
bprm->argc,
bprm->envc,
&elf_ex,
load_addr, load_bias,
interp_load_addr,
(interpreter_type == INTERPRETER_AOUT ? 0 : 1));
create_elf_tables(bprm, &elf_ex, (interpreter_type == INTERPRETER_AOUT),
load_addr, interp_load_addr);
/* N.B. passed_fileno might not be initialized? */
if (interpreter_type == INTERPRETER_AOUT)
current->mm->arg_start += strlen(passed_fileno) + 1;
current->mm->start_brk = current->mm->brk = elf_brk;
current->mm->end_code = end_code;
current->mm->start_code = start_code;
current->mm->start_data = start_data;
......
......@@ -323,9 +323,50 @@ int setup_arg_pages(struct linux_binprm *bprm)
{
unsigned long stack_base;
struct vm_area_struct *mpnt;
struct mm_struct *mm = current->mm;
int i;
stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
#ifdef ARCH_STACK_GROWSUP
/* Move the argument and environment strings to the bottom of the
* stack space.
*/
int offset, j;
char *to, *from;
/* Start by shifting all the pages down */
i = 0;
for (j = 0; j < MAX_ARG_PAGES; j++) {
struct page *page = bprm->page[j];
if (!page)
continue;
bprm->page[i++] = page;
}
/* Now move them within their pages */
offset = bprm->p % PAGE_SIZE;
to = kmap(bprm->page[0]);
for (j = 1; j < i; j++) {
memmove(to, to + offset, PAGE_SIZE - offset);
from = kmap(bprm->page[j]);
memcpy(to + PAGE_SIZE - offset, from, offset);
kunmap(bprm[j - 1]);
to = from;
}
memmove(to, to + offset, PAGE_SIZE - offset);
kunmap(bprm[j - 1]);
/* Adjust bprm->p to point to the end of the strings. */
bprm->p = PAGE_SIZE * i - offset;
stack_base = STACK_TOP - current->rlim[RLIMIT_STACK].rlim_max;
mm->arg_start = stack_base;
/* zero pages that were copied above */
while (i < MAX_ARG_PAGES)
bprm->page[i++] = NULL;
#else
stack_base = STACK_TOP - MAX_ARG_PAGES * PAGE_SIZE;
mm->arg_start = bprm->p + stack_base;
#endif
bprm->p += stack_base;
if (bprm->loader)
......@@ -333,7 +374,7 @@ int setup_arg_pages(struct linux_binprm *bprm)
bprm->exec += stack_base;
mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!mpnt)
if (!mpnt)
return -ENOMEM;
if (!vm_enough_memory((STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))>>PAGE_SHIFT)) {
......@@ -341,19 +382,25 @@ int setup_arg_pages(struct linux_binprm *bprm)
return -ENOMEM;
}
down_write(&current->mm->mmap_sem);
down_write(&mm->mmap_sem);
{
mpnt->vm_mm = current->mm;
mpnt->vm_mm = mm;
#ifdef ARCH_STACK_GROWSUP
mpnt->vm_start = stack_base;
mpnt->vm_end = PAGE_MASK &
(PAGE_SIZE - 1 + (unsigned long) bprm->p);
#else
mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
mpnt->vm_end = STACK_TOP;
#endif
mpnt->vm_page_prot = PAGE_COPY;
mpnt->vm_flags = VM_STACK_FLAGS;
mpnt->vm_ops = NULL;
mpnt->vm_pgoff = 0;
mpnt->vm_file = NULL;
mpnt->vm_private_data = (void *) 0;
insert_vm_struct(current->mm, mpnt);
current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
insert_vm_struct(mm, mpnt);
mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
}
for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
......@@ -364,7 +411,7 @@ int setup_arg_pages(struct linux_binprm *bprm)
}
stack_base += PAGE_SIZE;
}
up_write(&current->mm->mmap_sem);
up_write(&mm->mmap_sem);
return 0;
}
......@@ -732,7 +779,6 @@ void compute_creds(struct linux_binprm *bprm)
security_ops->bprm_compute_creds(bprm);
}
void remove_arg_zero(struct linux_binprm *bprm)
{
if (bprm->argc) {
......@@ -854,7 +900,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
return retval;
}
/*
* sys_execve() executes a new program.
*/
......
......@@ -334,7 +334,6 @@ void ia64_elf32_init(struct pt_regs *regs);
#define ELF_PLAT_INIT(_r) ia64_elf32_init(_r)
#define elf_addr_t u32
#define elf_caddr_t u32
/* ELF register definitions. This is needed for core dump support. */
......
......@@ -31,7 +31,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
\
if (__h->e_machine != EM_MIPS) \
__res = 0; \
if (sizeof(elf_caddr_t) == 8 && \
if (sizeof(elf_addr_t) == 8 && \
__h->e_ident[EI_CLASS] == ELFCLASS32) \
__res = 0; \
\
......
......@@ -98,19 +98,14 @@ extern int ucache_bsize;
* - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
* even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
*/
#define DLINFO_ARCH_ITEMS 3
#define ARCH_DLINFO \
do { \
sp -= DLINFO_ARCH_ITEMS * 2; \
NEW_AUX_ENT(0, AT_DCACHEBSIZE, dcache_bsize); \
NEW_AUX_ENT(1, AT_ICACHEBSIZE, icache_bsize); \
NEW_AUX_ENT(2, AT_UCACHEBSIZE, ucache_bsize); \
/* \
* Now handle glibc compatibility. \
*/ \
sp -= 2*2; \
NEW_AUX_ENT(0, AT_IGNOREPPC, AT_IGNOREPPC); \
NEW_AUX_ENT(1, AT_IGNOREPPC, AT_IGNOREPPC); \
NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \
NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \
NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \
/* Now handle glibc compatibility. */ \
NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
} while (0)
#endif /* __KERNEL__ */
......
......@@ -31,13 +31,11 @@ typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
typedef elf_greg_t64 elf_greg_t;
typedef elf_gregset_t64 elf_gregset_t;
# define elf_addr_t unsigned long
# define elf_caddr_t char *
#else
/* Assumption: ELF_ARCH == EM_PPC and ELF_CLASS == ELFCLASS32 */
typedef elf_greg_t32 elf_greg_t;
typedef elf_gregset_t32 elf_gregset_t;
# define elf_addr_t u32
# define elf_caddr_t u32
#endif
typedef double elf_fpreg_t;
......@@ -122,19 +120,14 @@ extern int ucache_bsize;
* - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
* even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
*/
#define DLINFO_ARCH_ITEMS 3
#define ARCH_DLINFO \
do { \
sp -= DLINFO_ARCH_ITEMS * 2; \
NEW_AUX_ENT(0, AT_DCACHEBSIZE, dcache_bsize); \
NEW_AUX_ENT(1, AT_ICACHEBSIZE, icache_bsize); \
NEW_AUX_ENT(2, AT_UCACHEBSIZE, ucache_bsize); \
/* \
* Now handle glibc compatibility. \
*/ \
sp -= 2*2; \
NEW_AUX_ENT(0, AT_IGNOREPPC, AT_IGNOREPPC); \
NEW_AUX_ENT(1, AT_IGNOREPPC, AT_IGNOREPPC); \
NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \
NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \
NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \
/* Now handle glibc compatibility. */ \
NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
} while (0)
#endif /* __PPC64_ELF_H */
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