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 asmlinkage int sys_exit (int exit_code);
65 asmlinkage int sys_close (unsigned fd);
66 asmlinkage int sys_open (const char *, int, int);
67 asmlinkage int sys_uselib(const char * library);
68
69 static int preload_library (struct linux_binprm *exe_bprm,
70 COFF_SCNHDR * sect,
71 struct file *fp);
72
73 static int load_object (struct linux_binprm *bprm,
74 struct pt_regs *regs,
75 int lib_ok);
76
77 /*
78 * Small procedure to test for the proper file alignment.
79 */
80
81 static inline int
82 is_properly_aligned (COFF_SCNHDR *sect)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
83 {
84 long scnptr = COFF_LONG (sect->s_scnptr);
85 long vaddr = COFF_LONG (sect->s_vaddr);
86 /*
87 * Print the section information if needed
88 */
89
90 #ifdef COFF_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 #ifdef COFF_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 static int
112 load_object (struct linux_binprm * bprm, struct pt_regs *regs, int lib_ok)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
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 int text_count; /* Number of text sections */
120 int data_count; /* Number of data sections */
121 int bss_count; /* Number of bss sections */
122 int lib_count; /* Number of lib sections */
123 unsigned int start_addr = 0;/* Starting location for program */
124 int status = 0; /* Result status register */
125 int fd = -1; /* Open file descriptor */
126 struct file *fp = NULL; /* Pointer to the file at "fd" */
127 short int sections = 0; /* Number of sections in the file */
128 short int aout_size = 0; /* Size of the a.out header area */
129 short int flags; /* Flag bits from the COFF header */
130
131 #ifdef COFF_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 #ifdef COFF_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 #ifdef COFF_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 #ifdef COFF_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 #ifdef COFF_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 #ifdef COFF_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 int nbytes = sections * COFF_SCNHSZ;
204
205 sect_bufr = (COFF_SCNHDR *) kmalloc (nbytes, GFP_KERNEL);
206 if (0 == sect_bufr) {
207 #ifdef COFF_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 int old_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 #ifdef COFF_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 int nIndex;
248 COFF_SCNHDR *sect_ptr = sect_bufr;
249
250 for (nIndex = 0; nIndex < sections; ++nIndex) {
251 long int sect_flags = COFF_LONG (sect_ptr->s_flags);
252
253 switch (sect_flags) {
254 case COFF_STYP_TEXT:
255 text_sect = sect_ptr;
256 ++text_count;
257 status = is_properly_aligned (sect_ptr);
258 break;
259
260 case COFF_STYP_DATA:
261 data_sect = sect_ptr;
262 ++data_count;
263 status = is_properly_aligned (sect_ptr);
264 break;
265
266 case COFF_STYP_BSS:
267 bss_sect = sect_ptr;
268 ++bss_count;
269 break;
270
271 case COFF_STYP_LIB:
272 #ifdef COFF_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 #ifdef COFF_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 #ifdef COFF_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 #ifdef COFF_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 #ifdef COFF_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 short int aout_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 case COFF_OMAGIC:
342 case COFF_ZMAGIC:
343 case COFF_STMAGIC:
344 if (!lib_ok) {
345 status = -ENOEXEC;
346 #ifdef COFF_DEBUG
347 printk ("wrong a.out header magic\n");
348 #endif
349 }
350 start_addr = (unsigned int) 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 case COFF_SHMAGIC:
357 if (lib_ok) {
358 #ifdef COFF_DEBUG
359 printk ("wrong a.out header magic\n");
360 #endif
361 status = -ENOEXEC;
362 }
363 break;
364
365 default:
366 #ifdef COFF_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 #ifdef COFF_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 long text_scnptr = COFF_LONG (text_sect->s_scnptr);
399 long text_size = COFF_LONG (text_sect->s_size);
400 long text_vaddr = COFF_LONG (text_sect->s_vaddr);
401
402 long data_scnptr;
403 long data_size;
404 long data_vaddr;
405
406 long bss_size;
407 long bss_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 #ifdef COFF_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 = (unsigned long) 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 #ifdef COFF_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 #ifdef COFF_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 #ifdef COFF_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 int nIndex;
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 long int sect_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 #ifdef COFF_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 static int
587 preload_this_library (struct linux_binprm *exe_bprm, char *lib_name)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
588 {
589 int status;
590 int old_fs = get_fs();
591 /*
592 * If debugging then print "we have arrived"
593 */
594 #ifdef COFF_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 static int
619 preload_library (struct linux_binprm *exe_bprm,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
620 COFF_SCNHDR * sect, struct file *fp)
621 {
622 int status = 0; /* Completion status */
623 long nbytes; /* 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 #ifdef COFF_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 #ifdef COFF_DEBUG
645 printk ("kmalloc failed\n");
646 #endif
647 }
648 else {
649 int old_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 #ifdef COFF_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 int entry_size = COFF_LONG (phdr->sl_entsz) * sizeof (long);
675 int header_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 #ifdef COFF_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 #ifdef COFF_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 (struct linux_binprm *bprm, struct pt_regs *regs)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
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 (int fd)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
736 {
737 struct linux_binprm *bprm; /* Parameters for the load operation */
738 int status; /* Status of the request */
739 /*
740 * Read the first portion of the file.
741 */
742 bprm = (struct linux_binprm *) kmalloc (sizeof (struct linux_binprm),
743 GFP_KERNEL);
744 if (0 == bprm) {
745 #ifdef COFF_DEBUG
746 printk ("kmalloc failed\n");
747 #endif
748 status = -ENOEXEC;
749 }
750 else {
751 struct file *file; /* Pointer to the file table */
752 struct pt_regs regs; /* Register work area */
753 int old_fs = get_fs (); /* Previous FS register value */
754
755 memset (bprm, '\0', sizeof (struct linux_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 }