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

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