LINK Fails with error: LINK : fatal error LNK1000: unknown error

Started by fantasia, February 13, 2012, 06:28:41 PM

Previous topic - Next topic

fantasia

Hello everyone!

I wonder if anyone might advise me as to how I might resolve an issue I have with LINK.EXE.

Consider a source code file assembled as follows:
ml /c /coff /Zi bare_bones.asm

I find no difficulty linking the object file like this:
LINK /LIBPATH:"c:\Irvine" "user32.lib" "irvine32.lib" "kernel32.lib" /SUBSYSTEM:CONSOLE bare_bones.obj

However, when I try to produce a DEBUG build i.e.
LINK /DEBUG /LIBPATH:"c:\Irvine" "user32.lib" "irvine32.lib" "kernel32.lib" /SUBSYSTEM:CONSOLE bare_bones.obj

I get a weird error message that I don't really know how to tackle, namely:
LINK : fatal error LNK1000: unknown error; consult documentation for technical support options

Please help.

Thanks

dedndave

lol
that is a pretty useless error message   :P
i have seen it before although i don't recall the details

this may help
we generally do not attempt to specify libpath's or lib's on the command line
you can put them in the source file
a typical ASM source might start out like this
      .486                                      ; create 32 bit code
      .model flat, stdcall                      ; 32 bit memory model
      option casemap :none                      ; case sensitive

;     include files
;     ~~~~~~~~~~~~~
      include \masm32\include\windows.inc       ; main windows include file
      include \masm32\include\masm32.inc        ; masm32 library include

    ; -------------------------
    ; Windows API include files
    ; -------------------------
      include \masm32\include\gdi32.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\Comctl32.inc
      include \masm32\include\comdlg32.inc
      include \masm32\include\shell32.inc
      include \masm32\include\oleaut32.inc
      include \masm32\include\ole32.inc
      include \masm32\include\msvcrt.inc

      include \masm32\include\dialogs.inc       ; macro file for dialogs
      include \masm32\macros\macros.asm         ; masm32 macro file

;     libraries
;     ~~~~~~~~~
      includelib \masm32\lib\masm32.lib         ; masm32 static library

    ; ------------------------------------------
    ; import libraries for Windows API functions
    ; ------------------------------------------
      includelib \masm32\lib\gdi32.lib
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
      includelib \masm32\lib\Comctl32.lib
      includelib \masm32\lib\comdlg32.lib
      includelib \masm32\lib\shell32.lib
      includelib \masm32\lib\oleaut32.lib
      includelib \masm32\lib\ole32.lib
      includelib \masm32\lib\msvcrt.lib


Kip has included many of these files in his inc file

also, see if you can get it to build properly without the debug stuff - then try it with

fantasia

Thanks, dedndave! I'll defintiely give that a try and let you know how it goes.

It's weird: It does link when I leave out the /DEBUG switch!

