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                 int sz = vma->vm_end-vma->vm_start;
 968                 
 969                 if (!maydump(vma))
 970                         continue;
 971 
 972                 if (size+sz > limit)
 973                         break;
 974                 
 975                 segs++;
 976                 size += sz;
 977         }
 978 #ifdef DEBUG
 979         printk("elf_core_dump: %d segs taking %d bytes\n", segs, size);
 980 #endif
 981 
 982         /* Set up header */
 983         memcpy(elf.e_ident, ELFMAG, SELFMAG);
 984         elf.e_ident[EI_CLASS] = ELFCLASS32;
 985         elf.e_ident[EI_DATA] = ELFDATA2LSB;
 986         elf.e_ident[EI_VERSION] = EV_CURRENT;
 987         memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
 988         
 989         elf.e_type = ET_CORE;
 990         elf.e_machine = EM_386;
 991         elf.e_version = EV_CURRENT;
 992         elf.e_entry = 0;
 993         elf.e_phoff = sizeof(elf);
 994         elf.e_shoff = 0;
 995         elf.e_flags = 0;
 996         elf.e_ehsize = sizeof(elf);
 997         elf.e_phentsize = sizeof(struct elf_phdr);
 998         elf.e_phnum = segs+1;           /* Include notes */
 999         elf.e_shentsize = 0;
