EuroAssembler Index Manual Download Source Macros


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.
INCLUDEHEAD  \  ; Include headers of another modules used in this module.
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,     \
syswin.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▲