Irvine suggests on his website that you use his visual c++ 2010 project template to assemble and link, but I'm desperately trying to fly the nest! My intention is to start off creating projects using qeditor.  I also want to use Irvine's library (so I cancontinue following the book's examples), but I'd like to know how to get the debug builds working.

Really I guess I'm asking if you know how I might gain a better understanding of LINK.EXE so I can figure out why it won't build when DEBUG is specified?

Thanks again.

jj2007

There are some assembler+linker combinations that don't fly with symbols. Higher Masm versions make trouble. The best combi is Jwasm plus the link.exe version that comes with Masm32. Alternatively, use ML.exe version 6.15

I use these command line options with RichMasm, and Olly is happy with them:
OPT_DebugA /Zi ; activate symbols
OPT_Assembler Jwasm ; must be present in \bin
OPT_DebugL /debug ; for debugging
OPT_Linker link ; version 6.14, must be present in \bin

fantasia

Thanks jj2007.

I've not heard of Jwasm until now (i'm not very experienced, as you've no doubt realised).

Before I move onto another assembler and linker combination, I'd really like to know why the debug build won't work for me.  As far as I am aware, when I use Irvine's Visual C++ 2010 project template, I am indirectly using ML and LINK.  When I run these from the command line the DEBUG build fails with the vague error described in my first post. 

I'm really stuck :-(

MichaelW

What are the versions of the ML and LINK that you are using, and what is in your source file?

Using ML 6.15.8803 and LINK 5.12.8078, with a known-good test source, and similar command lines less the /LIBPATH option, everything appears to work as it should.

You could try putting the necessary libraries in your working directory and eliminating the /LIBPATH option.


eschew obfuscation

fantasia

Hi MichaelW

I am using: "Microsoft (R) Incremental Linker Version 5.12.8078"

As for the version of ML.EXE: I don't know, sorry, but the ML.EXE is dated 29/03/1999, if that helps?

I copied all libraries into my working directory but I still get the same result.  Release build works :-) but the debug build does not :-(

I wondered if it had something to do with LINK not being able to generate debug symbols for the kernel32, user32, gdi32.lib libraries, but this is based on nothing but my naive instinct.

Also, I have attached my source file.

Thanks

fantasia

I don't know if this will throw any new light on the matter - but in my desperation to try anything - I tried to produce a debug build using Polink.  The debug build failed (again) but with a seemingly more specific error i.e.:

\Masm32\Bin\Polink @"C:\Users\adamg\Dropbox\assembly\MASM\masm32\templates\link.war"

Writing debug information
POLINK: fatal error: Unknown kind (0x0) of CodeView symbol in object 'Irvine32.lib(Irvine32.obj)

I don't know what this means?

Thanks

dedndave

i think i have all the pieces of Kip's latest stuff   :P
one problem i noticed is...
he has set everything up to run with visual studio 2005/8/10 - including the debug stuff
so - i have to ask - do you have visual studio ?

anyways, i am playing with it - let me see if i can build it...

fantasia

Hi dedndave!

I hope you don't think I'm being a pain, but I would like to move away from using Visual Studio (I've been using 2010). 

It's clear to me that Visual Studio (as configured according to Irvine's suggestions) has taken care of a lot of the linker's details, and I would like to learn how to do this myself.  The trouble is though, I don't know how to start learning about the linker and how it handles debug builds differently from release builds :-)

I really appreciate your help. Hopefully I will be able to help others in the same way when I accrue enough experience.

Thanks

MichaelW

Quote from: fantasia on February 13, 2012, 10:04:50 PM
Also, I have attached my source file.

Using your source, renamed to test.asm, and this batch file:

ml /c /coff /Zi test.asm
pause
:LINK "user32.lib" "irvine32.lib" "kernel32.lib" /SUBSYSTEM:CONSOLE test.obj
:pause
LINK /DEBUG "user32.lib" "irvine32.lib" "kernel32.lib" /SUBSYSTEM:CONSOLE test.obj
pause


I get no errors, but when I run the EXE it triggers a divide by zero exception. I think you need to pass a range value in EAX. This from the (probably outdated) irvine32 source that I have, and that I used to build the irvine32 static library that I am using:

;--------------------------------------------------------------
RandomRange PROC
;
; Returns an unsigned pseudo-random 32-bit integer
; in EAX, between 0 and n-1. Input parameter:
; EAX = n.
; Last update: 09/06/2002
;--------------------------------------------------------------
push  ebx
push  edx

mov   ebx,eax  ; maximum value
call  Random32 ; eax = random number
mov   edx,0
div   ebx      ; divide by max value
mov   eax,edx  ; return the remainder

pop   edx
pop   ebx

ret
RandomRange ENDP


As for your problem, I suspect that it may be in one of the libraries. I'm using the MASM32 import libraries for user32 and kernel32, and as I stated above an irvine32 static library that I built.
eschew obfuscation

fantasia

Hi MichaelW.

That's the first time I've seen a batch file being used for assembling and linking - thanks!

