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 * Author: Al Longyear (longyear@sii.com)
11 *
12 * Latest Revision:
13 * 3 Feburary 1994
14 * Al Longyear (longyear@sii.com)
15 * Cleared first page of bss section using put_fs_byte.
16 */
17
18 #include <linux/fs.h>
19 #include <linux/sched.h>
20 #include <linux/mm.h>
21 #include <linux/mman.h>
22 #include <linux/a.out.h>
23 #include <linux/errno.h>
24 #include <linux/signal.h>
25 #include <linux/binfmts.h>
26 #include <asm/segment.h>
27 #include <linux/string.h>
28 #include <linux/fcntl.h>
29 #include <linux/ptrace.h>
30 #include <linux/coff.h>
31 #include <linux/malloc.h>
32
33 asmlinkage int sys_exit (int exit_code);
34 asmlinkage int sys_close (unsigned fd);
35 asmlinkage int sys_open (const char *, int, int);
36 asmlinkage int sys_uselib(const char * library);
37
38 static int preload_library (struct linux_binprm *exe_bprm,
39 COFF_SCNHDR * sect,
40 struct file *fp);
41
42 static int load_object (struct linux_binprm *bprm,
43 struct pt_regs *regs,
44 int lib_ok);
45
46 /*
47 * Small procedure to test for the proper file alignment.
48 */
49
50 static inline int
51 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)
*/
52 {
53 long scnptr = COFF_LONG (sect->s_scnptr);
54 long vaddr = COFF_LONG (sect->s_vaddr);
55 /*
56 * Print the section information if needed
57 */
58
59 #ifdef COFF_DEBUG
60 printk ("%s, scnptr = %d, vaddr = %d\n",
61 sect->s_name,
62 scnptr, vaddr);
63 #endif
64
65 /*
66 * Return the error code if the section is not properly aligned.
67 */
68
69 #ifdef COFF_DEBUG
70 if (((vaddr - scnptr) & ~PAGE_MASK) != 0)
71 printk ("bad alignment in %s\n", sect->s_name);
72 #endif
73 return ((((vaddr - scnptr) & ~PAGE_MASK) != 0) ? -ENOEXEC : 0);
74 }
75
76 /*
77 * Clear the bytes in the last page of data.
78 */
79
80 static
81 int clear_memory (unsigned long addr, unsigned long size)
/* ![[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)
*/
82 {
83 int status;
84
85 size = (PAGE_SIZE - (addr & ~PAGE_MASK)) & ~PAGE_MASK;
86 if (size == 0)
87 status = 0;
88 else {
89
90 #ifdef COFF_DEBUG
91 printk ("un-initialized storage in last page %d\n", size);
92 #endif
93
94 status = verify_area (VERIFY_WRITE,
95 (void *) addr, size);
96 #ifdef COFF_DEBUG
97 printk ("result from verify_area = %d\n", status);
98 #endif
99
100 if (status >= 0)
101 while (size-- != 0)
102 put_fs_byte (0, addr++);
103 }
104 return status;
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 status = clear_memory (bss_vaddr, bss_size);
526 }
527 /*
528 * Load any shared library for the executable.
529 */
530 if (status >= 0 && lib_ok && lib_count != 0) {
531 int nIndex;
532 COFF_SCNHDR *sect_ptr = sect_bufr;
533 /*
534 * Find the library sections. (There should be atleast one. It was counted
535 * earlier.) This will evenutally recurse to our code and load the shared
536 * library with our own procedures.
537 */
538 for (nIndex = 0; nIndex < sections; ++nIndex) {
539 long int sect_flags = COFF_LONG (sect_ptr->s_flags);
540 if (sect_flags == COFF_STYP_LIB) {
541 status = preload_library (bprm, sect_ptr, fp);
542 if (status != 0)
543 break;
544 }
545 sect_ptr = (COFF_SCNHDR *) &((char *) sect_ptr) [COFF_SCNHSZ];
546 }
547 }
548 /*
549 * Generate any needed trap for this process. If an error occured then
550 * generate a segmentation violation. If the process is being debugged
551 * then generate the load trap. (Note: If this is a library load then
552 * do not generate the trap here. Pass the error to the caller who
553 * will do it for the process in the outer lay of this procedure call.)
554 */
555 if (lib_ok) {
556 if (status < 0)
557 send_sig (SIGSEGV, current, 0); /* Generate the error trap */
558 else {
559 if (current->flags & PF_PTRACED)
560 send_sig (SIGTRAP, current, 0);
561 }
562 status = 0; /* We are committed. It can't fail */
563 }
564 }
565 /*
566 * Do any cleanup processing
567 */
568 if (fd >= 0)
569 sys_close (fd); /* Close unused code file */
570
571 if (sect_bufr != NULL)
572 kfree (sect_bufr); /* Release section list buffer */
573 /*
574 * Return the completion status.
575 */
576 #ifdef COFF_DEBUG
577 printk ("binfmt_coff: result = %d\n", status);
578 #endif
579 return (status);
580 }
581
582 /*
583 * This procedure will load the library listed in the file name given
584 * as the paramter. The result will be non-zero should something fail
585 * to load.
586 */
587
588 static int
589 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)
*/
590 {
591 int status;
592 int old_fs = get_fs();
593 /*
594 * If debugging then print "we have arrived"
595 */
596 #ifdef COFF_DEBUG
597 printk ("%s loading shared library %s\n",
598 exe_bprm->filename,
599 lib_name);
600 #endif
601 /*
602 * Change the FS register to the proper kernel address space and attempt
603 * to load the library. The library name is allocated from the kernel
604 * pool.
605 */
606 set_fs (get_ds ());
607 status = sys_uselib (lib_name);
608 set_fs (old_fs);
609 /*
610 * Return the success/failure to the caller.
611 */
612 return (status);
613 }
614
615 /*
616 * This procedure is called to load a library section. The various
617 * libraries are loaded from the list given in the section data.
618 */
619
620 static int
621 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)
*/
622 COFF_SCNHDR * sect, struct file *fp)
623 {
624 int status = 0; /* Completion status */
625 long nbytes; /* Count of bytes in the header area */
626 /*
627 * Fetch the size of the section. There must be enough room for atleast
628 * one entry.
629 */
630 nbytes = COFF_LONG (sect->s_size);
631 if (nbytes < COFF_SLIBSZ) {
632 status = -ENOEXEC;
633 #ifdef COFF_DEBUG
634 printk ("library section too small\n");
635 #endif
636 }
637 /*
638 * Allocate a buffer to hold the section data
639 */
640 else {
641 COFF_SLIBHD *phdr;
642 char *buffer = (char *) kmalloc (nbytes, GFP_KERNEL);
643
644 if (0 == buffer) {
645 status = -ENOEXEC;
646 #ifdef COFF_DEBUG
647 printk ("kmalloc failed\n");
648 #endif
649 }
650 else {
651 int old_fs = get_fs ();
652 /*
653 * Read the section data from the disk file.
654 */
655 set_fs (get_ds ()); /* Make it point to the proper location */
656 status = read_exec (exe_bprm->inode, /* INODE for file */
657 COFF_LONG (sect->s_scnptr), /* Disk location */
658 buffer, /* Buffer for read */
659 nbytes); /* Byte count reqd. */
660 set_fs (old_fs); /* Restore the selector */
661 /*
662 * Check the result. The value returned is the byte count actaully read.
663 */
664 if (status >= 0 && status != nbytes) {
665 #ifdef COFF_DEBUG
666 printk ("read of lib section was short\n");
667 #endif
668 status = -ENOEXEC;
669 }
670 }
671 /*
672 * At this point, go through the list of libraries in the data area.
673 */
674 phdr = (COFF_SLIBHD *) buffer;
675 while (status >= 0 && nbytes > COFF_SLIBSZ) {
676 int entry_size = COFF_LONG (phdr->sl_entsz) * sizeof (long);
677 int header_size = COFF_LONG (phdr->sl_pathndx) * sizeof (long);
678 /*
679 * Validate the sizes of the various items. I don't trust the linker!!
680 */
681 if ((unsigned) header_size >= (unsigned) nbytes ||
682 entry_size <= 0 ||
683 (unsigned) entry_size <= (unsigned) header_size) {
684 status = -ENOEXEC;
685 #ifdef COFF_DEBUG
686 printk ("header count is invalid\n");
687 #endif
688 }
689 /*
690 * Load the library. Stop the load process on the first error.
691 */
692 else {
693 status = preload_this_library (exe_bprm,
694 &((char *) phdr)[header_size]);
695 #ifdef COFF_DEBUG
696 printk ("preload_this_library result = %d\n", status);
697 #endif
698 }
699 /*
700 * Point to the next library in the section data.
701 */
702 nbytes -= entry_size;
703 phdr = (COFF_SLIBHD *) &((char *) phdr)[entry_size];
704 }
705 /*
706 * Release the space for the library list.
707 */
708 if (buffer != NULL)
709 kfree (buffer);
710 }
711 /*
712 * Return the resulting status to the caller.
713 */
714 return (status);
715 }
716
717 /*
718 * This procedure is called by the main load sequence. It will load
719 * the executable and prepare it for execution. It provides the additional
720 * parameters used by the recursive coff loader and tells the loader that
721 * this is the main executable. How simple it is . . . .
722 */
723
724 int
725 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)
*/
726 {
727 return (load_object (bprm, regs, 1));
728 }
729
730 /*
731 * Load the image for any shared library.
732 *
733 * This is called when we need to load a library based upon a file name.
734 */
735
736 int
737 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)
*/
738 {
739 struct linux_binprm *bprm; /* Parameters for the load operation */
740 int status; /* Status of the request */
741 /*
742 * Read the first portion of the file.
743 */
744 bprm = (struct linux_binprm *) kmalloc (sizeof (struct linux_binprm),
745 GFP_KERNEL);
746 if (0 == bprm) {
747 #ifdef COFF_DEBUG
748 printk ("kmalloc failed\n");
749 #endif
750 status = -ENOEXEC;
751 }
752 else {
753 struct file *file; /* Pointer to the file table */
754 struct pt_regs regs; /* Register work area */
755 int old_fs = get_fs (); /* Previous FS register value */
756
757 memset (bprm, '\0', sizeof (struct linux_binprm));
758
759 file = current->filp[fd];
760 bprm->inode = file->f_inode; /* The only item _really_ needed */
761 bprm->filename = ""; /* Make it a legal string */
762 /*
763 * Read the section list from the disk file.
764 */
765 set_fs (get_ds ()); /* Make it point to the proper location */
766 status = read_exec (bprm->inode, /* INODE for file */
767 0L, /* Offset in the file */
768 bprm->buf, /* Buffer for read */
769 sizeof (bprm->buf)); /* Size of the buffer */
770 set_fs (old_fs); /* Restore the selector */
771 /*
772 * Try to load the library.
773 */
774 status = load_object (bprm, ®s, 0);
775 /*
776 * Release the work buffer and return the result.
777 */
778 kfree (bprm); /* Release the buffer area */
779 }
780 /*
781 * Return the result of the load operation
782 */
783 return (status);
784 }