News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Creating a .drectve section

Started by frisch, March 02, 2007, 05:57:45 PM

Previous topic - Next topic

frisch

Hello,

I'm trying to create a .drectve section. The obvious solution:


.drectve      SEGMENT DWORD USE32 PUBLIC
              BYTE 0,0,0,0
.drectve      ENDS


does not work because .drectve is not a valid symbol name.

How can I do it?

Apologies if the question is too basic for this forum. I'm new to MASM...

  -- Alain

Vortex

Hello Alain,

Welcome on board. Your question is a good one, please feel free to post here all your questions concerning asm.
The .drectve section is created in object files :

.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
MsgCaption      db "Iczelion's tutorial no.2",0
MsgBoxText      db "Win32 Assembly is Great!",0

.code
start:
invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
invoke ExitProcess,NULL
end start


\masm32\bin\ml /c /coff msgbox.asm
\masm32\bin\dumpbin /ALL msgbox.obj


SECTION HEADER #4
.drectve name
      9B physical address
       0 virtual address
      55 size of raw data
     177 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
     A00 flags
         Info
         Remove
         (no align specified)

RAW DATA #4
  00000000: 2D 64 65 66 61 75 6C 74 6C 69 62 3A 5C 6D 61 73  -defaultlib:\mas
  00000010: 6D 33 32 5C 6C 69 62 5C 75 73 65 72 33 32 2E 6C  m32\lib\user32.l
  00000020: 69 62 20 2D 64 65 66 61 75 6C 74 6C 69 62 3A 5C  ib -defaultlib:\
  00000030: 6D 61 73 6D 33 32 5C 6C 69 62 5C 6B 65 72 6E 65  masm32\lib\kerne
  00000040: 6C 33 32 2E 6C 69 62 20 2D 65 6E 74 72 79 3A 73  l32.lib -entry:s
  00000050: 74 61 72 74 20                                   tart

   Linker Directives
   -----------------
   -defaultlib:\masm32\lib\user32.lib
   -defaultlib:\masm32\lib\kernel32.lib
   -entry:start


Are you trying to use the full qualified 32-bit segmentation notation?

frisch

Hello,

Thanks a lot for your answer.

Actually, I'm trying to create the .drectve section by hand. My understanding is that the content of this section is passed to the linker as extra arguments (is it actually the case? where can I find this documented?). More precisely, I want to put "/export" directives to avoid the need for a .DEF file when creating a DLL. I guess this is what the C compiler does when it finds declspec(dllexport) attributes (again: I'd be happy to read some documentation about that), and I want to do the same for a compiler I'm working on. When I observe the ASM listing produced by the C compiler
(/Fa switch), I cannot see anything about exports (the listing is the same with or without declspec(dllexport)). With MinGW's gcc, I can see an explicit ".section .drectve" in the output of the compiler
(GNU assembler syntax).

In your example, how is the content of the .drectve section obtained from your code?  Is it possible to force the addition of  /export directives?

  Alain

Vortex

Alain,

Here is where you can find information about the .drectve section :

Microsoft Portable Executable and Common Object File Format Specification

http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx

Quote6.2.The .drectve Section (Object Only)
A section is a directive section if it has the IMAGE_SCN_LNK_INFO flag set in the section header and has the .drectve section name. The linker removes a .drectve section after processing the information, so the section does not appear in the image file that is being linked.
A .drectve section consists of a string of text that can be encoded as ANSI or UTF 8. If the UTF 8 byte order marker (BOM, a three-byte prefix that consists of 0xEF, 0xBB, and 0xBF) is not present, the directive string is interpreted as ANSI. The directive string is a series of linker options that are separated by spaces. Each option contains a hyphen, the option name, and any appropriate attribute. If an option contains spaces, the option must be enclosed in quotes. The .drectve section must not have relocations or line numbers.

GoAsm inserts the EXPORT statement in object module and GoLink can create DLLs without def files. Maybe, you could patch your Masm object file to insert the EXPORT statement and try to link it with GoLink to avoid def files.

SECTION HEADER #1
.drectve name
       0 physical address
       0 virtual address
      2C size of raw data
      64 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
     A00 flags
         Info
         Remove
         (no align specified)

RAW DATA #1
  00000000: 2F 45 58 50 4F 52 54 3A 53 74 64 4F 75 74 20 2F  /EXPORT:StdOut /
  00000010: 45 58 50 4F 52 54 3A 53 74 72 4C 65 6E 20 2F 45  EXPORT:StrLen /E
  00000020: 58 50 4F 52 54 3A 75 63 61 73 65 20              XPORT:ucase

   Linker Directives
   -----------------
   /EXPORT:StdOut
   /EXPORT:StrLen
   /EXPORT:ucase

manhattan

Unfortunately MASM doesn't let you declare segment names starting with a dot character. ml.exe can be patched to accept such names but even then the declared section doesn't have the right attributes to be accepted by the linker. I think FASM has better support for declaring section names and attributes.

Vortex

Alain,

Instead of def files, you can use the linker's EXPORT directive :

\masm32\bin\link /SUBSYSTEM:WINDOWS /DLL /EXPORT:LoadBitmapfromDLL /EXPORT:DeleteBitmapfromDLL Bitmap.obj Rsrc.res



[attachment deleted by admin]

frisch

Thanks for all these informations.

If I understand correctly, it is just impossible to produce a MASM source listing which does the same as the C declspec(dllexport) directive. This is very bad for people using MASM as the back end for a compiler.