With the batch file the end result is still the same: the debug linking fails, the release does not.

Maybe I am using your batch file incorrectly? Running the BAT seems to progress in three stages, each stage punctuated by a prompt saying "press any key to continue...".  Should I be waiting for a long time between each stage?

Thanks again.

dedndave

welllll
the problem i am seeing is with the orginization of Kip's include files, actually
and the PATH issue

first, the INC problem:
Kip's "bare" example, b32.asm, starts out like this...
INCLUDE Irvine32.inc
that tells me something right off
he is assuming that the visual studio installation has set the INCLUDE and LIB environment variables (and probably PATH)
setting that aside for a moment, let's continue with the first few lines of Irvine32.inc...
; Include file for Irvine32.lib             (Irvine32.inc)

;OPTION CASEMAP:NONE ; optional: make identifiers case-sensitive

INCLUDE SmallWin.inc ; MS-Windows prototypes, structures, and constants
INCLUDE VirtualKeys.inc

and the first few lines of SmallWin.inc...
.686P ; Pentium Pro or later
.MODEL flat, stdcall
.STACK 4096

i noticed 2 things right away:
1) the OPTION CASEMAP:NONE directive is commented out, and in the wrong place, anyways   :P
2) it's probably not a good idea to specify a stack size in a 32-bit flat asm program, unless you have a specific reason
however, for our trivial program, a 4 kb stack is sufficient
typically, the linker sets this to some much larger size by default

funny thing that i hadn't noticed before
if you include an INC file that has more INC files, it looks in the folder specified for the first for the others

to make things work, i would suggest commenting out the .STACK 4096 line in SmallWin.inc
not the cause of the problem - but it will give you headaches in the future

another modification you can make is to add:
       OPTION  CaseMap:None
right where the STACK directive was

for testing, i added it to the source file....
        INCLUDE    \Irvine\Irvine32.inc
        OPTION     CaseMap:None

        INCLUDELIB \Irvine\kernel32.lib
        INCLUDELIB \Irvine\user32.lib

;#######################################################################

        .DATA

szTest  db 'Test',0

;#######################################################################

        .CODE

;***********************************************************************

_main   PROC

        INVOKE  MessageBox,NULL,offset szTest,offset szTest,MB_OK
        exit

_main   ENDP

;#######################################################################

        END     _main


this particular program may be built as either a CONSOLE or WINDOWS mode app

notice that i did not specify the drive letter - only the root-relative path
that's how Hutch does things with the masm32 package, so i went the same direction for compatibility

then, i use the following command lines to build
i am using the same versions of MASM and LINK as you are
ml /c /coff /Zi MyProg.asm
link /SUBSYSTEM:CONSOLE /DEBUG MyProg.obj


here is a batch file for assembling debug/console apps
it assumes that ML and LINK are in the PATH
@echo off
if exist %1.obj del %1.obj
ml /c /coff /Zi %1.asm
if exist %1.exe del %1.exe
link /SUBSYSTEM:CONSOLE /DEBUG %1.obj
if exist %1.obj del %1.obj
dir %1.* /o-d

dedndave

now for the environment variables...

masm and link will inspect a few variables to get the default paths of libraries and include files
LIB and INCLUDE
if you have those set up permanently, fine
if not, it may be best to set them temporarily in the batch file
that way, they do not conflict with any compiler you may be using
@echo off
SET LIB = C:\Irvine
SET INCLUDE = C:\Irvine
if exist %1.obj del %1.obj
ml /c /coff /Zi %1.asm
if exist %1.exe del %1.exe
link /SUBSYSTEM:CONSOLE /DEBUG %1.obj
if exist %1.obj del %1.obj
dir %1.* /o-d


you can use the SETLOCAL batch command, but it isn't necessary
because when using SET in a batch file, the variables only live as long as the console window

fantasia

dedndave!

THANK YOU: you have freed me from Visual Studio.

I know I am way behind you and will probably never catch up, but I one day I hope to repay you.

Cheers  :dance: