This source file includes following definitions.
- padzero
- create_elf_tables
- load_elf_interp
- load_aout_interp
- load_elf_binary
- load_elf_library
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
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/sched.h>
22 #include <linux/mm.h>
23 #include <linux/mman.h>
24 #include <linux/a.out.h>
25 #include <linux/errno.h>
26 #include <linux/signal.h>
27 #include <linux/binfmts.h>
28 #include <linux/string.h>
29 #include <linux/fcntl.h>
30 #include <linux/ptrace.h>
31 #include <linux/malloc.h>
32 #include <linux/shm.h>
33 #include <linux/personality.h>
34
35 #include <asm/segment.h>
36 #include <asm/pgtable.h>
37
38 #include <linux/config.h>
39
40 #include <linux/unistd.h>
41 typedef int (*sysfun_p)(int);
42 extern sysfun_p sys_call_table[];
43 #define SYS(name) (sys_call_table[__NR_##name])
44
45 #define DLINFO_ITEMS 8
46
47 #include <linux/elf.h>
48
49 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
50 static int load_elf_library(int fd);
51
52 struct linux_binfmt elf_format = {
53 #ifndef MODULE
54 NULL, NULL, load_elf_binary, load_elf_library, NULL
55 #else
56 NULL, &mod_use_count_, load_elf_binary, load_elf_library, NULL
57 #endif
58 };
59
60
61
62
63
64
65
66 static void padzero(unsigned long elf_bss)
67 {
68 unsigned long fpnt, nbyte;
69
70 nbyte = elf_bss & (PAGE_SIZE-1);
71 if (nbyte) {
72 nbyte = PAGE_SIZE - nbyte;
73 verify_area(VERIFY_WRITE, (void *) elf_bss, nbyte);
74 fpnt = elf_bss;
75 do {
76 put_fs_byte(0, fpnt++);
77 } while (--nbyte);
78 }
79 }
80
81 unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exec, unsigned int load_addr, int ibcs)
82 {
83 unsigned long *argv,*envp, *dlinfo;
84 unsigned long * sp;
85 struct vm_area_struct *mpnt;
86
87 mpnt = (struct vm_area_struct *)kmalloc(sizeof(*mpnt), GFP_KERNEL);
88 if (mpnt) {
89 mpnt->vm_task = current;
90 mpnt->vm_start = PAGE_MASK & (unsigned long) p;
91 mpnt->vm_end = TASK_SIZE;
92 mpnt->vm_page_prot = PAGE_COPY;
93 #ifdef VM_STACK_FLAGS
94 mpnt->vm_flags = VM_STACK_FLAGS;
95 mpnt->vm_pte = 0;
96 #else
97 # ifdef VM_GROWSDOWN
98 mpnt->vm_flags = VM_GROWSDOWN;
99 # endif
100 #endif
101 mpnt->vm_inode = NULL;
102 mpnt->vm_offset = 0;
103 mpnt->vm_ops = NULL;
104 insert_vm_struct(current, mpnt);
105 #ifndef VM_GROWSDOWN
106 current->mm->stk_vma = mpnt;
107 #endif
108
109 }
110 sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
111 if(exec) sp -= DLINFO_ITEMS*2;
112 dlinfo = sp;
113 sp -= envc+1;
114 envp = sp;
115 sp -= argc+1;
116 argv = sp;
117 if (!ibcs) {
118 put_fs_long((unsigned long)envp,--sp);
119 put_fs_long((unsigned long)argv,--sp);
120 }
121
122
123
124
125 if(exec) {
126 struct elf_phdr * eppnt;
127 eppnt = (struct elf_phdr *) exec->e_phoff;
128 put_fs_long(3,dlinfo++); put_fs_long(load_addr + exec->e_phoff,dlinfo++);
129 put_fs_long(4,dlinfo++); put_fs_long(sizeof(struct elf_phdr),dlinfo++);
130 put_fs_long(5,dlinfo++); put_fs_long(exec->e_phnum,dlinfo++);
131 put_fs_long(9,dlinfo++); put_fs_long((unsigned long) exec->e_entry,dlinfo++);
132 put_fs_long(7,dlinfo++); put_fs_long(SHM_RANGE_START,dlinfo++);
133 put_fs_long(8,dlinfo++); put_fs_long(0,dlinfo++);
134 put_fs_long(6,dlinfo++); put_fs_long(PAGE_SIZE,dlinfo++);
135 put_fs_long(0,dlinfo++); put_fs_long(0,dlinfo++);
136 };
137
138 put_fs_long((unsigned long)argc,--sp);
139 current->mm->arg_start = (unsigned long) p;
140 while (argc-->0) {
141 put_fs_long((unsigned long) p,argv++);
142 while (get_fs_byte(p++)) ;
143 }
144 put_fs_long(0,argv);
145 current->mm->arg_end = current->mm->env_start = (unsigned long) p;
146 while (envc-->0) {
147 put_fs_long((unsigned long) p,envp++);
148 while (get_fs_byte(p++)) ;
149 }
150 put_fs_long(0,envp);
151 current->mm->env_end = (unsigned long) p;
152 return sp;
153 }
154
155
156
157
158
159
160
161 static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
162 struct inode * interpreter_inode)
163 {
164 struct file * file;
165 struct elf_phdr *elf_phdata = NULL;
166 struct elf_phdr *eppnt;
167 unsigned int len;
168 unsigned int load_addr;
169 int elf_exec_fileno;
170 int elf_bss;
171 int old_fs, retval;
172 unsigned int last_bss;
173 int error;
174 int i, k;
175
176 elf_bss = 0;
177 last_bss = 0;
178 error = load_addr = 0;
179
180
181 if((interp_elf_ex->e_type != ET_EXEC &&
182 interp_elf_ex->e_type != ET_DYN) ||
183 (interp_elf_ex->e_machine != EM_386 && interp_elf_ex->e_machine != EM_486) ||
184 (!interpreter_inode->i_op ||
185 !interpreter_inode->i_op->default_file_ops->mmap)){
186 return 0xffffffff;
187 };
188
189
190
191 if(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE)
192 return 0xffffffff;
193
194 elf_phdata = (struct elf_phdr *)
195 kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, GFP_KERNEL);
196 if(!elf_phdata) return 0xffffffff;
197
198 old_fs = get_fs();
199 set_fs(get_ds());
200 retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff, (char *) elf_phdata,
201 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
202 set_fs(old_fs);
203
204 elf_exec_fileno = open_inode(interpreter_inode, O_RDONLY);
205 if (elf_exec_fileno < 0) return 0xffffffff;
206 file = current->files->fd[elf_exec_fileno];
207
208 eppnt = elf_phdata;
209 for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
210 if(eppnt->p_type == PT_LOAD) {
211 error = do_mmap(file,
212 eppnt->p_vaddr & 0xfffff000,
213 eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
214 PROT_READ | PROT_WRITE | PROT_EXEC,
215 MAP_PRIVATE | MAP_DENYWRITE | (interp_elf_ex->e_type == ET_EXEC ? MAP_FIXED : 0),
216 eppnt->p_offset & 0xfffff000);
217
218 if(!load_addr && interp_elf_ex->e_type == ET_DYN)
219 load_addr = error;
220 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
221 if(k > elf_bss) elf_bss = k;
222 if(error < 0 && error > -1024) break;
223 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
224 if(k > last_bss) last_bss = k;
225 }
226
227
228
229
230 SYS(close)(elf_exec_fileno);
231 if(error < 0 && error > -1024) {
232 kfree(elf_phdata);
233 return 0xffffffff;
234 }
235
236 padzero(elf_bss);
237 len = (elf_bss + 0xfff) & 0xfffff000;
238
239
240 if (last_bss > len)
241 do_mmap(NULL, len, last_bss-len,
242 PROT_READ|PROT_WRITE|PROT_EXEC,
243 MAP_FIXED|MAP_PRIVATE, 0);
244 kfree(elf_phdata);
245
246 return ((unsigned int) interp_elf_ex->e_entry) + load_addr;
247 }
248
249 static unsigned int load_aout_interp(struct exec * interp_ex,
250 struct inode * interpreter_inode)
251 {
252 int retval;
253 unsigned int elf_entry;
254
255 current->mm->brk = interp_ex->a_bss +
256 (current->mm->end_data = interp_ex->a_data +
257 (current->mm->end_code = interp_ex->a_text));
258 elf_entry = interp_ex->a_entry;
259
260
261 if (N_MAGIC(*interp_ex) == OMAGIC) {
262 do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data,
263 PROT_READ|PROT_WRITE|PROT_EXEC,
264 MAP_FIXED|MAP_PRIVATE, 0);
265 retval = read_exec(interpreter_inode, 32, (char *) 0,
266 interp_ex->a_text+interp_ex->a_data);
267 } else if (N_MAGIC(*interp_ex) == ZMAGIC || N_MAGIC(*interp_ex) == QMAGIC) {
268 do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data,
269 PROT_READ|PROT_WRITE|PROT_EXEC,
270 MAP_FIXED|MAP_PRIVATE, 0);
271 retval = read_exec(interpreter_inode,
272 N_TXTOFF(*interp_ex) ,
273 (char *) N_TXTADDR(*interp_ex),
274 interp_ex->a_text+interp_ex->a_data);
275 } else
276 retval = -1;
277
278 if(retval >= 0)
279 do_mmap(NULL, (interp_ex->a_text + interp_ex->a_data + 0xfff) &
280 0xfffff000, interp_ex->a_bss,
281 PROT_READ|PROT_WRITE|PROT_EXEC,
282 MAP_FIXED|MAP_PRIVATE, 0);
283 if(retval < 0) return 0xffffffff;
284 return elf_entry;
285 }
286
287
288
289
290
291
292 #define INTERPRETER_NONE 0
293 #define INTERPRETER_AOUT 1
294 #define INTERPRETER_ELF 2
295
296
297 static int
298 load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
299 {
300 struct elfhdr elf_ex;
301 struct elfhdr interp_elf_ex;
302 struct file * file;
303 struct exec interp_ex;
304 struct inode *interpreter_inode;
305 unsigned int load_addr;
306 unsigned int interpreter_type = INTERPRETER_NONE;
307 unsigned char ibcs2_interpreter;
308 int i;
309 int old_fs;
310 int error;
311 struct elf_phdr * elf_ppnt, *elf_phdata;
312 int elf_exec_fileno;
313 unsigned int elf_bss, k, elf_brk;
314 int retval;
315 char * elf_interpreter;
316 unsigned int elf_entry;
317 int status;
318 unsigned int start_code, end_code, end_data;
319 unsigned int elf_stack;
320 char passed_fileno[6];
321
322 MOD_INC_USE_COUNT;
323
324 ibcs2_interpreter = 0;
325 status = 0;
326 load_addr = 0;
327 elf_ex = *((struct elfhdr *) bprm->buf);
328
329 if (elf_ex.e_ident[0] != 0x7f ||
330 strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
331 MOD_DEC_USE_COUNT;
332 return -ENOEXEC;
333 }
334
335
336
337 if(elf_ex.e_type != ET_EXEC ||
338 (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
339 (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
340 !bprm->inode->i_op->default_file_ops->mmap)){
341 MOD_DEC_USE_COUNT;
342 return -ENOEXEC;
343 };
344
345
346
347 elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize *
348 elf_ex.e_phnum, GFP_KERNEL);
349
350 old_fs = get_fs();
351 set_fs(get_ds());
352 retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata,
353 elf_ex.e_phentsize * elf_ex.e_phnum);
354 set_fs(old_fs);
355 if (retval < 0) {
356 kfree (elf_phdata);
357 MOD_DEC_USE_COUNT;
358 return retval;
359 }
360
361 elf_ppnt = elf_phdata;
362
363 elf_bss = 0;
364 elf_brk = 0;
365
366 elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
367
368 if (elf_exec_fileno < 0) {
369 kfree (elf_phdata);
370 MOD_DEC_USE_COUNT;
371 return elf_exec_fileno;
372 }
373
374 file = current->files->fd[elf_exec_fileno];
375
376 elf_stack = 0xffffffff;
377 elf_interpreter = NULL;
378 start_code = 0;
379 end_code = 0;
380 end_data = 0;
381
382 old_fs = get_fs();
383 set_fs(get_ds());
384
385 for(i=0;i < elf_ex.e_phnum; i++){
386 if(elf_ppnt->p_type == PT_INTERP) {
387
388
389
390 elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
391 GFP_KERNEL);
392
393 retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter,
394 elf_ppnt->p_filesz);
395
396
397
398 if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
399 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0)
400 ibcs2_interpreter = 1;
401 #if 0
402 printk("Using ELF interpreter %s\n", elf_interpreter);
403 #endif
404 if(retval >= 0)
405 retval = namei(elf_interpreter, &interpreter_inode);
406 if(retval >= 0)
407 retval = read_exec(interpreter_inode,0,bprm->buf,128);
408
409 if(retval >= 0){
410 interp_ex = *((struct exec *) bprm->buf);
411 interp_elf_ex = *((struct elfhdr *) bprm->buf);
412
413 };
414 if(retval < 0) {
415 kfree (elf_phdata);
416 kfree(elf_interpreter);
417 MOD_DEC_USE_COUNT;
418 return retval;
419 };
420 };
421 elf_ppnt++;
422 };
423
424 set_fs(old_fs);
425
426
427 if(elf_interpreter){
428 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
429 if(retval < 0) {
430 kfree(elf_interpreter);
431 kfree(elf_phdata);
432 MOD_DEC_USE_COUNT;
433 return -ELIBACC;
434 };
435
436 if((N_MAGIC(interp_ex) != OMAGIC) &&
437 (N_MAGIC(interp_ex) != ZMAGIC) &&
438 (N_MAGIC(interp_ex) != QMAGIC))
439 interpreter_type = INTERPRETER_ELF;
440
441 if (interp_elf_ex.e_ident[0] != 0x7f ||
442 strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0)
443 interpreter_type &= ~INTERPRETER_ELF;
444
445 if(!interpreter_type)
446 {
447 kfree(elf_interpreter);
448 kfree(elf_phdata);
449 MOD_DEC_USE_COUNT;
450 return -ELIBBAD;
451 };
452 }
453
454
455
456
457 if (!bprm->sh_bang) {
458 char * passed_p;
459
460 if(interpreter_type == INTERPRETER_AOUT) {
461 sprintf(passed_fileno, "%d", elf_exec_fileno);
462 passed_p = passed_fileno;
463
464 if(elf_interpreter) {
465 bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
466 bprm->argc++;
467 };
468 };
469 if (!bprm->p) {
470 if(elf_interpreter) {
471 kfree(elf_interpreter);
472 }
473 kfree (elf_phdata);
474 MOD_DEC_USE_COUNT;
475 return -E2BIG;
476 }
477 }
478
479
480 flush_old_exec(bprm);
481
482 current->mm->end_data = 0;
483 current->mm->end_code = 0;
484 current->mm->start_mmap = ELF_START_MMAP;
485 current->mm->mmap = NULL;
486 elf_entry = (unsigned int) elf_ex.e_entry;
487
488
489
490 current->mm->rss = 0;
491 bprm->p += setup_arg_pages(0, bprm->page);
492 current->mm->start_stack = bprm->p;
493
494
495
496
497
498
499 old_fs = get_fs();
500 set_fs(get_ds());
501
502 elf_ppnt = elf_phdata;
503 for(i=0;i < elf_ex.e_phnum; i++){
504
505 if(elf_ppnt->p_type == PT_INTERP) {
506
507
508 set_fs(old_fs);
509
510 if(interpreter_type & 1) elf_entry =
511 load_aout_interp(&interp_ex, interpreter_inode);
512
513 if(interpreter_type & 2) elf_entry =
514 load_elf_interp(&interp_elf_ex, interpreter_inode);
515
516 old_fs = get_fs();
517 set_fs(get_ds());
518
519 iput(interpreter_inode);
520 kfree(elf_interpreter);
521
522 if(elf_entry == 0xffffffff) {
523 printk("Unable to load interpreter\n");
524 kfree(elf_phdata);
525 send_sig(SIGSEGV, current, 0);
526 MOD_DEC_USE_COUNT;
527 return 0;
528 };
529 };
530
531
532 if(elf_ppnt->p_type == PT_LOAD) {
533 error = do_mmap(file,
534 elf_ppnt->p_vaddr & 0xfffff000,
535 elf_ppnt->p_filesz + (elf_ppnt->p_vaddr & 0xfff),
536 PROT_READ | PROT_WRITE | PROT_EXEC,
537 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
538 elf_ppnt->p_offset & 0xfffff000);
539
540 #ifdef LOW_ELF_STACK
541 if(elf_ppnt->p_vaddr & 0xfffff000 < elf_stack)
542 elf_stack = elf_ppnt->p_vaddr & 0xfffff000;
543 #endif
544
545 if(!load_addr)
546 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
547 k = elf_ppnt->p_vaddr;
548 if(k > start_code) start_code = k;
549 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
550 if(k > elf_bss) elf_bss = k;
551 if((elf_ppnt->p_flags | PROT_WRITE) && end_code < k)
552 end_code = k;
553 if(end_data < k) end_data = k;
554 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
555 if(k > elf_brk) elf_brk = k;
556 };
557 elf_ppnt++;
558 };
559 set_fs(old_fs);
560
561 kfree(elf_phdata);
562
563 if(interpreter_type != INTERPRETER_AOUT) SYS(close)(elf_exec_fileno);
564 current->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
565
566 if (current->exec_domain && current->exec_domain->use_count)
567 (*current->exec_domain->use_count)--;
568 if (current->binfmt && current->binfmt->use_count)
569 (*current->binfmt->use_count)--;
570 current->exec_domain = lookup_exec_domain(current->personality);
571 current->binfmt = &elf_format;
572 if (current->exec_domain && current->exec_domain->use_count)
573 (*current->exec_domain->use_count)++;
574 if (current->binfmt && current->binfmt->use_count)
575 (*current->binfmt->use_count)++;
576
577 #ifndef VM_STACK_FLAGS
578 current->executable = bprm->inode;
579 bprm->inode->i_count++;
580 #endif
581 #ifdef LOW_ELF_STACK
582 current->start_stack = p = elf_stack - 4;
583 #endif
584 bprm->p -= MAX_ARG_PAGES*PAGE_SIZE;
585 bprm->p = (unsigned long)
586 create_elf_tables((char *)bprm->p,
587 bprm->argc,
588 bprm->envc,
589 (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
590 load_addr,
591 (interpreter_type == INTERPRETER_AOUT ? 0 : 1));
592 if(interpreter_type == INTERPRETER_AOUT)
593 current->mm->arg_start += strlen(passed_fileno) + 1;
594 current->mm->start_brk = current->mm->brk = elf_brk;
595 current->mm->end_code = end_code;
596 current->mm->start_code = start_code;
597 current->mm->end_data = end_data;
598 current->mm->start_stack = bprm->p;
599 current->suid = current->euid = current->fsuid = bprm->e_uid;
600 current->sgid = current->egid = current->fsgid = bprm->e_gid;
601
602
603
604 current->mm->brk = (elf_bss + 0xfff) & 0xfffff000;
605 SYS(brk)((elf_brk + 0xfff) & 0xfffff000);
606
607 padzero(elf_bss);
608
609 #if 0
610 printk("(start_brk) %x\n" , current->mm->start_brk);
611 printk("(end_code) %x\n" , current->mm->end_code);
612 printk("(start_code) %x\n" , current->mm->start_code);
613 printk("(end_data) %x\n" , current->mm->end_data);
614 printk("(start_stack) %x\n" , current->mm->start_stack);
615 printk("(brk) %x\n" , current->mm->brk);
616 #endif
617
618
619
620
621
622 error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
623 MAP_FIXED | MAP_PRIVATE, 0);
624
625 start_thread(regs, elf_entry, bprm->p);
626 if (current->flags & PF_PTRACED)
627 send_sig(SIGTRAP, current, 0);
628 MOD_DEC_USE_COUNT;
629 return 0;
630 }
631
632
633
634
635 static int
636 load_elf_library(int fd){
637 struct file * file;
638 struct elfhdr elf_ex;
639 struct elf_phdr *elf_phdata = NULL;
640 struct inode * inode;
641 unsigned int len;
642 int elf_bss;
643 int old_fs, retval;
644 unsigned int bss;
645 int error;
646 int i,j, k;
647
648 MOD_INC_USE_COUNT;
649 len = 0;
650 file = current->files->fd[fd];
651 inode = file->f_inode;
652 elf_bss = 0;
653
654 set_fs(KERNEL_DS);
655 if (file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) {
656 SYS(close)(fd);
657 MOD_DEC_USE_COUNT;
658 return -EACCES;
659 }
660 set_fs(USER_DS);
661
662 if (elf_ex.e_ident[0] != 0x7f ||
663 strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
664 MOD_DEC_USE_COUNT;
665 return -ENOEXEC;
666 }
667
668
669 if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
670 (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
671 (!inode->i_op || !inode->i_op->default_file_ops->mmap)){
672 MOD_DEC_USE_COUNT;
673 return -ENOEXEC;
674 };
675
676
677
678 if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) {
679 MOD_DEC_USE_COUNT;
680 return -ENOEXEC;
681 }
682
683 elf_phdata = (struct elf_phdr *)
684 kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
685
686 old_fs = get_fs();
687 set_fs(get_ds());
688 retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata,
689 sizeof(struct elf_phdr) * elf_ex.e_phnum);
690 set_fs(old_fs);
691
692 j = 0;
693 for(i=0; i<elf_ex.e_phnum; i++)
694 if((elf_phdata + i)->p_type == PT_LOAD) j++;
695
696 if(j != 1) {
697 kfree(elf_phdata);
698 MOD_DEC_USE_COUNT;
699 return -ENOEXEC;
700 };
701
702 while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
703
704
705 error = do_mmap(file,
706 elf_phdata->p_vaddr & 0xfffff000,
707 elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
708 PROT_READ | PROT_WRITE | PROT_EXEC,
709 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
710 elf_phdata->p_offset & 0xfffff000);
711
712 k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
713 if(k > elf_bss) elf_bss = k;
714
715 SYS(close)(fd);
716 if (error != elf_phdata->p_vaddr & 0xfffff000) {
717 kfree(elf_phdata);
718 MOD_DEC_USE_COUNT;
719 return error;
720 }
721
722 padzero(elf_bss);
723
724 len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
725 bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
726 if (bss > len)
727 do_mmap(NULL, len, bss-len,
728 PROT_READ|PROT_WRITE|PROT_EXEC,
729 MAP_FIXED|MAP_PRIVATE, 0);
730 kfree(elf_phdata);
731 MOD_DEC_USE_COUNT;
732 return 0;
733 }
734
735 #ifdef MODULE
736 char kernel_version[] = UTS_RELEASE;
737
738 int init_module(void) {
739
740
741
742
743 register_binfmt(&elf_format);
744 return 0;
745 }
746
747 void cleanup_module( void) {
748
749 if (MOD_IN_USE)
750 printk(KERN_INFO "iBCS: module is in use, remove delayed\n");
751
752
753 unregister_binfmt(&elf_format);
754 }
755 #endif