Version 0.26.10 | by Jeremy Gordon - |
GoLink @command.fil ;example with one command file GoLink @hello @goodbye.def ;example with two command filesA command file must be a text only file containing one or more lines of instruction. It may be in ANSI, Unicode UTF-8BOM (Windows UTF-8) or Unicode UTF-16LE format. You can include comments in a command file because anything after a semi-colon on a line is ignored. You can therefore comment-out lines which temporarily you don't need. For example:-
MyProg.obj ;link this file to make MyProg.exe ;/debug coff ;use this line to add embedded debug information MyProg.res ;use this file for resource input
Kernel32.dll User32.dll Gdi32.dllthese are for the common controls and common dialog APIs:-
COMCTL32.dll comdlg32.dllyou may also need to use these:-
OLEAUT32.dll Hhctrl.ocx winspool.drv shell32.dllThere are of course several other system DLLs. You can find out which DLL holds the API you want to use by looking in the documentation for the API in the Windows Software Development Kit (SDK), available free from Microsoft see my web site for a link.
You can see how many imports from your program are coming from each DLL by using the /files switch in the command line or a command file.
You can see the path of the file used and also its creation date and time and its size by using the /files switch in the command line or a command file. Note that dates and times are adjusted to allow for the current daylight saving time setting on the computer running GoLink.
GoLink @command.fil > filenameThe format of the file created by GoLink may differ. The rules are:-
The command line switches you can use are as follows:-
/b | = beep on error |
/base xxxx |
= set image base (use hex) eg. /base 50000 sets the expected image base to 50000h.
This sets where, in virtual memory, you would like the executable to be loaded (the image base). If you do not set this value GoLink uses a default of 400000h for EXEs, 10000000h for DLLs and 10000h for drivers. You will not normally need to set this value when making an EXE because each loaded EXE has its own virtual memory. This means that at any one time a number of programs can be running, all with the same image base, and there will be no conflict between them. But if the EXE relies on DLLs the Windows loader will also load these DLLs into the virtual memory of the EXE. Inside the DLL, GoLink will have written certain addresses on the assumption that the DLL would be loaded at the expected base address. If the DLL cannot be loaded at that expected base address (because it is occupied by another DLL) the loader will have to load it at another address. If that happens, the loader will need to write over the addresses inserted by GoLink. These addresses which require changing are called base relocations. Clearly this process takes time during loading and you can help to speed up the loading process by specifying your own base address for your DLLs. This will ensure that the DLL will actually be loaded at the expected base address. I would suggest using the area 10000000h to 60000000h (the system itself tends to use the area outside these values). Ensure your value is rounded up to a 64K boundary. You can use GoBug (inspect/search promenade memory/promenade) to check where the operating system is loading your DLLs. It is interesting to note that the System DLLs themselves use this staggered base address system. Usually this is in the memory area of 80000000h and above. GoLink inserts base relocation information in the executable only if you use the /base xxxx switch, or if you are making a DLL or a driver. |
/console |
= make a console executable.
This sets a flag in the executable telling the Windows loader that the executable will not rely on the Windows GUI (Graphic User Interface). In practice this means that the executable will not be given a message queue and that it will not require memory to be set aside for creating windows and the resulting device contexts. On the other hand the executable will be automatically provided with a "console" by the loader, allowing input from and output to the various devices connected to the computer. Because of the lower overhead, console applications tend to load and exit more quickly than graphics applications. |
/debug coff |
= add embedded coff debug information to the final executable.
GoLink's debug output is tailored to what is required by assembler programmers. Basically every symbol known to the linker is put in the debug information together with its value. This can then be used to bring the program to life under debug control, using GoBug or other debuggers which accept coff debug information. |
/debug dbg |
= place coff debug information in a dbg file.
If this switch is used, GoLink places the coff debug information in a file in .dbg format in an "exe" or "dll" sub-folder depending on what type of executable is being made. The sub-folder is used to ensure that there is no mix-up between the main EXE and its DLLs. So for example MyProg.exe will have its debug information placed in exe\MyProg.dbg and MyProg.dll will have its debug information placed in dll\MyProg.dbg. |
/dll |
= make a DLL.
GoLink makes a DLL if either this switch is used or if using the /fo switch you specify an output file with the extension DLL. If neither of these apply and you are not making a driver, GoLink makes an EXE. GoLink inserts base relocation information in the executable only if you use the /base xxxx switch, if you are making a DLL or a driver. |
/driver |
= make a driver.
GoLink makes a driver if either this switch is used or if using the /fo switch you specify an output file with the extension SYS. GoLink does not set the WDM flag, unless /wdm is specified. See also making a Windows Driver Model driver and specifying the uponly flag. GoLink inserts base relocation information in drivers. |
/e |
= empty output file allowed.
Using this switch you can make a "shell" PE file which will have all the necessary formal parts but no sections. |
/entry xxxx |
= set program entry point to xxxx.
For example, /entry main will start the program at the code label "main:". If you do not specify the entry point with this switch GoLink assumes START will be used (in upper or lower case or a mixture). So if you want to use this default you should ensure that your code has the label "START:" at the correct place to start execution. Every EXE file needs an entry point, but in DLLs it is optional. GoLink warns you if it cannot find the entry point in your executable. For compatibility with Microsoft tools, GoLink also recognises the entry point specified at assemble time using END. This information is passed to the linker using the .drectve section. |
/export xxxx |
= specify exported functions, data and ordinals.
See exporting procedures and data |
/files |
= report in detail on files used and created
This option reports the full paths, file dates and times and sizes of the files used during the linker process and of the output files. There is other useful information such as the number of imports, exports and debug symbols. Note that all file times are adjusted to allow for the current daylight setting time of the computer running GoLink. |
/fo |
= specify output path/file.
If the output file and path is not specified, GoLink assumes that the output file should be an EXE, and should have the same name and path as the first object or res file. You can use the /fo switch to change these defaults, for example /fo MyProg.exe or /fo MyProg.dll or /fo c:\exe\MyProg.exe. |
/h or /? | = show a screen displaying these various options only. |
/mix |
= link input files and lib code made with a compiler which decorates symbols.
Part of the baggage of a "C" compiler, and of the MASM assembler, is the decoration of symbols in the object files which they produce. Examples are:- _MessageBoxW@16 (indirect call to an API where there are four parameters) __imp__GetKeyState@4 (direct call to an API where there is one parameter) _MyDataLabel (simple decoration applied to a data label) _MyCodeLabel (simple decoration applied to a code label) _MyCodeLabel@4 (decoration applied to a code label declared as having one parameter) The idea behind the _Name@xx decoration is that it provides a check that the number of parameters declared for a function is the same between the various modules (object files). In practice however, the added complexity of the required source code (eg. in MASM the need for EXTRN, EXTERN or PROTO to define the type of symbol) is very much out of proportion to the benefits achieved. Some compilers also use decoration to enhance error reporting, but this has another problem: there is no consistent format for this. Because GoAsm does not decorate symbols (unless the GoAsm /ms switch is used), GoLink does not expect symbol decoration. This means that if you want to use GoLink to link files made with a third party compiler which decorates symbols you must specify the /mix switch. This will cause GoLink to strip out decoration when comparing symbol names. If you use the /mix switch, you will be unable to use a single leading underscore intentionally to differentiate between symbols. For example GoLink will regard _DOG and DOG as the same name. If the /mix switch is used, symbols of types IMAGE_SYM_CLASS_STATIC and IMAGE_SYM_CLASS_LABEL will be limited to the module (object file) in which they appear, as expected by third party compilers. Otherwise, if these types have the same name GoLink will complain about duplicate symbols. The /mix switch may also resolve problems if you have merged in a GoAsm module static library code made with such third party tools. If such code calls or references other such merged code, it is possible that this will be done with decorated symbols. These would not be recognised by GoLink unless the /mix switch is used. |
/more |
= show console screenful then wait for input
See screen output - controlling, limiting and redirecting. |
/mslu |
= insert loader code for Microsoft Layer for Unicode.
This switch causes GoLink to add Microsoft Layer for Unicode ("mslu") loader code to the executable at link-time. If you are making an EXE file this code executes automatically immediately after your application loads (the entry point of your EXE is changed to the beginning of the loader code). If you are making a DLL GoLink adds the loader code as a function within the DLL called MSLU_LOADER which your EXE must call (only once) when convenient (certainly before using a function in the DLL which might need mslu). A convenient time in most cases will be to call MSLU_LOADER just after your EXE starts by using eg. CALL MSLU_LOADER. If you have more than one Dll which contains mslu loader code you can call each specifically using the sytax CALL DllName:MSLU_LOADER. The way the loader code works is this. Upon loading your application the system loader will have written the addresses of all the imports (APIs and other external calls) to the image of your EXE or DLL in memory. These addresses are only known at load-time as the system and other DLLs are loaded in your application's address space. If your application is being run under Windows 95, 98 or ME the mslu loader code added by GoLink will overwrite the relevant addresses to point to unicows.dll, rather than to the system DLLs. Unicows.dll contains wrappers around the NT, 2000 and XP versions of those APIs which are not fully supported under Windows 95, 98 or ME. Using mslu means that you may write just one version of your application (using the unicode APIs) to run under all versions of Windows. Under Windows 95, 98 or ME all the necessary conversion code (usually translation of strings from Unicode to Ansi and vice versa) is carried out in unicows.dll. If your application is being run under Windows NT, 2000 or XP then no action is taken by the loader code and unicows.dll will not be loaded at all by your application. For more information about the mslu see my help file The Microsoft Layer for Unicode. |
/msludll xxxx |
= mslu loader to use this name for unicows.dll.
This switch informs GoLink that you have changed the name of unicows.dll to the name specified. If this switch is used, GoLink does not look for unicows.dll at link-time but looks for the named file instead. Similarly at run-time the mslu loader will look for the named file instead. Also the mslu loader error messages will refer to the named file and not to unicows.dll (nor to the Microsoft download site). |
/msluerr xxxx |
/msluerr filename = specify a text file holding the mslu error message or
/msluerr off = switch off the error action altogether The Golink mslu loader code default action is to display an error message to the user and cause your application to exit if one of these events occurs:- 1. The unicows.dll is not found. It is looked for using the same search order as other DLLs. 2. Unicows.dll is found but is damaged. 3. An API which should be in unicows.dll is not there. The loader has a list of APIs found to be in unicows.dll at link-time and expects all of them to be in the unicows.dll found at run-time. The error message is in a message box in a GUI application or written to the console in a console application. The error message states that the application needs unicows.dll to run, that it should be placed in the same folder as the application, and that it is available from the supplier of the application or from microsoft via a link. You may prefer to use your own message instead of this default and if so, you can specify it using this switch. The file should be an ordinary Ansi text file. For example, if you want to use error.txt, you would specify the switch /msluerr error.txt You may wish to stop GoLink from giving the error message and ending the process on the happening of one of the above events. You can do this by specifying /msluerr off. If you use this switch, then your application will continue to run even if unicows.dll is not found or is found to be damaged or if expected APIs are missing. The mslu loader code indicates whether the unicows.dll load was successful. In your EXE this indication appears in the EAX register at the normal entry address for your program. In your DLLs EAX is set upon the return from the call to MSLU_LOADER. The values held in EAX are:- EAX=0 load successful EAX=1 unicows.dll not found EAX=2 unicows.dll found but damaged EAX=3 an API expected in unicows.dll not foundIf you change the name of the unicows.dll file you can inform GoLink of this using the /msludll switch. |
/ne
/ni /nw /no |
= no error messages.
= no information messages. = no warning messages. = no output messages at all. If you are using a makefile you may wish to suppress output messages and rely only on GoLink's exit code (error=1), or you may simply wish to reduce the output information. In a batch file, you can use the error return with ERRORLEVEL, for example the following will pause if there is an error return:- GoLink @command.fil IF ERRORLEVEL 1 PAUSEError messages are those which will stop GoLink from making the executable and include:- Insufficient memory; incorrect use of command line switches; unable to open or read a specified file; files in wrong format or corrupted; incorrect information given for output file; unable to make output file; specified entry point not found or not in a code section; duplicate Resource Type, nameID or Language found in res file; no defective or duplicate ordinal number if direct import/export by ordinal; symbols declared more than once; symbols not declared at all; exported symbols not found. Information messages are copyright and output information. Warning messages do not stop the executable being made. They include entry point not found and no exports in a DLL. See also screen output - controlling, limiting and redirecting. |
/stackinit xxxx |
= initial stack commitment on start-up and on new threads.
Here you can specify the size in bytes (using hex) of the amount of memory which the system should commit for the stack when the application starts or when making a new thread. If you do not use this switch a value of 10000h (64KB) is used by default. Regardless of the value specified using this switch the system always enlarges the amount of committed memory in the stack in 4K chunks as the application needs it. This switch may be used if your application needs to create space for a large amount of local data. Without this switch an exception could occur if your local data is larger than 4K. The reason for this is that the system uses Structured Exception Handling to manage the enlargement of the stack as and when it is needed, and it does this by establishing guard pages just adjacent to and deeper into the area of stack already committed. If your application attempts to write or read from a place beyond these guard pages, a true exception will occur rather than a signal to the system to create more stack. In experiments the size of the guard pages seems to vary but it is unlikely that it could ever be below 4K which is the normal page size. |
/stacksize xxxx |
= stack allocation size on start-up or on new threads.
Here you can specify the size in bytes (using hex) of the area of memory which the system should allocate for potential stack use, should the application require it. If you do not use this switch a value of 100000h (1MB) is used by default. At start-up the system merely allocates space in virtual memory and only a small amount is committed at first. The system commits the remainder automatically in 4K chunks if the application needs it. The value given with this switch applies both to the main thread of the application and also any new threads it makes. This switch may be used if your application might need more than 1MB of stack space. Specifying more than 1MB does not use memory unnecessarily since the memory is only committed if it is actually used. Normally 1MB is more than sufficient for the stack, but you would need this switch if you were keeping large amounts of local data on the stack in procedures which were highly recursive. |
/unused |
= report on unused/unreferenced labels
this only works with GoAsm object files or "Go" compatible object files see technical note. If this switch is used, GoLink will report on those data and code labels which have not been referenced in any way. Such redundant data declarations or code are easily left in the source code by mistake during development of a program. Now you can discover these and weed them out. |
/uponly |
= specify the uponly flag.
This sets the IMAGE_FILE_UP_SYSTEM_ONLY flag which indicates to Windows that the file (usually a driver) may only be used on single-processor machines. |
/version xxxx |
= set image version to major minor value
This is a 32 bit hex value so /version 20001 sets major version value to 2 and minor version value to 1. |
/wdm |
= make a Windows Driver Model driver.
GoLink makes a WDM driver if this switch is used. This is a driver which is designed for multiple Windows platforms. It is not necessary to specify the /driver flag as well. See also making a driver and specifying the uponly flag. |
MOV EBX,[DATA_VALUE] ;get pointer to DATA_VALUE MOV EAX,[EBX] ;get the valueIn the same way as for importing procedures from other programs at link-time you give GoLink the name of the executable containing the import.
Using GoLink and its companion program GoAsm, you can import by ordinal using this simple syntax in the assembler source script:-
CALL MyDll:6This will call procedure number 6 in MyDll.dll. The way this works is that GoAsm simply passes the symbol "MyDll:6" to GoLink in the object file. GoLink knows this is an import by ordinal because of the presence of the colon. Note that the extension "dll" is assumed if no extension is given. Suppose you want a DLL to call a function in the main executable by ordinal, then you could use:-
CALL Main.exe:15This calls the 15th function in Main.exe.
CALL [Main.exe:15]You should not include the path of the file in the call. GoLink will look for the file using the same search order as when looking for DLLs. If it is necessary to provide a path this should be provided in the command line or in a command file rather than incorporated in the call in the assembler script.
For example, if you do not want to call EnableWindow within unicows.dll under any circumstances, but always call EnableWindow within User32.dll you would use:-
User32:EnableWindow
/EXPORT LOAD_ELEMENT /EXPORTS CALCULATE, ADJUST_DATA, DATA_VALUEHere three functions are exported, and then a data pointer is exported. Only the symbol name is needed - there is no need to tell GoLink whether the symbol is in a code or data section.
In order to use this method clearly it is imperative that the exporting program specifies an ordinal value for a particular export and the linker must not change this.
This can be done very easily, for example:-
/EXPORTS CALCULATE:2, DATA_VALUE:6Here GoLink is instructed to use the ordinals 2 and 6 for the exports.
/EXPORTS CALCULATE:2:NONAME, DATA_VALUE:6:NONAMEHere 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. This works for data as well, as in this example.