#198 ✓resolved
Peter Johnson

32-bit fixup in Win64 .obj

Reported by Peter Johnson | June 25th, 2011 @ 07:52 PM

Originally posted on Trac by Martin Sander Martin@MartinSander.de
Original Trac Ticket


When in startup-default mode for win64, i.e. ABSOLUTE, the following code,

(in code section:)

mov rax, [symb]


(in data section:)

symb dq 12345678h

is assembled without problems, but the Visual Studio linker complains about a ADDR32 fixup.
Work-around: set YASM do DEFAULT rel mode.
1) Why does this work? (relative mode is relative to rip, which is the code pointer, not a data pointer)
2) Wouldn't it be better is YASM emitted correct code also in its default, i.e., abs mode?

In a similar vein, if I have to pass the address of one function to another by storing it, like

mov [_si], func

first YASM complains about non-matching sizes. Though YASM does not tell the truth here (anyway, how can it know?),
this one is easy to fix:

mov qword [_si], func

Now YASM likes what it sees, but again Visual Studio does not and complains again about ADDR32 fixup. For this problem,
I did not find any work-around.

Trac Attachments

h3. Trac Comments

              Changed 11 months ago by peter@tortall.net

RIP-relative means the address lookup is performed relative to the current instruction address (RIP), but that doesn't limit the resulting address to the code segment; the linker and loader adjust the displacement value such that the displacement is correct for the RIP of the instruction regardless of what segment the relocated value is in (it's all one big flat address space, and the linker+loader combined know what address each segment starts at).

Yasm does emit correct code for the abs mode, it's just that the linker requires you use RIP-relative relocations (e.g. REL32) instead of absolute relocations (e.g. ADDR32).  There's nothing Yasm can do about this beyond providing a convenient way to generate RIP-relative relocations by default (via the default rel directive).

With regards to "mov qword [_si], func", this doesn't work because the immediate value is 32 bits in size, thus creating an ADDR32 relocation for func.  Fortunately, there is one instruction that supports 64-bit immediates: "mov rax, qword func" will generate an ADDR64 relocation which should be accepted by the linker.  You can then follow this with "mov [_si], rax" to save this address elsewhere in memory.


              Changed 11 months ago by Martin Sander

Great, thanks for the quick answer!

Comments and changes to this ticket

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

The Yasm Modular Assembler Project

Shared Ticket Bins

People watching this ticket