The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/ndis/subr_pe.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2003
    3  *      Bill Paul <wpaul@windriver.com>.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by Bill Paul.
   16  * 4. Neither the name of the author nor the names of any co-contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   30  * THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 #ifdef __FreeBSD__
   35 __FBSDID("$FreeBSD: src/sys/compat/ndis/subr_pe.c,v 1.7.2.3 2005/03/31 04:24:36 wpaul Exp $");
   36 #endif
   37 #ifdef __NetBSD__
   38 __KERNEL_RCSID(0, "$NetBSD: subr_pe.c,v 1.4 2006/05/14 21:24:50 elad Exp $");
   39 #endif
   40 
   41 
   42 /*
   43  * This file contains routines for relocating and dynamically linking
   44  * executable object code files in the Windows(r) PE (Portable Executable)
   45  * format. In Windows, anything with a .EXE, .DLL or .SYS extention is
   46  * considered an executable, and all such files have some structures in
   47  * common. The PE format was apparently based largely on COFF but has
   48  * mutated significantly over time. We are mainly concerned with .SYS files,
   49  * so this module implements only enough routines to be able to parse the
   50  * headers and sections of a .SYS object file and perform the necessary
   51  * relocations and jump table patching to allow us to call into it
   52  * (and to have it call back to us). Note that while this module
   53  * can handle fixups for imported symbols, it knows nothing about
   54  * exporting them.
   55  */
   56 
   57 #include <sys/param.h>
   58 #include <sys/types.h>
   59 #include <sys/errno.h>
   60 #include <sys/lock.h>
   61 #ifdef _KERNEL
   62 #include <sys/systm.h>
   63 extern int ndis_strncasecmp(const char *, const char *, size_t);
   64 #define strncasecmp(a, b, c) ndis_strncasecmp(a, b, c)
   65 #else
   66 #include <stdio.h>
   67 #include <stdlib.h>
   68 #include <unistd.h>
   69 #include <string.h>
   70 #endif
   71 
   72 #include <compat/ndis/pe_var.h>
   73 
   74 static vm_offset_t pe_functbl_match(image_patch_table *, char *);
   75 
   76 /*
   77  * Check for an MS-DOS executable header. All Windows binaries
   78  * have a small MS-DOS executable prepended to them to print out
   79  * the "This program requires Windows" message. Even .SYS files
   80  * have this header, in spite of the fact that you're can't actually
   81  * run them directly.
   82  */
   83 
   84 int
   85 pe_get_dos_header(imgbase, hdr)
   86         vm_offset_t             imgbase;
   87         image_dos_header        *hdr;
   88 {
   89         uint16_t                signature;
   90 
   91         if (imgbase == 0 || hdr == NULL)
   92                 return (EINVAL);
   93 
   94         signature = *(uint16_t *)imgbase;
   95         if (signature != IMAGE_DOS_SIGNATURE)
   96                 return (ENOEXEC);
   97 
   98         bcopy ((char *)imgbase, (char *)hdr, sizeof(image_dos_header));
   99 
  100         return(0);
  101 }
  102 
  103 /*
  104  * Verify that this image has a Windows NT PE signature.
  105  */
  106 
  107 int
  108 pe_is_nt_image(imgbase)
  109         vm_offset_t             imgbase;
  110 {
  111         uint32_t                signature;
  112         image_dos_header        *dos_hdr;
  113 
  114         if (imgbase == 0)
  115                 return (EINVAL);
  116 
  117         signature = *(uint16_t *)imgbase;
  118         if (signature == IMAGE_DOS_SIGNATURE) {
  119                 dos_hdr = (image_dos_header *)imgbase;
  120                 signature = *(uint32_t *)(imgbase + dos_hdr->idh_lfanew);
  121                 if (signature == IMAGE_NT_SIGNATURE)
  122                         return(0);
  123         }
  124 
  125         return(ENOEXEC);
  126 }
  127 
  128 /*
  129  * Return a copy of the optional header. This contains the
  130  * executable entry point and the directory listing which we
  131  * need to find the relocations and imports later.
  132  */
  133 
  134 int
  135 pe_get_optional_header(imgbase, hdr)
  136         vm_offset_t             imgbase;
  137         image_optional_header   *hdr;
  138 {
  139         image_dos_header        *dos_hdr;
  140         image_nt_header         *nt_hdr;
  141 
  142         if (imgbase == 0 || hdr == NULL)
  143                 return(EINVAL);
  144 
  145         if (pe_is_nt_image(imgbase))
  146                 return (EINVAL);
  147 
  148         dos_hdr = (image_dos_header *)(imgbase);
  149         nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
  150 
  151         bcopy ((char *)&nt_hdr->inh_optionalhdr, (char *)hdr,
  152             sizeof(image_optional_header));
  153 
  154         return(0);
  155 }
  156 
  157 /*
  158  * Return a copy of the file header. Contains the number of
  159  * sections in this image.
  160  */
  161 
  162 int
  163 pe_get_file_header(imgbase, hdr)
  164         vm_offset_t             imgbase;
  165         image_file_header       *hdr;
  166 {
  167         image_dos_header        *dos_hdr;
  168         image_nt_header         *nt_hdr;
  169 
  170         if (imgbase == 0 || hdr == NULL)
  171                 return(EINVAL);
  172 
  173         if (pe_is_nt_image(imgbase))
  174                 return (EINVAL);
  175 
  176         dos_hdr = (image_dos_header *)imgbase;
  177         nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
  178 
  179         bcopy ((char *)&nt_hdr->inh_filehdr, (char *)hdr,
  180             sizeof(image_file_header));
  181 
  182         return(0);
  183 }
  184 
  185 /*
  186  * Return the header of the first section in this image (usually
  187  * .text).
  188  */
  189 
  190 int
  191 pe_get_section_header(imgbase, hdr)
  192         vm_offset_t             imgbase;
  193         image_section_header    *hdr;
  194 {
  195         image_dos_header        *dos_hdr;
  196         image_nt_header         *nt_hdr;
  197         image_section_header    *sect_hdr;
  198 
  199         if (imgbase == 0 || hdr == NULL)
  200                 return(EINVAL);
  201 
  202         if (pe_is_nt_image(imgbase))
  203                 return (EINVAL);
  204 
  205         dos_hdr = (image_dos_header *)imgbase;
  206         nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
  207         sect_hdr = (image_section_header *)((vm_offset_t)nt_hdr +
  208             sizeof(image_nt_header));
  209 
  210         bcopy ((char *)sect_hdr, (char *)hdr, sizeof(image_section_header));
  211 
  212         return(0);
  213 }
  214 
  215 /*
  216  * Return the number of sections in this executable, or 0 on error.
  217  */
  218 
  219 int
  220 pe_numsections(imgbase)
  221         vm_offset_t             imgbase;
  222 {
  223         image_file_header       file_hdr;
  224 
  225         if (pe_get_file_header(imgbase, &file_hdr))
  226                 return(0);
  227 
  228         return (file_hdr.ifh_numsections);
  229 }
  230 
  231 /*
  232  * Return the base address that this image was linked for.
  233  * This helps us calculate relocation addresses later.
  234  */
  235 
  236 vm_offset_t
  237 pe_imagebase(imgbase)
  238         vm_offset_t             imgbase;
  239 {
  240         image_optional_header   optional_hdr;
  241 
  242         if (pe_get_optional_header(imgbase, &optional_hdr))
  243                 return(0);
  244 
  245         return (optional_hdr.ioh_imagebase);
  246 }
  247 
  248 /*
  249  * Return the offset of a given directory structure within the
  250  * image. Directories reside within sections.
  251  */
  252 
  253 vm_offset_t
  254 pe_directory_offset(imgbase, diridx)
  255         vm_offset_t             imgbase;
  256         uint32_t                diridx;
  257 {
  258         image_optional_header   opt_hdr;
  259         vm_offset_t             dir;
  260 
  261         if (pe_get_optional_header(imgbase, &opt_hdr))
  262                 return(0);
  263 
  264         if (diridx >= opt_hdr.ioh_rva_size_cnt)
  265                 return(0);
  266 
  267         dir = opt_hdr.ioh_datadir[diridx].idd_vaddr;
  268 
  269         return(pe_translate_addr(imgbase, dir));
  270 }
  271 
  272 vm_offset_t
  273 pe_translate_addr(imgbase, rva)
  274         vm_offset_t             imgbase;
  275         vm_offset_t             rva;
  276 {
  277         image_optional_header   opt_hdr;
  278         image_section_header    *sect_hdr;
  279         image_dos_header        *dos_hdr;
  280         image_nt_header         *nt_hdr;
  281         int                     i = 0, sections, fixedlen;
  282 
  283         if (pe_get_optional_header(imgbase, &opt_hdr))
  284                 return(0);
  285 
  286         sections = pe_numsections(imgbase);
  287 
  288         dos_hdr = (image_dos_header *)imgbase;
  289         nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
  290         sect_hdr = (image_section_header *)((vm_offset_t)nt_hdr +
  291             sizeof(image_nt_header));
  292 
  293         /*
  294          * The test here is to see if the RVA falls somewhere
  295          * inside the section, based on the section's start RVA
  296          * and its length. However it seems sometimes the
  297          * virtual length isn't enough to cover the entire
  298          * area of the section. We fudge by taking into account
  299          * the section alignment and rounding the section length
  300          * up to a page boundary.
  301          */
  302         while (i++ < sections) {
  303                 fixedlen = sect_hdr->ish_misc.ish_vsize;
  304                 fixedlen += ((opt_hdr.ioh_sectalign - 1) -
  305                     sect_hdr->ish_misc.ish_vsize) &
  306                     (opt_hdr.ioh_sectalign - 1);
  307                 if (sect_hdr->ish_vaddr <= (uint32_t)rva &&
  308                     (sect_hdr->ish_vaddr + fixedlen) >
  309                     (uint32_t)rva)
  310                         break;
  311                 sect_hdr++;
  312         }
  313 
  314         if (i > sections)
  315                 return(0);
  316 
  317         return((vm_offset_t)(imgbase + rva - sect_hdr->ish_vaddr +
  318             sect_hdr->ish_rawdataaddr));
  319 }
  320 
  321 /*
  322  * Get the section header for a particular section. Note that
  323  * section names can be anything, but there are some standard
  324  * ones (.text, .data, .rdata, .reloc).
  325  */
  326 
  327 int
  328 pe_get_section(imgbase, hdr, name)
  329         vm_offset_t             imgbase;
  330         image_section_header    *hdr;
  331         const char              *name;
  332 {
  333         image_dos_header        *dos_hdr;
  334         image_nt_header         *nt_hdr;
  335         image_section_header    *sect_hdr;
  336 
  337         int                     i, sections;
  338 
  339         if (imgbase == 0 || hdr == NULL)
  340                 return(EINVAL);
  341 
  342         if (pe_is_nt_image(imgbase))
  343                 return (EINVAL);
  344 
  345         sections = pe_numsections(imgbase);
  346 
  347         dos_hdr = (image_dos_header *)imgbase;
  348         nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
  349         sect_hdr = (image_section_header *)((vm_offset_t)nt_hdr +
  350             sizeof(image_nt_header));
  351 
  352         for (i = 0; i < sections; i++) {
  353                 if (!strcmp ((char *)&sect_hdr->ish_name, name)) {
  354                         bcopy((char *)sect_hdr, (char *)hdr,
  355                             sizeof(image_section_header));
  356                         return(0);
  357                 } else
  358                         sect_hdr++;
  359         }
  360 
  361         return (ENOEXEC);
  362 }
  363 
  364 /*
  365  * Apply the base relocations to this image. The relocation table
  366  * resides within the .reloc section. Relocations are specified in
  367  * blocks which refer to a particular page. We apply the relocations
  368  * one page block at a time.
  369  */
  370 
  371 int
  372 pe_relocate(imgbase)
  373         vm_offset_t             imgbase;
  374 {
  375         image_section_header    sect;
  376         image_base_reloc        *relhdr;
  377         uint16_t                rel, *sloc;
  378         vm_offset_t             base;
  379         vm_size_t               delta;
  380         uint32_t                *lloc;
  381         uint64_t                *qloc;
  382         int                     i, count;
  383         vm_offset_t             txt;
  384 
  385         base = pe_imagebase(imgbase);
  386         pe_get_section(imgbase, &sect, ".text");
  387         txt = pe_translate_addr(imgbase, sect.ish_vaddr);
  388         delta = (uint32_t)(txt) - base - sect.ish_vaddr;
  389 
  390         pe_get_section(imgbase, &sect, ".reloc");
  391 
  392         relhdr = (image_base_reloc *)(imgbase + sect.ish_rawdataaddr);
  393 
  394         do {
  395                 count = (relhdr->ibr_blocksize -
  396                     (sizeof(uint32_t) * 2)) / sizeof(uint16_t);
  397                 for (i = 0; i < count; i++) {
  398                         rel = relhdr->ibr_rel[i];
  399                         switch (IMR_RELTYPE(rel)) {
  400                         case IMAGE_REL_BASED_ABSOLUTE:
  401                                 break;
  402                         case IMAGE_REL_BASED_HIGHLOW:
  403                                 lloc = (uint32_t *)pe_translate_addr(imgbase,
  404                                     relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
  405                                 *lloc = pe_translate_addr(imgbase,
  406                                     (*lloc - base));
  407                                 break;
  408                         case IMAGE_REL_BASED_HIGH:
  409                                 sloc = (uint16_t *)pe_translate_addr(imgbase,
  410                                     relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
  411                                 *sloc += (delta & 0xFFFF0000) >> 16;
  412                                 break;
  413                         case IMAGE_REL_BASED_LOW:
  414                                 sloc = (uint16_t *)pe_translate_addr(imgbase,
  415                                     relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
  416                                 *sloc += (delta & 0xFFFF);
  417                                 break;
  418                         case IMAGE_REL_BASED_DIR64:
  419                                 qloc = (uint64_t *)pe_translate_addr(imgbase,
  420                                     relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
  421                                 *qloc = pe_translate_addr(imgbase,
  422                                     (*qloc - base));
  423                                 break;
  424 
  425                         default:
  426                                 printf ("[%d]reloc type: %d\n",i,
  427                                     IMR_RELTYPE(rel));
  428                                 break;
  429                         }
  430                 }
  431                 relhdr = (image_base_reloc *)((vm_offset_t)relhdr +
  432                     relhdr->ibr_blocksize);
  433         } while (relhdr->ibr_blocksize);
  434 
  435         return(0);
  436 }
  437 
  438 /*
  439  * Return the import descriptor for a particular module. An image
  440  * may be linked against several modules, typically HAL.dll, ntoskrnl.exe
  441  * and NDIS.SYS. For each module, there is a list of imported function
  442  * names and their addresses.
  443  *
  444  * Note: module names are case insensitive!
  445  */
  446 
  447 int
  448 pe_get_import_descriptor(imgbase, desc, module)
  449         vm_offset_t             imgbase;
  450         image_import_descriptor *desc;
  451         const char              *module;
  452 {       
  453         vm_offset_t             offset;
  454         image_import_descriptor *imp_desc;
  455         char                    *modname;
  456 
  457         if (imgbase == 0 || module == NULL || desc == NULL)
  458                 return(EINVAL);
  459 
  460         offset = pe_directory_offset(imgbase, IMAGE_DIRECTORY_ENTRY_IMPORT);
  461         if (offset == 0)
  462                 return (ENOENT);
  463 
  464         imp_desc = (void *)offset;
  465 
  466         while (imp_desc->iid_nameaddr) {
  467                 modname = (char *)pe_translate_addr(imgbase,
  468                     imp_desc->iid_nameaddr);
  469                 if (!strncasecmp(module, modname, strlen(module))) {
  470                         bcopy((char *)imp_desc, (char *)desc,
  471                             sizeof(image_import_descriptor));
  472                         return(0);
  473                 }
  474                 imp_desc++;
  475         }
  476 
  477         return (ENOENT);
  478 }
  479 
  480 int
  481 pe_get_messagetable(imgbase, md)
  482         vm_offset_t             imgbase;
  483         message_resource_data   **md;
  484 {
  485         image_resource_directory        *rdir, *rtype;
  486         image_resource_directory_entry  *dent, *dent2;
  487         image_resource_data_entry       *rent;
  488         vm_offset_t             offset;
  489         int                     i;
  490 
  491         if (imgbase == 0)
  492                 return(EINVAL);
  493 
  494         offset = pe_directory_offset(imgbase, IMAGE_DIRECTORY_ENTRY_RESOURCE);
  495         if (offset == 0)
  496                 return (ENOENT);
  497 
  498         rdir = (image_resource_directory *)offset;
  499 
  500         dent = (image_resource_directory_entry *)(offset +
  501             sizeof(image_resource_directory));
  502 
  503         for (i = 0; i < rdir->ird_id_entries; i++){
  504                 if (dent->irde_name != RT_MESSAGETABLE) {
  505                         dent++;
  506                         continue;
  507                 }
  508                 dent2 = dent;
  509                 while (dent2->irde_dataoff & RESOURCE_DIR_FLAG) {
  510                         rtype = (image_resource_directory *)(offset +
  511                             (dent2->irde_dataoff & ~RESOURCE_DIR_FLAG));
  512                         dent2 = (image_resource_directory_entry *)
  513                             ((uintptr_t)rtype +
  514                              sizeof(image_resource_directory));
  515                 }
  516                 rent = (image_resource_data_entry *)(offset +
  517                     dent2->irde_dataoff);
  518                 *md = (message_resource_data *)pe_translate_addr(imgbase,
  519                     rent->irde_offset);
  520                 return(0);
  521         }
  522 
  523         return(ENOENT);
  524 }
  525 
  526 int
  527 pe_get_message(imgbase, id, str, len, flags)
  528         vm_offset_t             imgbase;
  529         uint32_t                id;
  530         char                    **str;
  531         int                     *len;
  532         uint16_t                *flags;
  533 {
  534         message_resource_data   *md = NULL;
  535         message_resource_block  *mb;
  536         message_resource_entry  *me;
  537         uint32_t                i;
  538 
  539         pe_get_messagetable(imgbase, &md);
  540 
  541         if (md == NULL)
  542                 return(ENOENT);
  543 
  544         mb = (message_resource_block *)((uintptr_t)md +
  545             sizeof(message_resource_data));
  546 
  547         for (i = 0; i < md->mrd_numblocks; i++) {
  548                 if (id >= mb->mrb_lowid && id <= mb->mrb_highid) {
  549                         me = (message_resource_entry *)((uintptr_t)md +
  550                             mb->mrb_entryoff);
  551                         for (i = id - mb->mrb_lowid; i > 0; i--)
  552                                 me = (message_resource_entry *)((uintptr_t)me +
  553                                     me->mre_len);
  554                         *str = me->mre_text;
  555                         *len = me->mre_len;
  556                         *flags = me->mre_flags;
  557                         return(0);
  558                 }
  559                 mb++;
  560         }
  561 
  562         return(ENOENT);
  563 }
  564 
  565 /*
  566  * Find the function that matches a particular name. This doesn't
  567  * need to be particularly speedy since it's only run when loading
  568  * a module for the first time.
  569  */
  570 
  571 static vm_offset_t
  572 pe_functbl_match(functbl, name)
  573         image_patch_table       *functbl;
  574         char                    *name;
  575 {
  576         image_patch_table       *p;
  577 
  578         if (functbl == NULL || name == NULL)
  579                 return(0);
  580 
  581         p = functbl;
  582 
  583         while (p->ipt_name != NULL) {
  584                 if (!strcmp(p->ipt_name, name))
  585                         return((vm_offset_t)p->ipt_wrap);
  586                 p++;
  587         }
  588         printf ("no match for %s\n", name);
  589 
  590         /*
  591          * Return the wrapper pointer for this routine.
  592          * For x86, this is the same as the funcptr.
  593          * For amd64, this points to a wrapper routine
  594          * that does calling convention translation and
  595          * then invokes the underlying routine.
  596          */
  597         return((vm_offset_t)p->ipt_wrap);
  598 }
  599 
  600 /*
  601  * Patch the imported function addresses for a given module.
  602  * The caller must specify the module name and provide a table
  603  * of function pointers that will be patched into the jump table.
  604  * Note that there are actually two copies of the jump table: one
  605  * copy is left alone. In a .SYS file, the jump tables are usually
  606  * merged into the INIT segment.
  607  */
  608 
  609 int
  610 pe_patch_imports(imgbase, module, functbl)
  611         vm_offset_t             imgbase;
  612         const char              *module;
  613         image_patch_table       *functbl;
  614 {
  615         image_import_descriptor imp_desc;
  616         char                    *fname;
  617         vm_offset_t             *nptr, *fptr;
  618         vm_offset_t             func;
  619 
  620         if (imgbase == 0 || module == NULL || functbl == NULL)
  621                 return(EINVAL);
  622 
  623         if (pe_get_import_descriptor(imgbase, &imp_desc, module))
  624                 return(ENOEXEC);
  625 
  626         nptr = (vm_offset_t *)pe_translate_addr(imgbase,
  627             imp_desc.iid_import_name_table_addr);
  628         fptr = (vm_offset_t *)pe_translate_addr(imgbase,
  629             imp_desc.iid_import_address_table_addr);
  630 
  631         while (nptr != NULL && pe_translate_addr(imgbase, *nptr)) {
  632                 fname = (char *)pe_translate_addr(imgbase, (*nptr) + 2);
  633                 func = pe_functbl_match(functbl, fname);
  634                 if (func)
  635                         *fptr = func;
  636 #ifdef notdef
  637                 if (*fptr == 0)
  638                         return(ENOENT);
  639 #endif
  640                 nptr++;
  641                 fptr++;
  642         }
  643 
  644         return(0);
  645 }

Cache object: 6ada95c920004905b28667b74625f7f6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.