root/fs/binfmt_elf.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_brk
  2. padzero
  3. create_elf_tables
  4. load_elf_interp
  5. load_aout_interp
  6. do_load_elf_binary
  7. load_elf_binary
  8. do_load_elf_library
  9. load_elf_library
  10. dump_write
  11. dump_seek
  12. maydump
  13. notesize
  14. dump_regs
  15. writenote
  16. elf_core_dump
  17. init_elf_binfmt
  18. init_module
  19. cleanup_module

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

/* [previous][next][first][last][top][bottom][index][help] */