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