Vortex: yes, I'm considering using the linker's EXPORT command line directive, but I've heard about a limit on the size of the command line (I might have hundreds of EXPORT directives). I guess I'll have to produce a DEF file, then...

Vortex

Frish,

You could code an MS COFF objet file patcher to add the EXPORT statements. This tool needs only to read the exported functions and modify the .drectve section.

Vortex

#8
Frish,

The easiest solution already exists, it's enough the specify the EXPORT statement in the procedure definition :

LoadBitmapfromDLL PROC EXPORT ResNumb:DWORD

    invoke  LoadBitmap,hInstance,ResNumb
    ret

LoadBitmapfromDLL ENDP


This is the output :

\masm32\bin\dumpbin /ALL bitmap.obj

.
.
Linker Directives
-----------------
-defaultlib:\masm32\lib\kernel32.lib
-defaultlib:\masm32\lib\user32.lib
-defaultlib:\masm32\lib\gdi32.lib
-export:_LoadBitmapfromDLL@4
-export:_DeleteBitmapfromDLL@4
-entry:LibMain@12
.
.

[attachment deleted by admin]

frisch

That's very cool. Thanks again. Do you know how to export similarly a symbol which is not a procedure?

Vortex

You are welcome. Unfortunately, the PUBLIC directive does not take any additional parameter to declare a symbol as an export.

jorgon

Hi frisch!

QuoteThat's very cool. Thanks again. Do you know how to export similarly a symbol which is not a procedure?

Exporting is easy with GoAsm, if you would like to migrate.  You can specify that a particular function (procedure) is to be an export either in the source code, or at link-time by giving the name to the linker in the command line, or in a separate command file, which will take any number of lines.  I am not sure if you mean a data label when you refer to exporting a symbol which is not a procedure.  But if you want to do this, you can export pointers to data as well.

This appears in the GoAsm help file:-

QuoteExporting procedures and data
You can make your procedures and your data available to other executables by exporting them. In Windows it is usual for Dlls to be used for exports, but sometimes a Dll will need to call a procedure or use data in an Exe file, and in that case the Exe file will also export. Exporting can be done either at link time (you tell the linker which symbols to export), or using GoAsm, you can also do it at assemble time. GoAsm then gives the linker the export information via the .drectve section in the object file (note that not all linkers support this).
There are two ways to declare exports in GoAsm. You can either declare all the exports at the top of your file (before any sections are declared) or you can declare them within your source code as you go along. You may use either or both of these methods to suit your own preference.
Here is an example of declaring all the exports before any sections are declared:-
EXPORTS CALCULATE, ADJUST_DATA, DATA_VALUE

Here is an example of declaring an export as you go along:-
EXPORT CALCULATE:
CMP EAX,EDX                ;code for the
JZ >4                           ;procedure

This code exports the label to the procedure CALCULATE.
If you prefer you can have the two words on separate lines for example:-
EXPORT
CALCULATE:
CMP EAX,EDX                ;code for the
JZ >4                           ;procedure

Exporting data
Data can only be exported indirectly. That is to say you can only export a pointer to data. However, using that pointer the importing program can get the data itself.
You may use exactly the same method to export a data label as used to export a code label. There is no need to declare the label as data or code. This is because it is the linker's job to check whether the label is within a data or code section. Here is an example of a data label export:-
EXPORT DATA_VALUE DD 0

This exports the data label DATA_VALUE. The recipient would obtain the value of DATA_VALUE in the following way:-
MOV EBX,[DATA_VALUE]       ;get pointer to DATA_VALUE
MOV EAX,[EBX]                    ;get the value

Exporting by ordinal
Normally exports are conducted by name. What happens here is that when the Windows loader starts the program it searches through the Dlls for the imports required by the program. This is done by comparing the names of the Dll exports against the names of the program's imports. To speed up this process with private Dlls sometimes exporting and importing by ordinal is used. Then the loader can find the correct import by using an index to a table within the Dll. Note that it is unwise to do this in the case of Windows system Dlls since the ordinal numbers of the exports are not guaranteed to be the same across different Dll versions.
In order to use this method it is clearly imperative that the exporting program specifies an ordinal value for a particular export and the linker must not change this. Again, using GoAsm you can specify the correct ordinal value and pass this to the linker via the .drectve section (not all linkers support this).
Here is how to specify an export by ordinal if exports are listed before any sections are declared:-
EXPORTS CALCULATE:2, DATA_VALUE:6

Here the linker will be instructed to use the ordinals 2 and 6 for the exports. If you are using the alternative method of declaring exports (within a section) you can use for example:-
EXPORT:2 CALCULATE:

or in the case of data:-
EXPORT:6 DATA_VALUE DD 0

Exporting by ordinal without a name
Exporting by ordinal does not stop the name of the export appearing in the final executable. This is because it is the importing program which decides whether to import by ordinal or by name. All the exporting program can do is to fix the ordinal value. However sometimes a programmer might like to ensure no name for the export appears in the final executable. You sometimes see such "no name" exports in system Dlls for example, probably in order to hide the job carried out by particular functions. In order to do this in GoAsm add the word NONAME to the end of the export for example:-
EXPORT:2:NONAME
CALCULATE:

Here the value of the code label CALCULATE will be exported as ordinal number 2, but the name of the export will not appear in the final executable. This means that if another program tried to call the CALCULATE function it would fail. The function can only be called by ordinal.

The "Go" tools have for some time permitted you to use Unicode data and code labels.  This means you can export code and data using labels in any language and script you want.
Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)