home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / binfmt_coff.c next >
Encoding:
C/C++ Source or Header  |  1994-02-14  |  20.8 KB  |  785 lines

  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)
  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)
  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)
  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)
  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,
  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)
  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)
  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. }
  785.