1000         elf.e_shnum = 0;
1001         elf.e_shstrndx = 0;
1002         
1003         fs = get_fs();
1004         set_fs(KERNEL_DS);
1005         memcpy(corefile,"core.",5);
1006 #if 0
1007         memcpy(corefile+5,current->comm,sizeof(current->comm));
1008 #else
1009         corefile[4] = '\0';
1010 #endif
1011         if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) {
1012                 inode = NULL;
1013                 goto end_coredump;
1014         }
1015         if (!S_ISREG(inode->i_mode))
1016                 goto end_coredump;
1017         if (!inode->i_op || !inode->i_op->default_file_ops)
1018                 goto end_coredump;
1019         file.f_mode = 3;
1020         file.f_flags = 0;
1021         file.f_count = 1;
1022         file.f_inode = inode;
1023         file.f_pos = 0;
1024         file.f_reada = 0;
1025         file.f_op = inode->i_op->default_file_ops;
1026         if (file.f_op->open)
1027                 if (file.f_op->open(inode,&file))
1028                         goto end_coredump;
1029         if (!file.f_op->write)
1030                 goto close_coredump;
1031         has_dumped = 1;
1032         current->flags |= PF_DUMPCORE;
1033 
1034         DUMP_WRITE(&elf, sizeof(elf));
1035         offset += sizeof(elf);                          /* Elf header */
1036         offset += (segs+1) * sizeof(struct elf_phdr);   /* Program headers */
1037 
1038         /*
1039          * Set up the notes in similar form to SVR4 core dumps made
1040          * with info from their /proc.
1041          */
1042         memset(&psinfo, 0, sizeof(psinfo));
1043         memset(&prstatus, 0, sizeof(prstatus));
1044 
1045         notes[0].name = "CORE";
1046         notes[0].type = NT_PRSTATUS;
1047         notes[0].datasz = sizeof(prstatus);
1048         notes[0].data = &prstatus;
1049         prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
1050         prstatus.pr_sigpend = current->signal;
1051         prstatus.pr_sighold = current->blocked;
1052         psinfo.pr_pid = prstatus.pr_pid = current->pid;
1053         psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
1054         psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
1055         psinfo.pr_sid = prstatus.pr_sid = current->session;
1056         prstatus.pr_utime.tv_sec = CT_TO_SECS(current->utime);
1057         prstatus.pr_utime.tv_usec = CT_TO_USECS(current->utime);
1058         prstatus.pr_stime.tv_sec = CT_TO_SECS(current->stime);
1059         prstatus.pr_stime.tv_usec = CT_TO_USECS(current->stime);
1060         prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->cutime);
1061         prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->cutime);
1062         prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->cstime);
1063         prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->cstime);
1064         if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
1065         {
1066                 printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) (%d)\n",
1067                         sizeof(elf_gregset_t), sizeof(struct pt_regs));
1068         }
1069         else
1070                 *(struct pt_regs *)&prstatus.pr_reg = *regs;
1071         
1072 #ifdef DEBUG
1073         dump_regs("Passed in regs", (elf_greg_t *)regs);
1074         dump_regs("prstatus regs", (elf_greg_t *)&prstatus.pr_reg);
1075 #endif
1076 
1077         notes[1].name = "CORE";
1078         notes[1].type = NT_PRPSINFO;
1079         notes[1].datasz = sizeof(psinfo);
1080         notes[1].data = &psinfo;
1081         psinfo.pr_state = current->state;
1082         psinfo.pr_sname = (current->state < 0 || current->state > 5) ? '.' : "RSDZTD"[current->state];
1083         psinfo.pr_zomb = psinfo.pr_sname == 'Z';
1084         psinfo.pr_nice = current->priority-15;
1085         psinfo.pr_flag = current->flags;
1086         psinfo.pr_uid = current->uid;
1087         psinfo.pr_gid = current->gid;
1088         {
1089                 int i, len;
1090 
1091                 set_fs(fs);
1092                 
1093                 len = current->mm->arg_end - current->mm->arg_start;
1094                 len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
1095                 memcpy_fromfs(&psinfo.pr_psargs,
1096                               (const char *)current->mm->arg_start, len);
1097                 for(i = 0; i < len; i++)
1098                         if (psinfo.pr_psargs[i] == 0)
1099                                 psinfo.pr_psargs[i] = ' ';
1100                 psinfo.pr_psargs[len] = 0;
1101 
1102                 set_fs(KERNEL_DS);
1103         }
1104         strncpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
1105 
1106         notes[2].name = "CORE";
1107         notes[2].type = NT_TASKSTRUCT;
1108         notes[2].datasz = sizeof(*current);
1109         notes[2].data = current;
1110         
1111         /* Try to dump the fpu. */
1112         prstatus.pr_fpvalid = dump_fpu (&fpu);
1113         if (!prstatus.pr_fpvalid)
1114         {
1115                 numnote--;
1116         }
1117         else
1118         {
1119                 notes[3].name = "CORE";
1120                 notes[3].type = NT_PRFPREG;
1121                 notes[3].datasz = sizeof(fpu);
1122                 notes[3].data = &fpu;
1123         }
1124         
1125         /* Write notes phdr entry */
1126         {
1127                 struct elf_phdr phdr;
1128                 int sz = 0;
1129 
1130                 for(i = 0; i < numnote; i++)
1131                         sz += notesize(&notes[i]);
1132                 
1133                 phdr.p_type = PT_NOTE;
1134                 phdr.p_offset = offset;
1135                 phdr.p_vaddr = 0;
1136                 phdr.p_paddr = 0;
1137                 phdr.p_filesz = sz;
1138                 phdr.p_memsz = 0;
1139                 phdr.p_flags = 0;
1140                 phdr.p_align = 0;
1141 
1142                 offset += phdr.p_filesz;
1143                 DUMP_WRITE(&phdr, sizeof(phdr));
1144         }
1145 
1146         /* Page-align dumped data */
1147         dataoff = offset = roundup(offset, PAGE_SIZE);
1148         
1149         /* Write program headers for segments dump */
1150         for(vma = current->mm->mmap, i = 0;
1151                 i < segs && vma != NULL; vma = vma->vm_next) {
1152                 struct elf_phdr phdr;
1153                 size_t sz;
1154 
1155                 if (!maydump(vma))
1156                         continue;
1157                 i++;
1158 
1159                 sz = vma->vm_end - vma->vm_start;
1160                 
1161                 phdr.p_type = PT_LOAD;
1162                 phdr.p_offset = offset;
1163                 phdr.p_vaddr = vma->vm_start;
1164                 phdr.p_paddr = 0;
1165                 phdr.p_filesz = sz;
1166                 phdr.p_memsz = sz;
1167                 offset += sz;
1168                 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
1169                 if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
1170                 if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
1171                 phdr.p_align = PAGE_SIZE;
1172 
1173                 DUMP_WRITE(&phdr, sizeof(phdr));
1174         }
1175 
1176         for(i = 0; i < numnote; i++)
1177                 if (!writenote(&notes[i], &file))
1178                         goto close_coredump;
1179         
1180         set_fs(fs);
1181 
1182         DUMP_SEEK(dataoff);
1183         
1184         for(i = 0, vma = current->mm->mmap;
1185             i < segs && vma != NULL;
1186             vma = vma->vm_next) {
1187                 unsigned long addr = vma->vm_start;
1188                 unsigned long len = vma->vm_end - vma->vm_start;
1189                 
1190                 if (!maydump(vma))
1191                         continue;
1192                 i++;
1193 #ifdef DEBUG
1194                 printk("elf_core_dump: writing %08lx %lx\n", addr, len);
1195 #endif
1196                 DUMP_WRITE((void *)addr, len);
1197         }
1198 
1199         if ((off_t) file.f_pos != offset) {
1200                 /* Sanity check */
1201                 printk("elf_core_dump: file.f_pos (%ld) != offset (%ld)\n",
1202                        (off_t) file.f_pos, offset);
1203         }
1204 
1205  close_coredump:
1206         if (file.f_op->release)
1207                 file.f_op->release(inode,&file);
1208 
1209  end_coredump:
1210         set_fs(fs);
1211         iput(inode);
1212 #ifndef CONFIG_BINFMT_ELF
1213         MOD_DEC_USE_COUNT;
1214 #endif
1215         return has_dumped;
1216 }
1217 
1218 int init_elf_binfmt(void) {
     /* [previous][next][first][last][top][bottom][index][help] */
1219         return register_binfmt(&elf_format);
1220 }
1221 
1222 #ifdef MODULE
1223 
1224 int init_module(void) {
     /* [previous][next][first][last][top][bottom][index][help] */
1225         /* Install the COFF, ELF and XOUT loaders.
1226          * N.B. We *rely* on the table being the right size with the
1227          * right number of free slots...
1228          */
1229         return init_elf_binfmt();
1230 }
1231 
1232 
1233 void cleanup_module( void) {
     /* [previous][next][first][last][top][bottom][index][help] */
1234         /* Remove the COFF and ELF loaders. */
1235         unregister_binfmt(&elf_format);
1236 }
1237 #endif

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