| Index | Manual | Download | Source | Macros | Embedded word Case ins.
Sitemap | Links | Forum | Tests | Projects

# pfdll.htm
Procedures
PfdllCompile
PfdllLoadPgm

This source PFDLL generates and imports EuroAssembler output object file in program format DLL (COFF Dynamic Linked Library).

    pfdll PROGRAM FORMAT=COFF,MODEL=FLAT,WIDTH=32
          INCLUDEHEAD euroasm.htm, \  Interface (structures, symbols and macros) of other modules used in this source.
                      ea.htm,eaopt.htm,exp.htm,msg.htm,pf.htm,pfcoff.htm,pfmz.htm,pfpe.htm,pgm.htm,pgmopt.htm, \
                      reloc.htm,sss.htm,stm.htm,sym.htm

     pfdll HEAD ; Start module interface.
     ; Program pfdll exports nothing.
     ENDHEAD pfdll  ; End of module interface.

↑ PfdllCompile OutputStream, Pgm
  PfdllCompile is constructor of output file image in format DLL.
  It is almost identical with file format PE, the only difference is filename extension, voluntary entry point, different image base and binary flag `PFCOFF_FILE_HEADER.Characteristics:pfcoffFILE_DLL` set by PfcoffFileHeader.
Input
  OutputStream is pointer to an empty STREAM for the output image contents.
  Pgm is pointer to PGM representing the completely assembled program, optionally combined with other linked modules.
Output
  OutputStream is filled with output file contents.
Error
  Errors are reported with macro Msg.
Invoked from
  PfOutput
Invokes
  PfpeCompile
Tested by
  t9485 t9536

    PfdllCompile Procedure OutputStream, Pgm
       Invoke PfpeCompile::,[%OutputStream],[%Pgm]
       EndProcedure PfdllCompile

↑ PfdllLoadPgm BasePgm, ObjBegin, ObjSize, FileNamePtr
  PfdllLoadPgm reads the exports from one DLL file (32bit or 64bit) mapped in memory, and creates imported symbols from them, as if statements `IMPORT ExportedName,LIB=DllName` were written in BasePgm.
Input
  BasePgm is pointer to an existing PGM to which the library is being imported.
  ObjBegin is pointer to the contents of imported file mapped in memory by the caller.
  ObjSize is number of bytes in the file.
  FileNamePtr is pointer to zero-terminated library file name (used in error reports).
Output
  Symbols which are exported from the loaded DLL file were imported to the BasePgm.
Error
  Errors are reported with macro Msg.
Invoked from
  PfLoad
