linux-old/fs/binfmt_elf.c
<<
>>
Prefs
   1/*
   2 * linux/fs/binfmt_elf.c
   3 *
   4 * These are the functions used to load ELF format executables as used
   5 * on SVr4 machines.  Information on the format may be found in the book
   6 * "UNIX SYSTEM V RELEASE 4 Programmers Guide: Ansi C and Programming Support
   7 * Tools".
   8 *
   9 * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
  10 */
  11
  12#include <linux/module.h>
  13
  14#include <linux/fs.h>
  15#include <linux/stat.h>
  16#include <linux/sched.h>
  17#include <linux/mm.h>
  18#include <linux/mman.h>
  19#include <linux/a.out.h>
  20#include <linux/errno.h>
  21#include <linux/signal.h>
  22#include <linux/binfmts.h>
  23#include <linux/string.h>
  24#include <linux/file.h>
  25#include <linux/fcntl.h>
  26#include <linux/ptrace.h>
  27#include <linux/malloc.h>
  28#include <linux/shm.h>
  29#include <linux/personality.h>
  30#include <linux/elfcore.h>
  31#include <linux/init.h>
  32
  33#include <asm/uaccess.h>
  34#include <asm/pgtable.h>
  35
  36#include <linux/config.h>
  37
  38#define DLINFO_ITEMS 13
  39
  40#include <linux/elf.h>
  41
  42static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
  43static int load_elf_library(struct file *file);
  44extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
  45extern void dump_thread(struct pt_regs *, struct user *);
  46
  47#ifndef elf_addr_t
  48#define elf_addr_t unsigned long
  49#define elf_caddr_t char *
  50#endif
  51
  52/*
  53 * If we don't support core dumping, then supply a NULL so we
  54 * don't even try.
  55 */
  56#ifdef USE_ELF_CORE_DUMP
  57static int elf_core_dump(long signr, struct pt_regs * regs, struct file *);
  58#else
  59#define elf_core_dump   NULL
  60#endif
  61
  62#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_EXEC_PAGESIZE-1))
  63#define ELF_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
  64#define ELF_PAGEALIGN(_v) (((_v) + ELF_EXEC_PAGESIZE - 1) & ~(ELF_EXEC_PAGESIZE - 1))
  65
  66static struct linux_binfmt elf_format = {
  67        module:         THIS_MODULE,
  68        load_binary:    load_elf_binary,
  69        load_shlib:     load_elf_library,
  70        core_dump:      elf_core_dump,
  71        min_coredump:   ELF_EXEC_PAGESIZE,
  72};
  73
  74static void set_brk(unsigned long start, unsigned long end)
  75{
  76        start = ELF_PAGEALIGN(start);
  77        end = ELF_PAGEALIGN(end);
  78        if (end <= start)
  79                return;
  80        do_mmap(NULL, start, end - start,
  81                PROT_READ | PROT_WRITE | PROT_EXEC,
  82                MAP_FIXED | MAP_PRIVATE, 0);
  83}
  84
  85
  86/* We need to explicitly zero any fractional pages
  87   after the data section (i.e. bss).  This would
  88   contain the junk from the file that should not
  89   be in memory */
  90
  91
  92static void padzero(unsigned long elf_bss)
  93{
  94        unsigned long nbyte;
  95
  96        nbyte = ELF_PAGEOFFSET(elf_bss);
  97        if (nbyte) {
  98                nbyte = ELF_EXEC_PAGESIZE - nbyte;
  99                clear_user((void *) elf_bss, nbyte);
 100        }
 101}
 102
 103static elf_addr_t * 
 104create_elf_tables(char *p, int argc, int envc,
 105                  struct elfhdr * exec,
 106                  unsigned long load_addr,
 107                  unsigned long load_bias,
 108                  unsigned long interp_load_addr, int ibcs)
 109{
 110        elf_caddr_t *argv;
 111        elf_caddr_t *envp;
 112        elf_addr_t *sp, *csp;
 113        char *k_platform, *u_platform;
 114        long hwcap;
 115        size_t platform_len = 0;
 116        long len;
 117
 118        /*
 119         * Get hold of platform and hardware capabilities masks for
 120         * the machine we are running on.  In some cases (Sparc), 
 121         * this info is impossible to get, in others (i386) it is
 122         * merely difficult.
 123         */
 124
 125        hwcap = ELF_HWCAP;
 126        k_platform = ELF_PLATFORM;
 127
 128        if (k_platform) {
 129                platform_len = strlen(k_platform) + 1;
 130                u_platform = p - platform_len;
 131                __copy_to_user(u_platform, k_platform, platform_len);
 132        } else
 133                u_platform = p;
 134
 135        /*
 136         * Force 16 byte _final_ alignment here for generality.
 137         * Leave an extra 16 bytes free so that on the PowerPC we
 138         * can move the aux table up to start on a 16-byte boundary.
 139         */
 140        sp = (elf_addr_t *)((~15UL & (unsigned long)(u_platform)) - 16UL);
 141        csp = sp;
 142        csp -= ((exec ? DLINFO_ITEMS*2 : 4) + (k_platform ? 2 : 0));
 143        csp -= envc+1;
 144        csp -= argc+1;
 145        csp -= (!ibcs ? 3 : 1); /* argc itself */
 146        if ((unsigned long)csp & 15UL)
 147                sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
 148
 149        /*
 150         * Put the ELF interpreter info on the stack
 151         */
 152#define NEW_AUX_ENT(nr, id, val) \
 153          __put_user ((id), sp+(nr*2)); \
 154          __put_user ((val), sp+(nr*2+1)); \
 155
 156        sp -= 2;
 157        NEW_AUX_ENT(0, AT_NULL, 0);
 158        if (k_platform) {
 159                sp -= 2;
 160                NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform);
 161        }
 162        sp -= 2;
 163        NEW_AUX_ENT(0, AT_HWCAP, hwcap);
 164
 165        if (exec) {
 166                sp -= 11*2;
 167
 168                NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff);
 169                NEW_AUX_ENT(1, AT_PHENT, sizeof (struct elf_phdr));
 170                NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum);
 171                NEW_AUX_ENT(3, AT_PAGESZ, ELF_EXEC_PAGESIZE);
 172                NEW_AUX_ENT(4, AT_BASE, interp_load_addr);
 173                NEW_AUX_ENT(5, AT_FLAGS, 0);
 174                NEW_AUX_ENT(6, AT_ENTRY, load_bias + exec->e_entry);
 175                NEW_AUX_ENT(7, AT_UID, (elf_addr_t) current->uid);
 176                NEW_AUX_ENT(8, AT_EUID, (elf_addr_t) current->euid);
 177                NEW_AUX_ENT(9, AT_GID, (elf_addr_t) current->gid);
 178                NEW_AUX_ENT(10, AT_EGID, (elf_addr_t) current->egid);
 179        }
 180#undef NEW_AUX_ENT
 181
 182        sp -= envc+1;
 183        envp = (elf_caddr_t *) sp;
 184        sp -= argc+1;
 185        argv = (elf_caddr_t *) sp;
 186        if (!ibcs) {
 187                __put_user((elf_addr_t)(unsigned long) envp,--sp);
 188                __put_user((elf_addr_t)(unsigned long) argv,--sp);
 189        }
 190
 191        __put_user((elf_addr_t)argc,--sp);
 192        current->mm->arg_start = (unsigned long) p;
 193        while (argc-->0) {
 194                __put_user((elf_caddr_t)(unsigned long)p,argv++);
 195                len = strnlen_user(p, PAGE_SIZE*MAX_ARG_PAGES);
 196                /* "can't happen" */
 197                if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
 198                        return NULL;
 199                p += len;
 200        }
 201        __put_user(NULL, argv);
 202        current->mm->arg_end = current->mm->env_start = (unsigned long) p;
 203        while (envc-->0) {
 204                __put_user((elf_caddr_t)(unsigned long)p,envp++);
 205                len = strnlen_user(p, PAGE_SIZE*MAX_ARG_PAGES);
 206                /* "can't happen" */
 207                if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
 208                        return NULL;
 209                p += len;
 210        }
 211        __put_user(NULL, envp);
 212        current->mm->env_end = (unsigned long) p;
 213        return sp;
 214}
 215
 216
 217/* This is much more generalized than the library routine read function,
 218   so we keep this separate.  Technically the library read function
 219   is only provided so that we can read a.out libraries that have
 220   an ELF header */
 221
 222static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
 223                                     struct dentry * interpreter_dentry,
 224                                     unsigned long *interp_load_addr)
 225{
 226        struct file * file;
 227        struct elf_phdr *elf_phdata;
 228        struct elf_phdr *eppnt;
 229        unsigned long load_addr = 0;
 230        int load_addr_set = 0;
 231        unsigned long last_bss = 0, elf_bss = 0;
 232        unsigned long error = ~0UL;
 233        int elf_exec_fileno;
 234        int retval, i, size;
 235
 236        /* First of all, some simple consistency checks */
 237        if (interp_elf_ex->e_type != ET_EXEC &&
 238            interp_elf_ex->e_type != ET_DYN)
 239                goto out;
 240        if (!elf_check_arch(interp_elf_ex->e_machine))
 241                goto out;
 242        if (!interpreter_dentry->d_inode->i_op ||
 243            !interpreter_dentry->d_inode->i_op->default_file_ops->mmap)
 244                goto out;
 245
 246        /*
 247         * If the size of this structure has changed, then punt, since
 248         * we will be doing the wrong thing.
 249         */
 250        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr))
 251                goto out;
 252
 253        /* Now read in all of the header information */
 254
 255        if (interp_elf_ex->e_phnum < 1 || interp_elf_ex->e_phnum >
 256            ELF_EXEC_PAGESIZE / sizeof(struct elf_phdr))
 257                goto out;
 258        size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum;
 259        elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
 260        if (!elf_phdata)
 261                goto out;
 262
 263        retval = read_exec(interpreter_dentry, interp_elf_ex->e_phoff,
 264                           (char *) elf_phdata, size, 1);
 265        error = retval;
 266        if (retval < 0)
 267                goto out_free;
 268
 269        error = ~0UL;
 270        elf_exec_fileno = open_dentry(interpreter_dentry, O_RDONLY);
 271        if (elf_exec_fileno < 0)
 272                goto out_free;
 273        file = fget(elf_exec_fileno);
 274
 275        eppnt = elf_phdata;
 276        for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
 277          if (eppnt->p_type == PT_LOAD) {
 278            int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
 279            int elf_prot = 0;
 280            unsigned long vaddr = 0;
 281            unsigned long k, map_addr;
 282
 283            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
 284            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
 285            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
 286            vaddr = eppnt->p_vaddr;
 287            if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
 288                elf_type |= MAP_FIXED;
 289#ifdef __sparc__
 290            } else {
 291                load_addr = get_unmapped_area(0, eppnt->p_filesz +
 292                                        ELF_PAGEOFFSET(vaddr));
 293#endif
 294            }
 295
 296            map_addr = do_mmap(file,
 297                            load_addr + ELF_PAGESTART(vaddr),
 298                            eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr),
 299                            elf_prot,
 300                            elf_type,
 301                            eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
 302            if (map_addr > -1024UL) /* Real error */
 303                goto out_close;
 304
 305            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
 306                load_addr = map_addr - ELF_PAGESTART(vaddr);
 307                load_addr_set = 1;
 308            }
 309
 310            /*
 311             * Find the end of the file mapping for this phdr, and keep
 312             * track of the largest address we see for this.
 313             */
 314            k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
 315            if (k > elf_bss)
 316                elf_bss = k;
 317
 318            /*
 319             * Do the same thing for the memory mapping - between
 320             * elf_bss and last_bss is the bss section.
 321             */
 322            k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
 323            if (k > last_bss)
 324                last_bss = k;
 325          }
 326        }
 327
 328        /* Now use mmap to map the library into memory. */
 329
 330        /*
 331         * Now fill out the bss section.  First pad the last page up
 332         * to the page boundary, and then perform a mmap to make sure
 333         * that there are zero-mapped pages up to and including the 
 334         * last bss page.
 335         */
 336        padzero(elf_bss);
 337        elf_bss = ELF_PAGESTART(elf_bss + ELF_EXEC_PAGESIZE - 1); /* What we have mapped so far */
 338
 339        /* Map the last of the bss segment */
 340        if (last_bss > elf_bss)
 341                do_mmap(NULL, elf_bss, last_bss - elf_bss,
 342                        PROT_READ|PROT_WRITE|PROT_EXEC,
 343                        MAP_FIXED|MAP_PRIVATE, 0);
 344
 345        *interp_load_addr = load_addr;
 346        /*
 347         * AUDIT: is everything deallocated properly if this happens
 348         * to be ~0UL? We'd better switch to out-of-band error reporting.
 349         * Also for a.out.
 350         */
 351        error = ((unsigned long) interp_elf_ex->e_entry) + load_addr;
 352
 353out_close:
 354        fput(file);
 355        sys_close(elf_exec_fileno);
 356out_free:
 357        kfree(elf_phdata);
 358out:
 359        return error;
 360}
 361
 362static unsigned long load_aout_interp(struct exec * interp_ex,
 363                             struct dentry * interpreter_dentry)
 364{
 365        unsigned long text_data, offset, elf_entry = ~0UL;
 366        char * addr;
 367        int retval;
 368
 369        current->mm->end_code = interp_ex->a_text;
 370        text_data = interp_ex->a_text + interp_ex->a_data;
 371        current->mm->end_data = text_data;
 372        current->mm->brk = interp_ex->a_bss + text_data;
 373
 374        switch (N_MAGIC(*interp_ex)) {
 375        case OMAGIC:
 376                offset = 32;
 377                addr = (char *) 0;
 378                break;
 379        case ZMAGIC:
 380        case QMAGIC:
 381                offset = N_TXTOFF(*interp_ex);
 382                addr = (char *) N_TXTADDR(*interp_ex);
 383                break;
 384        default:
 385                goto out;
 386        }
 387
 388        if ((unsigned long)addr + text_data < text_data)
 389                goto out;
 390
 391        do_mmap(NULL, 0, text_data,
 392                PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0);
 393        retval = read_exec(interpreter_dentry, offset, addr, text_data, 0);
 394        if (retval < 0)
 395                goto out;
 396        flush_icache_range((unsigned long)addr,
 397                           (unsigned long)addr + text_data);
 398
 399        do_mmap(NULL, ELF_PAGESTART(text_data + ELF_EXEC_PAGESIZE - 1),
 400                interp_ex->a_bss,
 401                PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0);
 402        elf_entry = interp_ex->a_entry;
 403
 404out:
 405        return elf_entry;
 406}
 407
 408/*
 409 * These are the functions used to load ELF style executables and shared
 410 * libraries.  There is no binary dependent code anywhere else.
 411 */
 412
 413#define INTERPRETER_NONE 0
 414#define INTERPRETER_AOUT 1
 415#define INTERPRETER_ELF 2
 416
 417
 418static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
 419{
 420        struct file * file;
 421        struct dentry *interpreter_dentry = NULL; /* to shut gcc up */
 422        unsigned long load_addr = 0, load_bias;
 423        int load_addr_set = 0;
 424        char * elf_interpreter = NULL;
 425        unsigned int interpreter_type = INTERPRETER_NONE;
 426        unsigned char ibcs2_interpreter = 0;
 427        mm_segment_t old_fs;
 428        unsigned long error;
 429        struct elf_phdr * elf_ppnt, *elf_phdata;
 430        unsigned long elf_bss, k, elf_brk;
 431        int elf_exec_fileno;
 432        int retval, size, i;
 433        unsigned long elf_entry, interp_load_addr = 0;
 434        unsigned long start_code, end_code, end_data;
 435        struct elfhdr elf_ex;
 436        struct elfhdr interp_elf_ex;
 437        struct exec interp_ex;
 438        char passed_fileno[6];
 439
 440        /* Get the exec-header */
 441        elf_ex = *((struct elfhdr *) bprm->buf);
 442
 443        retval = -ENOEXEC;
 444        /* First of all, some simple consistency checks */
 445        if (elf_ex.e_ident[0] != 0x7f ||
 446            strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0)
 447                goto out;
 448
 449        if (elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN)
 450                goto out;
 451        if (!elf_check_arch(elf_ex.e_machine))
 452                goto out;
 453#ifdef __mips__
 454        /* IRIX binaries handled elsewhere. */
 455        if (elf_ex.e_flags & EF_MIPS_ARCH) {
 456                retval = -ENOEXEC;
 457                goto out;
 458        }
 459#endif
 460        if (!bprm->dentry->d_inode->i_op                   ||
 461            !bprm->dentry->d_inode->i_op->default_file_ops ||
 462            !bprm->dentry->d_inode->i_op->default_file_ops->mmap)
 463                goto out;
 464
 465        /* Now read in all of the header information */
 466
 467        if (elf_ex.e_phentsize != sizeof(struct elf_phdr) ||
 468            elf_ex.e_phnum < 1 ||
 469            elf_ex.e_phnum > 65536 / sizeof(struct elf_phdr))
 470                goto out;
 471
 472        retval = -ENOMEM;
 473        size = elf_ex.e_phentsize * elf_ex.e_phnum;
 474        elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
 475        if (!elf_phdata)
 476                goto out;
 477
 478        retval = read_exec(bprm->dentry, elf_ex.e_phoff,
 479                                (char *) elf_phdata, size, 1);
 480        if (retval < 0)
 481                goto out_free_ph;
 482
 483        retval = open_dentry(bprm->dentry, O_RDONLY);
 484        if (retval < 0)
 485                goto out_free_ph;
 486        elf_exec_fileno = retval;
 487        file = fget(elf_exec_fileno);
 488
 489        elf_ppnt = elf_phdata;
 490        elf_bss = 0;
 491        elf_brk = 0;
 492
 493        start_code = ~0UL;
 494        end_code = 0;
 495        end_data = 0;
 496
 497        for (i = 0; i < elf_ex.e_phnum; i++) {
 498                if (elf_ppnt->p_type == PT_INTERP) {
 499                        retval = -ENOEXEC;
 500                        if (elf_interpreter ||
 501                            elf_ppnt->p_filesz < 2 ||
 502                            elf_ppnt->p_filesz > PAGE_SIZE)
 503                                goto out_free_dentry;
 504
 505                        /* This is the program interpreter used for
 506                         * shared libraries - for now assume that this
 507                         * is an a.out format binary
 508                         */
 509
 510                        retval = -ENOMEM;
 511                        elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
 512                                                           GFP_KERNEL);
 513                        if (!elf_interpreter)
 514                                goto out_free_file;
 515
 516                        retval = read_exec(bprm->dentry, elf_ppnt->p_offset,
 517                                           elf_interpreter,
 518                                           elf_ppnt->p_filesz, 1);
 519                        if (retval < 0)
 520                                goto out_free_interp;
 521                        elf_interpreter[elf_ppnt->p_filesz - 1] = 0;
 522                        /* If the program interpreter is one of these two,
 523                         * then assume an iBCS2 image. Otherwise assume
 524                         * a native linux image.
 525                         */
 526                        if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
 527                            strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0)
 528                                ibcs2_interpreter = 1;
 529#if 0
 530                        printk("Using ELF interpreter %s\n", elf_interpreter);
 531#endif
 532                        old_fs = get_fs(); /* This could probably be optimized */
 533                        set_fs(get_ds());
 534#ifdef __sparc__
 535                        if (ibcs2_interpreter) {
 536                                unsigned long old_pers = current->personality;
 537                                        
 538                                current->personality = PER_SVR4;
 539                                interpreter_dentry = open_namei(elf_interpreter,
 540                                                                1, 0);
 541                                current->personality = old_pers;
 542                        } else
 543#endif                                  
 544                                interpreter_dentry = open_namei(elf_interpreter,
 545                                                                1, 0);
 546                        set_fs(old_fs);
 547                        retval = PTR_ERR(interpreter_dentry);
 548                        if (IS_ERR(interpreter_dentry))
 549                                goto out_free_interp;
 550                        retval = permission(interpreter_dentry->d_inode, MAY_EXEC);
 551                        if (retval < 0)
 552                                goto out_free_dentry;
 553                        retval = read_exec(interpreter_dentry, 0, bprm->buf, 128, 1);
 554                        if (retval < 0)
 555                                goto out_free_dentry;
 556
 557                        /* Get the exec headers */
 558                        interp_ex = *((struct exec *) bprm->buf);
 559                        interp_elf_ex = *((struct elfhdr *) bprm->buf);
 560                }
 561                elf_ppnt++;
 562        }
 563
 564        /* Some simple consistency checks for the interpreter */
 565        if (elf_interpreter) {
 566                interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
 567
 568                /* Now figure out which format our binary is */
 569                if ((N_MAGIC(interp_ex) != OMAGIC) &&
 570                    (N_MAGIC(interp_ex) != ZMAGIC) &&
 571                    (N_MAGIC(interp_ex) != QMAGIC))
 572                        interpreter_type = INTERPRETER_ELF;
 573
 574                if (interp_elf_ex.e_ident[0] != 0x7f ||
 575                    strncmp(&interp_elf_ex.e_ident[1], "ELF", 3) != 0)
 576                        interpreter_type &= ~INTERPRETER_ELF;
 577
 578                retval = -ELIBBAD;
 579                if (!interpreter_type)
 580                        goto out_free_dentry;
 581
 582                /* Make sure only one type was selected */
 583                if ((interpreter_type & INTERPRETER_ELF) &&
 584                     interpreter_type != INTERPRETER_ELF) {
 585                        printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");
 586                        interpreter_type = INTERPRETER_ELF;
 587                }
 588        }
 589
 590        /* OK, we are done with that, now set up the arg stuff,
 591           and then start this sucker up */
 592
 593        if (!bprm->sh_bang) {
 594                char * passed_p;
 595
 596                if (interpreter_type == INTERPRETER_AOUT) {
 597                  sprintf(passed_fileno, "%d", elf_exec_fileno);
 598                  passed_p = passed_fileno;
 599
 600                  if (elf_interpreter) {
 601                    bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
 602                    bprm->argc++;
 603                  }
 604                }
 605                retval = (long)bprm->p;
 606                if ((long)bprm->p < 0)
 607                        goto out_free_dentry;
 608        }
 609
 610        /* Flush all traces of the currently running executable */
 611        retval = flush_old_exec(bprm);
 612        if (retval)
 613                goto out_free_dentry;
 614
 615        /* OK, This is the point of no return */
 616        current->mm->end_data = 0;
 617        current->mm->end_code = 0;
 618        current->mm->mmap = NULL;
 619        current->flags &= ~PF_FORKNOEXEC;
 620        elf_entry = (unsigned long) elf_ex.e_entry;
 621
 622        /* Do this immediately, since STACK_TOP as used in setup_arg_pages
 623           may depend on the personality.  */
 624        SET_PERSONALITY(elf_ex, ibcs2_interpreter);
 625
 626        /* Do this so that we can load the interpreter, if need be.  We will
 627           change some of these later */
 628        current->mm->rss = 0;
 629        bprm->p = setup_arg_pages(bprm->p, bprm);
 630        current->mm->start_stack = bprm->p;
 631
 632        /* Try and get dynamic programs out of the way of the default mmap
 633           base, as well as whatever program they might try to exec.  This
 634           is because the brk will follow the loader, and is not movable.  */
 635
 636        load_bias = ELF_PAGESTART(elf_ex.e_type==ET_DYN ? ELF_ET_DYN_BASE : 0);
 637
 638        /* Now we do a little grungy work by mmaping the ELF image into
 639           the correct location in memory.  At this point, we assume that
 640           the image should be loaded at fixed address, not at a variable
 641           address. */
 642
 643        old_fs = get_fs();
 644        set_fs(get_ds());
 645        for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
 646                int elf_prot = 0, elf_flags;
 647                unsigned long vaddr;
 648
 649                if (elf_ppnt->p_type != PT_LOAD)
 650                        continue;
 651
 652                if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
 653                if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
 654                if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
 655
 656                elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
 657
 658                vaddr = elf_ppnt->p_vaddr;
 659                if (elf_ex.e_type == ET_EXEC || load_addr_set) {
 660                        elf_flags |= MAP_FIXED;
 661                }
 662
 663                error = do_mmap(file, ELF_PAGESTART(load_bias + vaddr),
 664                                (elf_ppnt->p_filesz +
 665                                ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
 666                                elf_prot, elf_flags, (elf_ppnt->p_offset -
 667                                ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
 668
 669                if (!load_addr_set) {
 670                        load_addr_set = 1;
 671                        load_addr = (elf_ppnt->p_vaddr - elf_ppnt->p_offset);
 672                        if (elf_ex.e_type == ET_DYN) {
 673                                load_bias += error -
 674                                             ELF_PAGESTART(load_bias + vaddr);
 675                                load_addr += load_bias;
 676                        }
 677                }
 678                k = elf_ppnt->p_vaddr;
 679                if (k < start_code) start_code = k;
 680                k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
 681                if (k > elf_bss)
 682                        elf_bss = k;
 683                if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
 684                        end_code = k;
 685                if (end_data < k)
 686                        end_data = k;
 687                k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
 688                if (k > elf_brk)
 689                        elf_brk = k;
 690        }
 691        set_fs(old_fs);
 692        fput(file); /* all done with the file */
 693
 694        elf_entry += load_bias;
 695        elf_bss += load_bias;
 696        elf_brk += load_bias;
 697        start_code += load_bias;
 698        end_code += load_bias;
 699        end_data += load_bias;
 700
 701        if (elf_interpreter) {
 702                if (interpreter_type == INTERPRETER_AOUT)
 703                        elf_entry = load_aout_interp(&interp_ex,
 704                                                     interpreter_dentry);
 705                else
 706                        elf_entry = load_elf_interp(&interp_elf_ex,
 707                                                    interpreter_dentry,
 708                                                    &interp_load_addr);
 709
 710                dput(interpreter_dentry);
 711
 712                if (elf_entry == ~0UL) {
 713                        printk(KERN_ERR "Unable to load interpreter %.128s\n",
 714                                elf_interpreter);
 715                        kfree(elf_interpreter);
 716                        kfree(elf_phdata);
 717                        force_sig(SIGSEGV, current);
 718                        return 0;
 719                }
 720
 721                kfree(elf_interpreter);
 722        }
 723
 724        kfree(elf_phdata);
 725
 726        if (interpreter_type != INTERPRETER_AOUT)
 727                sys_close(elf_exec_fileno);
 728
 729        set_binfmt(&elf_format);
 730        if (current->exec_domain && current->exec_domain->module)
 731                __MOD_DEC_USE_COUNT(current->exec_domain->module);
 732        current->exec_domain = lookup_exec_domain(current->personality);
 733        if (current->exec_domain && current->exec_domain->module)
 734                __MOD_INC_USE_COUNT(current->exec_domain->module);
 735
 736        compute_creds(bprm);
 737        current->flags &= ~PF_FORKNOEXEC;
 738        bprm->p = (unsigned long)
 739          create_elf_tables((char *)bprm->p,
 740                        bprm->argc,
 741                        bprm->envc,
 742                        (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
 743                        load_addr, load_bias,
 744                        interp_load_addr,
 745                        (interpreter_type == INTERPRETER_AOUT ? 0 : 1));
 746        if (!bprm->p) {
 747                force_sig(SIGSEGV, current);
 748                return 0;
 749        }
 750        /* N.B. passed_fileno might not be initialized? */
 751        if (interpreter_type == INTERPRETER_AOUT)
 752                current->mm->arg_start += strlen(passed_fileno) + 1;
 753        current->mm->start_brk = current->mm->brk = elf_brk;
 754        current->mm->end_code = end_code;
 755        current->mm->start_code = start_code;
 756        current->mm->end_data = end_data;
 757        current->mm->start_stack = bprm->p;
 758
 759        /* Calling set_brk effectively mmaps the pages that we need
 760         * for the bss and break sections
 761         */
 762        set_brk(elf_bss, elf_brk);
 763
 764        padzero(elf_bss);
 765
 766#if 0
 767        printk("(start_brk) %x\n" , current->mm->start_brk);
 768        printk("(end_code) %x\n" , current->mm->end_code);
 769        printk("(start_code) %x\n" , current->mm->start_code);
 770        printk("(end_data) %x\n" , current->mm->end_data);
 771        printk("(start_stack) %x\n" , current->mm->start_stack);
 772        printk("(brk) %x\n" , current->mm->brk);
 773#endif
 774
 775        if ( current->personality == PER_SVR4 )
 776        {
 777                /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
 778                   and some applications "depend" upon this behavior.
 779                   Since we do not have the power to recompile these, we
 780                   emulate the SVr4 behavior.  Sigh.  */
 781                /* N.B. Shouldn't the size here be PAGE_SIZE?? */
 782                error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
 783                                MAP_FIXED | MAP_PRIVATE, 0);
 784        }
 785
 786#ifdef ELF_PLAT_INIT
 787        /*
 788         * The ABI may specify that certain registers be set up in special
 789         * ways (on i386 %edx is the address of a DT_FINI function, for
 790         * example.  This macro performs whatever initialization to
 791         * the regs structure is required.
 792         */
 793        ELF_PLAT_INIT(regs);
 794#endif
 795
 796        start_thread(regs, elf_entry, bprm->p);
 797        if (current->ptrace & PT_PTRACED)
 798                send_sig(SIGTRAP, current, 0);
 799        retval = 0;
 800out:
 801        return retval;
 802
 803        /* error cleanup */
 804out_free_dentry:
 805        dput(interpreter_dentry);
 806out_free_interp:
 807        if (elf_interpreter)
 808                kfree(elf_interpreter);
 809out_free_file:
 810        fput(file);
 811        sys_close(elf_exec_fileno);
 812out_free_ph:
 813        kfree(elf_phdata);
 814        goto out;
 815}
 816
 817/* This is really simpleminded and specialized - we are loading an
 818   a.out library that is given an ELF header. */
 819
 820static int load_elf_library(struct file *file)
 821{
 822        struct dentry * dentry;
 823        struct inode * inode;
 824        struct elf_phdr *elf_phdata;
 825        unsigned long elf_bss = 0, bss, len, k;
 826        int retval, error, i, j;
 827        struct elfhdr elf_ex;
 828        loff_t offset = 0;
 829
 830        dentry = file->f_dentry;
 831        inode = dentry->d_inode;
 832
 833        /* seek to the beginning of the file */
 834        error = -ENOEXEC;
 835
 836        /* N.B. save current DS?? */
 837        set_fs(KERNEL_DS);
 838        retval = file->f_op->read(file, (char *) &elf_ex, sizeof(elf_ex), &offset);
 839        set_fs(USER_DS);
 840        if (retval != sizeof(elf_ex))
 841                goto out_putf;
 842
 843        if (elf_ex.e_ident[0] != 0x7f ||
 844            strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0)
 845                goto out_putf;
 846
 847        /* First of all, some simple consistency checks */
 848        if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
 849           !elf_check_arch(elf_ex.e_machine) ||
 850           (!inode->i_op || !inode->i_op->default_file_ops->mmap))
 851                goto out_putf;
 852
 853        /* Now read in all of the header information */
 854
 855        j = sizeof(struct elf_phdr) * elf_ex.e_phnum;
 856        if (j > ELF_EXEC_PAGESIZE)
 857                goto out_putf;
 858
 859        error = -ENOMEM;
 860        elf_phdata = (struct elf_phdr *) kmalloc(j, GFP_KERNEL);
 861        if (!elf_phdata)
 862                goto out_putf;
 863
 864        /* N.B. check for error return?? */
 865        retval = read_exec(dentry, elf_ex.e_phoff, (char *) elf_phdata,
 866                           sizeof(struct elf_phdr) * elf_ex.e_phnum, 1);
 867
 868        error = -ENOEXEC;
 869        for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
 870                if ((elf_phdata + i)->p_type == PT_LOAD) j++;
 871        if (j != 1)
 872                goto out_free_ph;
 873
 874        while (elf_phdata->p_type != PT_LOAD) elf_phdata++;
 875
 876        /* Now use mmap to map the library into memory. */
 877        error = do_mmap(file,
 878                        ELF_PAGESTART(elf_phdata->p_vaddr),
 879                        (elf_phdata->p_filesz +
 880                         ELF_PAGEOFFSET(elf_phdata->p_vaddr)),
 881                        PROT_READ | PROT_WRITE | PROT_EXEC,
 882                        MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
 883                        (elf_phdata->p_offset -
 884                         ELF_PAGEOFFSET(elf_phdata->p_vaddr)));
 885        if (error != ELF_PAGESTART(elf_phdata->p_vaddr))
 886                goto out_free_ph;
 887
 888        k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
 889        if (k > elf_bss)
 890                elf_bss = k;
 891        padzero(elf_bss);
 892
 893        len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + 
 894                                ELF_EXEC_PAGESIZE - 1);
 895        bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
 896        if (bss > len)
 897                do_mmap(NULL, len, bss - len,
 898                        PROT_READ|PROT_WRITE|PROT_EXEC,
 899                        MAP_FIXED|MAP_PRIVATE, 0);
 900        error = 0;
 901
 902out_free_ph:
 903        kfree(elf_phdata);
 904out_putf:
 905        return error;
 906}
 907
 908/*
 909 * Note that some platforms still use traditional core dumps and not
 910 * the ELF core dump.  Each platform can select it as appropriate.
 911 */
 912#ifdef USE_ELF_CORE_DUMP
 913
 914/*
 915 * ELF core dumper
 916 *
 917 * Modelled on fs/exec.c:aout_core_dump()
 918 * Jeremy Fitzhardinge <jeremy@sw.oz.au>
 919 */
 920/*
 921 * These are the only things you should do on a core-file: use only these
 922 * functions to write out all the necessary info.
 923 */
 924static int dump_write(struct file *file, const void *addr, int nr)
 925{
 926        int r;
 927        fs_down(&file->f_dentry->d_inode->i_sem);
 928        r = file->f_op->write(file, addr, nr, &file->f_pos) == nr;
 929        fs_up(&file->f_dentry->d_inode->i_sem);
 930        return r;
 931}
 932
 933static int dump_seek(struct file *file, off_t off)
 934{
 935        if (file->f_op->llseek) {
 936                if (file->f_op->llseek(file, off, 0) != off)
 937                        return 0;
 938        } else
 939                file->f_pos = off;
 940        return 1;
 941}
 942
 943/*
 944 * Decide whether a segment is worth dumping; default is yes to be
 945 * sure (missing info is worse than too much; etc).
 946 * Personally I'd include everything, and use the coredump limit...
 947 *
 948 * I think we should skip something. But I am not sure how. H.J.
 949 */
 950static inline int maydump(struct vm_area_struct *vma)
 951{
 952        if (!(vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)))
 953                return 0;
 954
 955        /* Do not dump I/O mapped devices! -DaveM */
 956        if(vma->vm_flags & VM_IO)
 957                return 0;
 958#if 1
 959        if (vma->vm_flags & (VM_WRITE|VM_GROWSUP|VM_GROWSDOWN))
 960                return 1;
 961        if (vma->vm_flags & (VM_READ|VM_EXEC|VM_EXECUTABLE|VM_SHARED))
 962                return 0;
 963#endif
 964        return 1;
 965}
 966
 967#define roundup(x, y)  ((((x)+((y)-1))/(y))*(y))
 968
 969/* An ELF note in memory */
 970struct memelfnote
 971{
 972        const char *name;
 973        int type;
 974        unsigned int datasz;
 975        void *data;
 976};
 977
 978static int notesize(struct memelfnote *en)
 979{
 980        int sz;
 981
 982        sz = sizeof(struct elf_note);
 983        sz += roundup(strlen(en->name), 4);
 984        sz += roundup(en->datasz, 4);
 985
 986        return sz;
 987}
 988
 989/* #define DEBUG */
 990
 991#ifdef DEBUG
 992static void dump_regs(const char *str, elf_greg_t *r)
 993{
 994        int i;
 995        static const char *regs[] = { "ebx", "ecx", "edx", "esi", "edi", "ebp",
 996                                              "eax", "ds", "es", "fs", "gs",
 997                                              "orig_eax", "eip", "cs",
 998                                              "efl", "uesp", "ss"};
 999        printk("Registers: %s\n", str);
1000
1001        for(i = 0; i < ELF_NGREG; i++)
1002        {
1003                unsigned long val = r[i];
1004                printk("   %-2d %-5s=%08lx %lu\n", i, regs[i], val, val);
1005        }
1006}
1007#endif
1008
1009#define DUMP_WRITE(addr, nr)    \
1010        do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
1011#define DUMP_SEEK(off)  \
1012        do { if (!dump_seek(file, (off))) return 0; } while(0)
1013
1014static int writenote(struct memelfnote *men, struct file *file)
1015{
1016        struct elf_note en;
1017
1018        en.n_namesz = strlen(men->name);
1019        en.n_descsz = men->datasz;
1020        en.n_type = men->type;
1021
1022        DUMP_WRITE(&en, sizeof(en));
1023        DUMP_WRITE(men->name, en.n_namesz);
1024        /* XXX - cast from long long to long to avoid need for libgcc.a */
1025        DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));      /* XXX */
1026        DUMP_WRITE(men->data, men->datasz);
1027        DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));      /* XXX */
1028
1029        return 1;
1030}
1031#undef DUMP_WRITE
1032#undef DUMP_SEEK
1033
1034#define DUMP_WRITE(addr, nr)    \
1035        if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
1036                goto close_coredump;
1037#define DUMP_SEEK(off)  \
1038        if (!dump_seek(file, (off))) \
1039                goto close_coredump;
1040/*
1041 * Actual dumper
1042 *
1043 * This is a two-pass process; first we find the offsets of the bits,
1044 * and then they are actually written out.  If we run out of core limit
1045 * we just truncate.
1046 */
1047static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
1048{
1049        int has_dumped = 0;
1050        mm_segment_t fs;
1051        int segs;
1052        int i;
1053        size_t size = 0;
1054        struct vm_area_struct *vma;
1055        struct elfhdr elf;
1056        off_t offset = 0, dataoff;
1057        unsigned long limit = current->rlim[RLIMIT_CORE].rlim_cur;
1058        int numnote = 4;
1059        struct memelfnote notes[4];
1060        struct elf_prstatus prstatus;   /* NT_PRSTATUS */
1061        elf_fpregset_t fpu;             /* NT_PRFPREG */
1062        struct elf_prpsinfo psinfo;     /* NT_PRPSINFO */
1063
1064        segs = current->mm->map_count;
1065
1066#ifdef DEBUG
1067        printk("elf_core_dump: %d segs %lu limit\n", segs, limit);
1068#endif
1069
1070        /* Set up header */
1071        memcpy(elf.e_ident, ELFMAG, SELFMAG);
1072        elf.e_ident[EI_CLASS] = ELF_CLASS;
1073        elf.e_ident[EI_DATA] = ELF_DATA;
1074        elf.e_ident[EI_VERSION] = EV_CURRENT;
1075        memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
1076
1077        elf.e_type = ET_CORE;
1078        elf.e_machine = ELF_ARCH;
1079        elf.e_version = EV_CURRENT;
1080        elf.e_entry = 0;
1081        elf.e_phoff = sizeof(elf);
1082        elf.e_shoff = 0;
1083        elf.e_flags = 0;
1084        elf.e_ehsize = sizeof(elf);
1085        elf.e_phentsize = sizeof(struct elf_phdr);
1086        elf.e_phnum = segs+1;           /* Include notes */
1087        elf.e_shentsize = 0;
1088        elf.e_shnum = 0;
1089        elf.e_shstrndx = 0;
1090
1091        fs = get_fs();
1092        set_fs(KERNEL_DS);
1093
1094        has_dumped = 1;
1095        current->flags |= PF_DUMPCORE;
1096
1097        DUMP_WRITE(&elf, sizeof(elf));
1098        offset += sizeof(elf);                          /* Elf header */
1099        offset += (segs+1) * sizeof(struct elf_phdr);   /* Program headers */
1100
1101        /*
1102         * Set up the notes in similar form to SVR4 core dumps made
1103         * with info from their /proc.
1104         */
1105        memset(&psinfo, 0, sizeof(psinfo));
1106        memset(&prstatus, 0, sizeof(prstatus));
1107
1108        notes[0].name = "CORE";
1109        notes[0].type = NT_PRSTATUS;
1110        notes[0].datasz = sizeof(prstatus);
1111        notes[0].data = &prstatus;
1112        prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
1113        prstatus.pr_sigpend = current->signal.sig[0];
1114        prstatus.pr_sighold = current->blocked.sig[0];
1115        psinfo.pr_pid = prstatus.pr_pid = current->pid;
1116        psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
1117        psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
1118        psinfo.pr_sid = prstatus.pr_sid = current->session;
1119        prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime);
1120        prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime);
1121        prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime);
1122        prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime);
1123        prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
1124        prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime);
1125        prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
1126        prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime);
1127
1128        /*
1129         * This transfers the registers from regs into the standard
1130         * coredump arrangement, whatever that is.
1131         */
1132#ifdef ELF_CORE_COPY_REGS
1133        ELF_CORE_COPY_REGS(prstatus.pr_reg, regs)
1134#else
1135        if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
1136        {
1137                printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n",
1138                        (long)sizeof(elf_gregset_t), (long)sizeof(struct pt_regs));
1139        }
1140        else
1141                *(struct pt_regs *)&prstatus.pr_reg = *regs;
1142#endif
1143
1144#ifdef DEBUG
1145        dump_regs("Passed in regs", (elf_greg_t *)regs);
1146        dump_regs("prstatus regs", (elf_greg_t *)&prstatus.pr_reg);
1147#endif
1148
1149        notes[1].name = "CORE";
1150        notes[1].type = NT_PRPSINFO;
1151        notes[1].datasz = sizeof(psinfo);
1152        notes[1].data = &psinfo;
1153        i = current->state ? ffz(~current->state) + 1 : 0;
1154        psinfo.pr_state = i;
1155        psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];
1156        psinfo.pr_zomb = psinfo.pr_sname == 'Z';
1157        psinfo.pr_nice = current->priority-15;
1158        psinfo.pr_flag = current->flags;
1159        psinfo.pr_uid = current->uid;
1160        psinfo.pr_gid = current->gid;
1161        {
1162                int i, len;
1163
1164                set_fs(fs);
1165
1166                len = current->mm->arg_end - current->mm->arg_start;
1167                if (len < 0 /* overflow */ || len >= ELF_PRARGSZ)
1168                        len = ELF_PRARGSZ-1;
1169                copy_from_user(&psinfo.pr_psargs,
1170                              (const char *)current->mm->arg_start, len);
1171                for(i = 0; i < len; i++)
1172                        if (psinfo.pr_psargs[i] == 0)
1173                                psinfo.pr_psargs[i] = ' ';
1174                psinfo.pr_psargs[len] = 0;
1175
1176                set_fs(KERNEL_DS);
1177        }
1178        strncpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
1179
1180        notes[2].name = "CORE";
1181        notes[2].type = NT_TASKSTRUCT;
1182        notes[2].datasz = sizeof(*current);
1183        notes[2].data = current;
1184
1185        /* Try to dump the FPU. */
1186        prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
1187        if (!prstatus.pr_fpvalid)
1188        {
1189                numnote--;
1190        }
1191        else
1192        {
1193                notes[3].name = "CORE";
1194                notes[3].type = NT_PRFPREG;
1195                notes[3].datasz = sizeof(fpu);
1196                notes[3].data = &fpu;
1197        }
1198        
1199        /* Write notes phdr entry */
1200        {
1201                struct elf_phdr phdr;
1202                int sz = 0;
1203
1204                for(i = 0; i < numnote; i++)
1205                        sz += notesize(&notes[i]);
1206
1207                phdr.p_type = PT_NOTE;
1208                phdr.p_offset = offset;
1209                phdr.p_vaddr = 0;
1210                phdr.p_paddr = 0;
1211                phdr.p_filesz = sz;
1212                phdr.p_memsz = 0;
1213                phdr.p_flags = 0;
1214                phdr.p_align = 0;
1215
1216                offset += phdr.p_filesz;
1217                DUMP_WRITE(&phdr, sizeof(phdr));
1218        }
1219
1220        /* Page-align dumped data */
1221        dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1222
1223        /* Write program headers for segments dump */
1224        for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
1225                struct elf_phdr phdr;
1226                size_t sz;
1227
1228                sz = vma->vm_end - vma->vm_start;
1229
1230                phdr.p_type = PT_LOAD;
1231                phdr.p_offset = offset;
1232                phdr.p_vaddr = vma->vm_start;
1233                phdr.p_paddr = 0;
1234                phdr.p_filesz = maydump(vma) ? sz : 0;
1235                phdr.p_memsz = sz;
1236                offset += phdr.p_filesz;
1237                phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
1238                if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
1239                if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
1240                phdr.p_align = ELF_EXEC_PAGESIZE;
1241
1242                DUMP_WRITE(&phdr, sizeof(phdr));
1243        }
1244
1245        for(i = 0; i < numnote; i++)
1246                if (!writenote(&notes[i], file))
1247                        goto close_coredump;
1248
1249        set_fs(fs);
1250
1251        DUMP_SEEK(dataoff);
1252
1253        for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
1254                unsigned long addr;
1255
1256                if (!maydump(vma))
1257                        continue;
1258#ifdef DEBUG
1259                printk("elf_core_dump: writing %08lx %lx\n", addr, len);
1260#endif
1261                for (addr = vma->vm_start;
1262                     addr < vma->vm_end;
1263                     addr += PAGE_SIZE) {
1264                        pgd_t *pgd;
1265                        pmd_t *pmd;
1266                        pte_t *pte;
1267
1268                        pgd = pgd_offset(vma->vm_mm, addr);
1269                        pmd = pmd_alloc(pgd, addr);
1270        
1271                        if (!pmd)
1272                                goto end_coredump;
1273                        pte = pte_alloc(pmd, addr);
1274                        if (!pte)
1275                                goto end_coredump;
1276                        if (!pte_present(*pte) &&
1277                            pte_none(*pte)) {
1278                                DUMP_SEEK (file->f_pos + PAGE_SIZE);
1279                        } else {
1280                                DUMP_WRITE((void*)addr, PAGE_SIZE);
1281                        }
1282                }
1283        }
1284
1285        if ((off_t) file->f_pos != offset) {
1286                /* Sanity check */
1287                printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
1288                       (off_t) file->f_pos, offset);
1289        }
1290
1291 close_coredump:
1292 end_coredump:
1293        set_fs(fs);
1294        return has_dumped;
1295}
1296#endif          /* USE_ELF_CORE_DUMP */
1297
1298int __init init_elf_binfmt(void)
1299{
1300        return register_binfmt(&elf_format);
1301}
1302
1303#ifdef MODULE
1304
1305int init_module(void)
1306{
1307        /* Install the COFF, ELF and XOUT loaders.
1308         * N.B. We *rely* on the table being the right size with the
1309         * right number of free slots...
1310         */
1311        return init_elf_binfmt();
1312}
1313
1314
1315void cleanup_module( void)
1316{
1317        /* Remove the COFF and ELF loaders. */
1318        unregister_binfmt(&elf_format);
1319}
1320#endif
1321
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.