News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

More GoLink issues

Started by bartc, September 09, 2017, 08:43:36 PM

Previous topic - Next topic

bartc

A year ago I posted about an odd thing with Golink, where you have to do:

    mov rax,[puts]
    call rax


instead of this used with LD:

    mov rax,puts
    call [rax]

So I've changed my code to go along with the first example as now I'm mainly using Golink.

But the new problem is this: calling functions such as malloc() or HeapAlloc(), they are limited to 2GB of allocation (ie. 32 bits) even though the app is definitely 64-bit. With LD, no such problem (except that LD has strange bugs linking certain functions so am using Golink).

With Golink, it seems I have to use /largeaddressaware to get around that. But with that, the behaviour of mov rax,[puts]/call rax flips to the other! OK, I can change that.

Except that now, I can't write to any .bss data as it crashes. (Update: it seems reading or writing to any .bss or .data memory causes a crash. I'll see if I can put together an example.)

Does anyone know what's going on here?

bartc

Here's an example, written and assembled with Nasm, linked with Golink (I haven't shown here the issues with calling DLL functions via a pointer):


segment .data
abc:
dd 1234

extern puts
extern exit
segment   .text
global main
main:
sub rsp,40

; mov eax,[abc]

mov rcx, KK1
call puts

mov rcx,0
call exit

segment   .data
KK1:    db 'HELLO',0


With the mov eax,[abc] line commented out, it works. It can take the address of KK1, and puts can access the data as it prints the message. (The sub rsp,40 includes an 8-byte stack adjustment.)

But uncomment the mov eax,[abc] line, and it crashes. It was assembled and linked as follows in Windows 7 64-bit (with some Intel processor):


nasm -fwin64 test.asm
c:\go\golink /console /largeaddressaware /entry main -s /fo test.exe test.obj c:\windows\system32\msvcrt.dll

wjr

With /largeaddressaware GoLink sets an appropriate flag as well as an Image Base address of 140000000h which will result in such a crash if the assembler and/or programmer doesn't code with large address awareness. NASM is coding that instruction with a SIB byte and a relocation record in an 32-bit absolute address fashion. It will work if you don't use /largeaddressaware. If you do want that though, then using DEFAULT REL at the start of your NASM source seems to be the way to get the proper 64-bit RIP-relative addressing encodings and relocation records into the OBJ file.

bartc

Thanks, I put DEFAULT REL in front of the test example, and it worked!

That is, accessing 'static' data and using /largeaddressaware. I'll try applying it to my actual programs later.

(It does seem odd; I only need /largeaddressaware so that functions like malloc and HeapAlloc can be used to full capacity. Those allocations will ever be accessed via pointers. The program itself will be miniscule compared with even 2GB memory space, and direct memory accesses will always be within that space. I wonder why the program is located that high up?)

bartc

An update: I wasn't able to use 'default rel' in Nasm because it didn't appear to work for certain address modes.

But something more significant has come up: when I link something with Golink to produce an executable, then if I try and copy it anywhere (outside of my disk areas where I normally have Anti-Virus disabled), then my AV software says it contains an Evo-gen virus I think it called it.

I didn't pay too much attention, as the executables work, but today I also noticed that executable seem to run at about half the speed it ought to.

Linking exactly the same object files with another linker, (a separate LD, or another version which is part of gcc), I didn't get
those problems.

I upgraded Golink from 1.0.2.1 to 1.0.2.3, but it made no difference. I can understand the structure of the resulting .exe file may just happen to match this evo-gen virus, but I'm more worried about the loss of speed! And if I can't use Golink, then LD has its own problems; I might be stuck...

wjr

Instructions that refer to memory with a displacement and an index and/or scale*index register can not be encoded for RIP-relative addressing. These instructions need to be changed in order to use /largeaddressaware with a high Image Base. For example:


mov rax,[Symbol+rcx] ;does not use RIP-relative addressing

;could be changed to...

lea rax,[Symbol] ;uses RIP-relative addressing
mov rax,[rax+rcx]


However, without those changes, you can try using /largeaddressaware also with the GoLink /base 400000 command line option to set the Image Base back down to the default for 32-bit programs.