Invokes
  PgmCreateImportModule

    PfdllLoadPgm Procedure BasePgm, ObjBegin, ObjSize, FileNamePtr
    NumberOfSections    LocalVar ; As specified in file header.
    RVA2Ptr             LocalVar ; Difference of mapped address from RVA.
    DLLPtr              LocalVar ; Ptr to volatile DLL name.
    DLLSize             LocalVar ; Number of bytes in DLL name.
        MOV ESI,[%ObjBegin] ; Pointer to the start of file in mapped memory. FileAddress FA=0.
        MOV ECX,[%ObjSize]
        LEA EDX,[ESI+ECX] ; ObjEnd in mapped memory. Procedure may read only data below EDX.
        ADD ESI,[ESI+PFMZ_DOS_HEADER.e_lfanew] ; Add FA of PE signature.
        CMP ESI,EDX
        JNB .E8535: ; Report error if file too short.
        LODSD
        CMP EAX,'PE' ; Check the PE/DLL signature.
        JNE .E8535:
        MOVZXW ECX,[ESI+PFCOFF_FILE_HEADER.NumberOfSections]
        MOVZXW EBX,[ESI+PFCOFF_FILE_HEADER.SizeOfOptionalHeader]
        MOVZXW EAX,[ESI+PFCOFF_FILE_HEADER.Characteristics]
        MOV [%NumberOfSections],ECX
        JECXZ .E8535: ; If no sections in file.
        ADD ESI,SIZE# PFCOFF_FILE_HEADER ; Skip the file header.
        ADD EBX,ESI
        CMP EBX,EDX
        JNB .E8535:
        MOV EDI,[ESI+PFPE_OPTIONAL_HEADER32.DataDirectory+pfpeDIRECTORY_ENTRY_EXPORT*SIZE#PFPE_DATA_DIRECTORY+PFPE_DATA_DIRECTORY.VirtualAddress]
        MOV ECX,[ESI+PFPE_OPTIONAL_HEADER32.DataDirectory+pfpeDIRECTORY_ENTRY_EXPORT*SIZE#PFPE_DATA_DIRECTORY+PFPE_DATA_DIRECTORY.Size]
        JNSt EAX,pfcoffFILE_LARGE_ADDRESS_AWARE,.15:
        MOV EDI,[ESI+PFPE_OPTIONAL_HEADER64.DataDirectory+pfpeDIRECTORY_ENTRY_EXPORT*SIZE#PFPE_DATA_DIRECTORY+PFPE_DATA_DIRECTORY.VirtualAddress]
        MOV ECX,[ESI+PFPE_OPTIONAL_HEADER64.DataDirectory+pfpeDIRECTORY_ENTRY_EXPORT*SIZE#PFPE_DATA_DIRECTORY+PFPE_DATA_DIRECTORY.Size]
    .15:MOV ESI,EBX ; ESI now points to the first section header.
        JECXZ .E8535:
        ; Enumerate sections and find FA of ExportTable in the loop .20: .. .30:.
        MOV ECX,[%NumberOfSections]
    .20:MOV EAX,[ESI+PFCOFF_SECTION_HEADER.VirtualAddress]
        CMP EDI,EAX
        JB .30:
        ADD EAX,[ESI+PFCOFF_SECTION_HEADER.VirtualSize]
        CMP EDI,EAX ; Does the export table lay in section with header ESI?
        JB .40: ; If section found. Usually it is [.edata] or [.text].
    .30:ADD ESI,SIZE#PFCOFF_SECTION_HEADER ; Otherwise try the next section.
        LOOP .20:
    .E8535:Msg '8535',[%FileNamePtr] ; Format of file "!1$" is not importable.
        JMP .90:
    .40:MOV EAX,EDI ; EDI is RVA of export table residing in section whose header is mapped with ESI.
        SUB EDI,[ESI+PFCOFF_SECTION_HEADER.VirtualAddress] ; EDI is now offset of export directory table.
        ADD EDI,[ESI+PFCOFF_SECTION_HEADER.PointerToRawData] ; EDI is now FA of import tables.
        ADD EDI,[%ObjBegin] ; EDI is now ptr to import table mapped in memory.
        MOV ESI,EDI ; ESI now points to mapped PFPE_EXPORT_DIRECTORY.
        SUB EDI,EAX
        MOV [%RVA2Ptr],EDI ; Keep the difference of mapped address from its RVA.
        ; Find and store DLL name.
        MOV EDX,[ESI+PFPE_EXPORT_DIRECTORY.Name]
        ADD EDX,[%RVA2Ptr]
        GetLength$ EDX
        MOV [%DLLPtr],EDX
        MOV [%DLLSize],ECX
        SUB EDX,EDX ; Index of export (0,1,2,3,4...).
        MOV ECX,[ESI+PFPE_EXPORT_DIRECTORY.AddressOfNames] ; RVA of Name ptr table (NPT).
        ADD ECX,[%RVA2Ptr] ; Pointer to NPT in memory.
        MOV EAX,[ESI+PFPE_EXPORT_DIRECTORY.AddressOfOrdinals]
        ADD EAX,[%RVA2Ptr] ; Pointer to ONT in memory.
        ; Create import module of each export.
        ; EDX=zero-based index, EAX=^ONT,  ECX=^NPT, ESI=^PFPE_EXPORT_DIRECTORY.
    .50:CMP EDX,[ESI+PFPE_EXPORT_DIRECTORY.NumberOfNames]
        JAE .90:
        PUSH EAX,ECX
          LEA EAX,[EAX+2*EDX] ; EAX is now pointer to word ordinal number.
          MOVZXW EDI,[EAX] ; Ordinal number.
          ADD EDI,[ESI+PFPE_EXPORT_DIRECTORY.Base]
          LEA EAX,[ECX+4*EDX] ; EAX is now pointer to RVA of ASCIIZ symbol name.
          MOV EBX,[EAX] ; RVA of ASCIIZ name.
          ADD EBX,[%RVA2Ptr] ; Convert RVA to memory pointer.
          GetLength$ EBX
          Invoke PgmCreateImportModule::,[%BasePgm],[%DLLPtr],[%DLLSize],EDI, \
                 symImport+'A',EBX,ECX,EBX,ECX
        POP ECX,EAX
        INC EDX
        JMP .50:
    .90:EndProcedure PfdllLoadPgm

      ENDPROGRAM pfdll

▲Back to the top▲