root/fs/binfmt_elf.c

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

DEFINITIONS

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

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