root/fs/binfmt_coff.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. is_properly_aligned
  2. load_object
  3. preload_this_library
  4. preload_library
  5. load_coff_binary
  6. load_coff_library

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

/* [previous][next][first][last][top][bottom][index][help] */