1 /* 2 * These are the functions used to load COFF IBSC style executables. 3 * Information on COFF format may be obtained in either the Intel Binary 4 * Compatibility Specification 2 or O'Rilley's book on COFF. The shared 5 * libraries are defined only the in the Intel book. 6 * 7 * This file is based upon code written by Eric Youndale for the ELF object 8 * file format. 9 * 10 * Revision information: 11 * 28 August 1993 12 * Al Longyear (longyear@sii.com) 13 * initial release to alpha level testing. This version does not load 14 * shared libraries, but will identify them and log the file names. 15 * 16 * 4 September 1993 17 * Al Longyear (longyear@sii.com) 18 * Added support for shared libraries. 19 * 20 * 9 September 1993 21 * Al Longyear (longyear@sii.com) 22 * Load the FS register with the proper value prior to the call to 23 * sys_uselib(). 24 * 25 * Built the parameter and envionment strings before destroying the 26 * current executable. 27 * 28 * 10 September 1993 29 * Al Longyear (longyear@sii.com) 30 * Added new parameter to the create_tables() function to allow the 31 * proper creation of the IBCS environment stack when the process is 32 * started. 33 * 34 * Added code to create_tables() which I mistakenly deleted in the 35 * last patch. 36 * 37 * 13 September 1993 38 * Al Longyear (longyear@sii.com) 39 * Removed erroneous code which mistakenly folded .data with .bss for 40 * a shared library. 41 * 42 * 8 Janurary 1994 43 * Al Longyear (longyear@sii.com) 44 * Corrected problem with read of library section returning the byte 45 * count rather than zero. This was a change between the pl12 and 46 * pl14 kernels which slipped by me. 47 */ 48
49 #include <linux/fs.h>
50 #include <linux/sched.h>
51 #include <linux/mm.h>
52 #include <linux/mman.h>
53 #include <linux/a.out.h>
54 #include <linux/errno.h>
55 #include <linux/signal.h>
56 #include <linux/binfmts.h>
57 #include <asm/segment.h>
58 #include <linux/string.h>
59 #include <linux/fcntl.h>
60 #include <linux/ptrace.h>
61 #include <linux/coff.h>
62 #include <linux/malloc.h>
63
64 asmlinkageintsys_exit (intexit_code);
65 asmlinkageintsys_close (unsignedfd);
66 asmlinkageintsys_open (constchar *, int, int);
67 asmlinkageintsys_uselib(constchar * library);
68
69 staticintpreload_library (structlinux_binprm *exe_bprm,
70 COFF_SCNHDR * sect,
71 structfile *fp);
72
73 staticintload_object (structlinux_binprm *bprm,
74 structpt_regs *regs,
75 intlib_ok);
76
77 /* 78 * Small procedure to test for the proper file alignment. 79 */ 80
81 staticinlineint 82 is_properly_aligned (COFF_SCNHDR *sect)
/* */ 83 { 84 longscnptr = COFF_LONG (sect->s_scnptr);
85 longvaddr = COFF_LONG (sect->s_vaddr);
86 /* 87 * Print the section information if needed 88 */ 89
90 #ifdefCOFF_DEBUG 91 printk ("%s, scnptr = %d, vaddr = %d\n",
92 sect->s_name,
93 scnptr, vaddr);
94 #endif 95
96 /* 97 * Return the error code if the section is not properly aligned. 98 */ 99
100 #ifdefCOFF_DEBUG 101 if (((vaddr - scnptr) & ~PAGE_MASK) != 0)
102 printk ("bad alignment in %s\n", sect->s_name);
103 #endif 104 return ((((vaddr - scnptr) & ~PAGE_MASK) != 0) ? -ENOEXEC : 0);
105 } 106
107 /* 108 * Helper function to process the load operation. 109 */ 110
111 staticint 112 load_object (structlinux_binprm * bprm, structpt_regs *regs, intlib_ok)
/* */ 113 { 114 COFF_FILHDR *coff_hdr = (COFF_FILHDR *) bprm->buf; /* COFF Header */ 115 COFF_SCNHDR *sect_bufr; /* Pointer to section table */ 116 COFF_SCNHDR *text_sect; /* Pointer to the text section */ 117 COFF_SCNHDR *data_sect; /* Pointer to the data section */ 118 COFF_SCNHDR *bss_sect; /* Pointer to the bss section */ 119 inttext_count; /* Number of text sections */ 120 intdata_count; /* Number of data sections */ 121 intbss_count; /* Number of bss sections */ 122 intlib_count; /* Number of lib sections */ 123 unsignedintstart_addr = 0;/* Starting location for program */ 124 intstatus = 0; /* Result status register */ 125 intfd = -1; /* Open file descriptor */ 126 structfile *fp = NULL; /* Pointer to the file at "fd" */ 127 shortintsections = 0; /* Number of sections in the file */ 128 shortintaout_size = 0; /* Size of the a.out header area */ 129 shortintflags; /* Flag bits from the COFF header */ 130
131 #ifdefCOFF_DEBUG 132 printk ("binfmt_coff entry: %s\n", bprm->filename);
133 #endif 134
135 /* 136 * Validate the magic value for the object file. 137 */ 138 do{ 139 if (COFF_I386BADMAG (*coff_hdr)) { 140 #ifdefCOFF_DEBUG 141 printk ("bad filehdr magic\n");
142 #endif 143 status = -ENOEXEC;
144 break;
145 } 146 /* 147 * The object file should have 32 BIT little endian format. Do not allow 148 * it to have the 16 bit object file flag set as Linux is not able to run 149 * on the 80286/80186/8086. 150 */ 151 flags = COFF_SHORT (coff_hdr->f_flags);
152 if ((flags & (COFF_F_AR32WR | COFF_F_AR16WR)) != COFF_F_AR32WR) { 153 #ifdefCOFF_DEBUG 154 printk ("invalid f_flags bits\n");
155 #endif 156 status = -ENOEXEC;
157 break;
158 } 159 /* 160 * Extract the header information which we need. 161 */ 162 sections = COFF_SHORT (coff_hdr->f_nscns); /* Number of sections */ 163 aout_size = COFF_SHORT (coff_hdr->f_opthdr); /* Size of opt. headr */ 164 /* 165 * If the file is not executable then reject the exectution. This means 166 * that there must not be external references. 167 */ 168 if ((flags & COFF_F_EXEC) == 0) { 169 #ifdefCOFF_DEBUG 170 printk ("not executable bit\n");
171 #endif 172 status = -ENOEXEC;
173 break;
174 } 175 /* 176 * There must be atleast one section. 177 */ 178 if (sections == 0) { 179 #ifdefCOFF_DEBUG 180 printk ("no sections\n");
181 #endif 182 status = -ENOEXEC;
183 break;
184 } 185 /* 186 * Do some additional consistency checks. 187 * The system requires mapping for this loader. If you try 188 * to use a file system with no mapping, the format is not valid. 189 */ 190 if (!bprm->inode->i_op ||
191 !bprm->inode->i_op->default_file_ops->mmap) { 192 #ifdefCOFF_DEBUG 193 printk ("no mmap in fs\n");
194 #endif 195 status = -ENOEXEC;
196 } 197 } 198 while (0);
199 /* 200 * Allocate a buffer to hold the entire coff section list. 201 */ 202 if (status >= 0) { 203 intnbytes = sections * COFF_SCNHSZ;
204
205 sect_bufr = (COFF_SCNHDR *) kmalloc (nbytes, GFP_KERNEL);
206 if (0 == sect_bufr) { 207 #ifdefCOFF_DEBUG 208 printk ("kmalloc failed\n");
209 #endif 210 status = -ENOEXEC;
211 } 212 /* 213 * Read the section list from the disk file. 214 */ 215 else{ 216 intold_fs = get_fs ();
217 set_fs (get_ds ()); /* Make it point to the proper location */ 218 status = read_exec (bprm->inode, /* INODE for file */ 219 aout_size + COFF_FILHSZ, /* Offset in the file */ 220 (char *) sect_bufr, /* Buffer for read */ 221 nbytes); /* Byte count reqd. */ 222 set_fs (old_fs); /* Restore the selector */ 223 #ifdefCOFF_DEBUG 224 if (status < 0)
225 printk ("read aout hdr, status = %d\n", status);
226 #endif 227 } 228 } 229 else 230 sect_bufr = NULL; /* Errors do not have a section buffer */ 231 /* 232 * Count the number of sections for the required types and store the location 233 * of the last section for the three primary types. 234 */ 235 text_count = 0;
236 data_count = 0;
237 bss_count = 0;
238 lib_count = 0;
239
240 text_sect = NULL;
241 data_sect = NULL;
242 bss_sect = NULL;
243 /* 244 * Loop through the sections and find the various types 245 */ 246 if (status >= 0) { 247 intnIndex;
248 COFF_SCNHDR *sect_ptr = sect_bufr;
249
250 for (nIndex = 0; nIndex < sections; ++nIndex) { 251 longintsect_flags = COFF_LONG (sect_ptr->s_flags);
252
253 switch (sect_flags) { 254 caseCOFF_STYP_TEXT:
255 text_sect = sect_ptr;
256 ++text_count;
257 status = is_properly_aligned (sect_ptr);
258 break;
259
260 caseCOFF_STYP_DATA:
261 data_sect = sect_ptr;
262 ++data_count;
263 status = is_properly_aligned (sect_ptr);
264 break;
265
266 caseCOFF_STYP_BSS:
267 bss_sect = sect_ptr;
268 ++bss_count;
269 break;
270
271 caseCOFF_STYP_LIB:
272 #ifdefCOFF_DEBUG 273 printk (".lib section found\n");
274 #endif 275 ++lib_count;
276 break;
277
278 default:
279 break;
280 } 281 sect_ptr = (COFF_SCNHDR *) & ((char *) sect_ptr)[COFF_SCNHSZ];
282 } 283 /* 284 * Ensure that there are the required sections. There must be one text 285 * sections and one each of the data and bss sections for an executable. 286 * A library may or may not have a data / bss section. 287 */ 288 if (text_count != 1) { 289 status = -ENOEXEC;
290 #ifdefCOFF_DEBUG 291 printk ("no text sections\n");
292 #endif 293 } 294 else{ 295 if (lib_ok) { 296 if (data_count != 1 || bss_count != 1) { 297 status = -ENOEXEC;
298 #ifdefCOFF_DEBUG 299 printk ("no .data nor .bss sections\n");
300 #endif 301 } 302 } 303 } 304 } 305 /* 306 * If there is no additional header then assume the file starts at 307 * the first byte of the text section. This may not be the proper place, 308 * so the best solution is to include the optional header. A shared library 309 * __MUST__ have an optional header to indicate that it is a shared library. 310 */ 311 if (status >= 0) { 312 if (aout_size == 0) { 313 if (!lib_ok) { 314 status = -ENOEXEC;
315 #ifdefCOFF_DEBUG 316 printk ("no header in library\n");
317 #endif 318 } 319 start_addr = COFF_LONG (text_sect->s_vaddr);
320 } 321 /* 322 * There is some header. Ensure that it is sufficient. 323 */ 324 else{ 325 if (aout_size < COFF_AOUTSZ) { 326 status = -ENOEXEC;
327 #ifdefCOFF_DEBUG 328 printk ("header too small\n");
329 #endif 330 } 331 else{ 332 COFF_AOUTHDR *aout_hdr = /* Pointer to a.out header */ 333 (COFF_AOUTHDR *) & ((char *) coff_hdr)[COFF_FILHSZ];
334 shortintaout_magic = COFF_SHORT (aout_hdr->magic); /* id */ 335 /* 336 * Validate the magic number in the a.out header. If it is valid then 337 * update the starting symbol location. Do not accept these file formats 338 * when loading a shared library. 339 */ 340 switch (aout_magic) { 341 caseCOFF_OMAGIC:
342 caseCOFF_ZMAGIC:
343 caseCOFF_STMAGIC:
344 if (!lib_ok) { 345 status = -ENOEXEC;
346 #ifdefCOFF_DEBUG 347 printk ("wrong a.out header magic\n");
348 #endif 349 } 350 start_addr = (unsignedint) COFF_LONG (aout_hdr->entry);
351 break;
352 /* 353 * Magic value for a shared library. This is valid only when loading a 354 * shared library. (There is no need for a start_addr. It won't be used.) 355 */ 356 caseCOFF_SHMAGIC:
357 if (lib_ok) { 358 #ifdefCOFF_DEBUG 359 printk ("wrong a.out header magic\n");
360 #endif 361 status = -ENOEXEC;
362 } 363 break;
364
365 default:
366 #ifdefCOFF_DEBUG 367 printk ("wrong a.out header magic\n");
368 #endif 369 status = -ENOEXEC;
370 break;
371 } 372 } 373 } 374 } 375 /* 376 * Fetch a file pointer to the executable. 377 */ 378 if (status >= 0) { 379 fd = open_inode (bprm->inode, O_RDONLY);
380 if (fd < 0) { 381 #ifdefCOFF_DEBUG 382 printk ("can not open inode, result = %d\n", fd);
383 #endif 384 status = fd;
385 } 386 else 387 fp = current->filp[fd];
388 } 389 else 390 fd = -1; /* Invalidate the open file descriptor */ 391 /* 392 * Generate the proper values for the text fields 393 * 394 * THIS IS THE POINT OF NO RETURN. THE NEW PROCESS WILL TRAP OUT SHOULD 395 * SOMETHING FAIL IN THE LOAD SEQUENCE FROM THIS POINT ONWARD. 396 */ 397 if (status >= 0) { 398 longtext_scnptr = COFF_LONG (text_sect->s_scnptr);
399 longtext_size = COFF_LONG (text_sect->s_size);
400 longtext_vaddr = COFF_LONG (text_sect->s_vaddr);
401
402 longdata_scnptr;
403 longdata_size;
404 longdata_vaddr;
405
406 longbss_size;
407 longbss_vaddr;
408 /* 409 * Generate the proper values for the data fields 410 */ 411 if (data_sect != NULL) { 412 data_scnptr = COFF_LONG (data_sect->s_scnptr);
413 data_size = COFF_LONG (data_sect->s_size);
414 data_vaddr = COFF_LONG (data_sect->s_vaddr);
415 } 416 else{ 417 data_scnptr = 0;
418 data_size = 0;
419 data_vaddr = 0;
420 } 421 /* 422 * Generate the proper values for the bss fields 423 */ 424 if (bss_sect != NULL) { 425 bss_size = COFF_LONG (bss_sect->s_size);
426 bss_vaddr = COFF_LONG (bss_sect->s_vaddr);
427 } 428 else{ 429 bss_size = 0;
430 bss_vaddr = 0;
431 } 432 /* 433 * Flush the executable from memory. At this point the executable is 434 * committed to being defined or a segmentation violation will occur. 435 */ 436 if (lib_ok) { 437 #ifdefCOFF_DEBUG 438 printk ("flushing executable\n");
439 #endif 440 flush_old_exec (bprm);
441 /* 442 * Define the initial locations for the various items in the new process 443 */ 444 current->mmap = NULL;
445 current->rss = 0;
446 /* 447 * Construct the parameter and environment string table entries. 448 */ 449 bprm->p += change_ldt (0, bprm->page);
450 bprm->p -= MAX_ARG_PAGES*PAGE_SIZE;
451 bprm->p = (unsignedlong) create_tables ((char *) bprm->p,
452 bprm->argc,
453 bprm->envc,
454 1);
455 /* 456 * Do the end processing once the stack has been constructed 457 */ 458 current->start_code = text_vaddr & PAGE_MASK;
459 current->end_code = text_vaddr + text_size;
460 current->end_data = data_vaddr + data_size;
461 current->start_brk =
462 current->brk = bss_vaddr + bss_size;
463 current->suid =
464 current->euid = bprm->e_uid;
465 current->sgid =
466 current->egid = bprm->e_gid;
467 current->executable = bprm->inode; /* Store inode for file */ 468 ++bprm->inode->i_count; /* Count the open inode */ 469 regs->eip = start_addr; /* Current EIP register */ 470 regs->esp =
471 current->start_stack = bprm->p;
472 } 473 /* 474 * Map the text pages 475 */ 476
477 #ifdefCOFF_DEBUG 478 printk (".text: vaddr = %d, size = %d, scnptr = %d\n",
479 text_vaddr,
480 text_size,
481 text_scnptr);
482 #endif 483 status = do_mmap (fp,
484 text_vaddr & PAGE_MASK,
485 text_size + (text_vaddr & ~PAGE_MASK),
486 PROT_READ | PROT_EXEC,
487 MAP_FIXED | MAP_SHARED,
488 text_scnptr & PAGE_MASK);
489
490 status = (status == (text_vaddr & PAGE_MASK)) ? 0 : -ENOEXEC;
491 /* 492 * Map the data pages 493 */ 494 if (status >= 0 && data_size != 0) { 495 #ifdefCOFF_DEBUG 496 printk (".data: vaddr = %d, size = %d, scnptr = %d\n",
497 data_vaddr,
498 data_size,
499 data_scnptr);
500 #endif 501 status = do_mmap (fp,
502 data_vaddr & PAGE_MASK,
503 data_size + (data_vaddr & ~PAGE_MASK),
504 PROT_READ | PROT_WRITE | PROT_EXEC,
505 MAP_FIXED | MAP_PRIVATE,
506 data_scnptr & PAGE_MASK);
507
508 status = (status == (data_vaddr & PAGE_MASK)) ? 0 : -ENOEXEC;
509 } 510 /* 511 * Construct the bss data for the process. The bss ranges from the 512 * end of the data (which may not be on a page boundry) to the end 513 * of the bss section. Allocate any necessary pages for the data. 514 */ 515 if (status >= 0 && bss_size != 0) { 516 #ifdefCOFF_DEBUG 517 printk (".bss: vaddr = %d, size = %d\n",
518 bss_vaddr,
519 bss_size);
520 #endif 521 zeromap_page_range (PAGE_ALIGN (bss_vaddr),
522 PAGE_ALIGN (bss_size),
523 PAGE_COPY);
524 } 525 /* 526 * Load any shared library for the executable. 527 */ 528 if (lib_ok && lib_count != 0) { 529 intnIndex;
530 COFF_SCNHDR *sect_ptr = sect_bufr;
531 /* 532 * Find the library sections. (There should be atleast one. It was counted 533 * earlier.) This will evenutally recurse to our code and load the shared 534 * library with our own procedures. 535 */ 536 for (nIndex = 0; nIndex < sections; ++nIndex) { 537 longintsect_flags = COFF_LONG (sect_ptr->s_flags);
538 if (sect_flags == COFF_STYP_LIB) { 539 status = preload_library (bprm, sect_ptr, fp);
540 if (status != 0)
541 break;
542 } 543 sect_ptr = (COFF_SCNHDR *) &((char *) sect_ptr) [COFF_SCNHSZ];
544 } 545 } 546 /* 547 * Generate any needed trap for this process. If an error occured then 548 * generate a segmentation violation. If the process is being debugged 549 * then generate the load trap. (Note: If this is a library load then 550 * do not generate the trap here. Pass the error to the caller who 551 * will do it for the process in the outer lay of this procedure call.) 552 */ 553 if (lib_ok) { 554 if (status < 0)
555 send_sig (SIGSEGV, current, 0); /* Generate the error trap */ 556 else{ 557 if (current->flags & PF_PTRACED)
558 send_sig (SIGTRAP, current, 0);
559 } 560 status = 0; /* We are committed. It can't fail */ 561 } 562 } 563 /* 564 * Do any cleanup processing 565 */ 566 if (fd >= 0)
567 sys_close (fd); /* Close unused code file */ 568
569 if (sect_bufr != NULL)
570 kfree (sect_bufr); /* Release section list buffer */ 571 /* 572 * Return the completion status. 573 */ 574 #ifdefCOFF_DEBUG 575 printk ("binfmt_coff: result = %d\n", status);
576 #endif 577 return (status);
578 } 579
580 /* 581 * This procedure will load the library listed in the file name given 582 * as the paramter. The result will be non-zero should something fail 583 * to load. 584 */ 585
586 staticint 587 preload_this_library (structlinux_binprm *exe_bprm, char *lib_name)
/* */ 588 { 589 intstatus;
590 intold_fs = get_fs();
591 /* 592 * If debugging then print "we have arrived" 593 */ 594 #ifdefCOFF_DEBUG 595 printk ("%s loading shared library %s\n",
596 exe_bprm->filename,
597 lib_name);
598 #endif 599 /* 600 * Change the FS register to the proper kernel address space and attempt 601 * to load the library. The library name is allocated from the kernel 602 * pool. 603 */ 604 set_fs (get_ds ());
605 status = sys_uselib (lib_name);
606 set_fs (old_fs);
607 /* 608 * Return the success/failure to the caller. 609 */ 610 return (status);
611 } 612
613 /* 614 * This procedure is called to load a library section. The various 615 * libraries are loaded from the list given in the section data. 616 */ 617
618 staticint 619 preload_library (structlinux_binprm *exe_bprm,
/* */ 620 COFF_SCNHDR * sect, structfile *fp)
621 { 622 intstatus = 0; /* Completion status */ 623 longnbytes; /* Count of bytes in the header area */ 624 /* 625 * Fetch the size of the section. There must be enough room for atleast 626 * one entry. 627 */ 628 nbytes = COFF_LONG (sect->s_size);
629 if (nbytes < COFF_SLIBSZ) { 630 status = -ENOEXEC;
631 #ifdefCOFF_DEBUG 632 printk ("library section too small\n");
633 #endif 634 } 635 /* 636 * Allocate a buffer to hold the section data 637 */ 638 else{ 639 COFF_SLIBHD *phdr;
640 char *buffer = (char *) kmalloc (nbytes, GFP_KERNEL);
641
642 if (0 == buffer) { 643 status = -ENOEXEC;
644 #ifdefCOFF_DEBUG 645 printk ("kmalloc failed\n");
646 #endif 647 } 648 else{ 649 intold_fs = get_fs ();
650 /* 651 * Read the section data from the disk file. 652 */ 653 set_fs (get_ds ()); /* Make it point to the proper location */ 654 status = read_exec (exe_bprm->inode, /* INODE for file */ 655 COFF_LONG (sect->s_scnptr), /* Disk location */ 656 buffer, /* Buffer for read */ 657 nbytes); /* Byte count reqd. */ 658 set_fs (old_fs); /* Restore the selector */ 659 /* 660 * Check the result. The value returned is the byte count actaully read. 661 */ 662 if (status >= 0 && status != nbytes) { 663 #ifdefCOFF_DEBUG 664 printk ("read of lib section was short\n");
665 #endif 666 status = -ENOEXEC;
667 } 668 } 669 /* 670 * At this point, go through the list of libraries in the data area. 671 */ 672 phdr = (COFF_SLIBHD *) buffer;
673 while (status >= 0 && nbytes > COFF_SLIBSZ) { 674 intentry_size = COFF_LONG (phdr->sl_entsz) * sizeof (long);
675 intheader_size = COFF_LONG (phdr->sl_pathndx) * sizeof (long);
676 /* 677 * Validate the sizes of the various items. I don't trust the linker!! 678 */ 679 if ((unsigned) header_size >= (unsigned) nbytes ||
680 entry_size <= 0 ||
681 (unsigned) entry_size <= (unsigned) header_size) { 682 status = -ENOEXEC;
683 #ifdefCOFF_DEBUG 684 printk ("header count is invalid\n");
685 #endif 686 } 687 /* 688 * Load the library. Stop the load process on the first error. 689 */ 690 else{ 691 status = preload_this_library (exe_bprm,
692 &((char *) phdr)[header_size]);
693 #ifdefCOFF_DEBUG 694 printk ("preload_this_library result = %d\n", status);
695 #endif 696 } 697 /* 698 * Point to the next library in the section data. 699 */ 700 nbytes -= entry_size;
701 phdr = (COFF_SLIBHD *) &((char *) phdr)[entry_size];
702 } 703 /* 704 * Release the space for the library list. 705 */ 706 if (buffer != NULL)
707 kfree (buffer);
708 } 709 /* 710 * Return the resulting status to the caller. 711 */ 712 return (status);
713 } 714
715 /* 716 * This procedure is called by the main load sequence. It will load 717 * the executable and prepare it for execution. It provides the additional 718 * parameters used by the recursive coff loader and tells the loader that 719 * this is the main executable. How simple it is . . . . 720 */ 721
722 int 723 load_coff_binary (structlinux_binprm *bprm, structpt_regs *regs)
/* */ 724 { 725 return (load_object (bprm, regs, 1));
726 } 727
728 /* 729 * Load the image for any shared library. 730 * 731 * This is called when we need to load a library based upon a file name. 732 */ 733
734 int 735 load_coff_library (intfd)
/* */ 736 { 737 structlinux_binprm *bprm; /* Parameters for the load operation */ 738 intstatus; /* Status of the request */ 739 /* 740 * Read the first portion of the file. 741 */ 742 bprm = (structlinux_binprm *) kmalloc (sizeof (structlinux_binprm),
743 GFP_KERNEL);
744 if (0 == bprm) { 745 #ifdefCOFF_DEBUG 746 printk ("kmalloc failed\n");
747 #endif 748 status = -ENOEXEC;
749 } 750 else{ 751 structfile *file; /* Pointer to the file table */ 752 structpt_regsregs; /* Register work area */ 753 intold_fs = get_fs (); /* Previous FS register value */ 754
755 memset (bprm, '\0', sizeof (structlinux_binprm));
756
757 file = current->filp[fd];
758 bprm->inode = file->f_inode; /* The only item _really_ needed */ 759 bprm->filename = ""; /* Make it a legal string */ 760 /* 761 * Read the section list from the disk file. 762 */ 763 set_fs (get_ds ()); /* Make it point to the proper location */ 764 status = read_exec (bprm->inode, /* INODE for file */ 765 0L, /* Offset in the file */ 766 bprm->buf, /* Buffer for read */ 767 sizeof (bprm->buf)); /* Size of the buffer */ 768 set_fs (old_fs); /* Restore the selector */ 769 /* 770 * Try to load the library. 771 */ 772 status = load_object (bprm, ®s, 0);
773 /* 774 * Release the work buffer and return the result. 775 */ 776 kfree (bprm); /* Release the buffer area */ 777 } 778 /* 779 * Return the result of the load operation 780 */ 781 return (status);
782 }