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

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