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

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