flat assembler
Message board for the users of flat assembler.

Index > Windows > Help - Is this a .reloc problem?

Author
Thread Post new topic Reply to topic
HyperVista



Joined: 18 Apr 2005
Posts: 691
Location: Virginia, USA
HyperVista 05 Apr 2007, 00:42
As most of you guys know, I'm trying to put together a demo hypervisor based on fasm. I have most of the set-up code written in fasm and working from within a Windows device driver. So far, so good.

I've slightly rewritten vid's stubbed out virtual machine control structure (VMCS) and have implemented it as a structure. I used a random fake org value just to put a value there for now. It compiles nicely.

However, when I link it into my device driver, I get a compiler error relating to "absolute symbol" and REL32 relocation. I'm thinking that it's related to .reloc section, but not certain. I've researched the nature of the error message and can only find references to processors other than x86. Any help or insight would be appreciated.

Here's the code and screen shot of the device driver compiler error:

Code:
format MS COFF

include 'c:\Dev Tools\fasmw 1.67.14\include\macro\struct.inc'

section '.text' code readable executable

public SET_VMCS as '_set_vmcs@0'

org 56785h



SET_VMCS:

align 1000h  ;must be 4KB aligned, in writeback cacheable memory

virtual at 0

struct VMCS

;header
.revision               dd ?    ; processor revision ID, found in low 32 bits of MSR 1152 (MSR_VMX_BASIC) 
.abort_indicator        dd ?    ; reason of VM exit 

;guest state area (2.4) 
.guest.CR0              dq ?    ; 64, quest CR0 
.guest.CR3              dq ?    ; 64, quest CR3 
.guest.CR4              dq ?    ; 64, quest CR4 
.guest.DR7              dq ?    ; 64, quest DR7 
.guest.RSP              dq ?    ; 64, quest RSP 
.guest.RIP              dq ?    ; 64, quest RIP
.guest.RFLAGS           dq ?    ; 64, quest RFLAGS 
.guest.CS.selector      dw ?    ; 16, quest CS selector 
.guest.CS.base          dq ?    ; 64, quest CS base address 
.guest.CS.limit         dd ?    ; 32, quest CS limit (in bytes) 
.guest.CS.rights        dd ?    ; 32, quest CS access rights 
.guest.SS.selector      dw ?    ; 16, quest SS selector 
.guest.SS.base          dq ?    ; 64, quest SS base address 
.guest.SS.limit         dd ?    ; 32, quest SS limit (in bytes) 
.guest.SS.rights        dd ?    ; 32, quest SS access rights 
.guest.DS.selector      dw ?    ; 16, quest DS selector 
.guest.DS.base          dq ?    ; 64, quest DS base address 
.guest.DS.limit         dd ?    ; 32, quest DS limit (in bytes) 
.guest.DS.rights        dd ?    ; 32, quest DS access rights 
.guest.ES.selector      dw ?    ; 16, quest ES selector 
.guest.ES.base          dq ?    ; 64, quest ES base address 
.guest.ES.limit         dd ?    ; 32, quest ES limit (in bytes) 
.guest.ES.rights        dd ?    ; 32, quest ES access rights 
.guest.FS.selector      dw ?    ; 16, quest FS selector 
.guest.FS.base          dq ?    ; 64, quest FS base address 
.guest.FS.limit         dd ?    ; 32, quest FS limit (in bytes) 
.guest.FS.rights        dd ?    ; 32, quest FS access rights 
.guest.GS.selector      dw ?    ; 16, quest GS selector 
.guest.GS.base          dq ?    ; 64, quest GS base address 
.guest.GS.limit         dd ?    ; 32, quest GS limit (in bytes) 
.guest.GS.rights        dd ?    ; 32, quest GS access rights 
.guest.LDTR.selector    dw ?    ; 16, quest LDTR selector 
.guest.LDTR.base        dq ?    ; 64, quest LDTR base address 
.guest.LDTR.limit       dd ?    ; 32, quest LDTR limit (in bytes) 
.guest.LDTR.rights      dd ?    ; 32, quest LDTR access rights 
.guest.TR.selector      dw ?    ; 16, quest TR selector 
.guest.TR.base          dq ?    ; 64, quest TR base address 
.guest.TR.limit         dd ?    ; 32, quest TR limit (in bytes) 
.guest.TR.rights        dd ?    ; 32, quest TR access rights 
.guest.GDTR.base        dq ?    ; 64, quest GDTR base address 
.guest.GDTR.limit       dd ?    ; 32, quest GDTR limit 
.guest.IDTR.base        dq ?    ; 64, quest IDTR base address 
.guest.IDTR.limit       dd ?    ; 32, quest IDTR limit 
.guest.MSR_DEBUGCTL     dq ?    ; 64, quest MSR_IA32_DEBUGCTL 
.guest.MSR_SYSENTER_CS  dd ?    ; 32, quest MSR_IA32_SYSENTER_CS 
.guest.MSR_SYSENTER_ESP dq ?    ; 64, quest MSR_IA32_SYSENTER_ESP 
.guest.MSR_SYSENTER_EIP dq ?    ; 64, quest MSR_IA32_SYSENTER_EIP 
.guest.activity_state   dd ?    ; 32, activity state (2.4.2) 
.guest.int_state        dd ?    ; 32, interruptibility state (2.4.2) 
.guest.debug_exceptions dq ?    ; 64, pending debug exceptions (table 2.4) 
.guest.VMCS_link        dq ?    ; 64, reserved, should be set to -1. (2.4.2) 

;host state (2.5) 
.host.CR0               dq ?    ; 64, host CR0 
.host.CR3               dq ?    ; 64, host CR3 
.host.CR4               dq ?    ; 64, host CR4 
.host.RSP               dq ?    ; 64, host RSP 
.host.RIP               dq ?    ; 64, host RIP 
.host.CS                dw ?    ; 16, host CS selector 
.host.SS                dw ?    ; 16, host SS selector 
.host.DS                dw ?    ; 16, host DS selector 
.host.ES                dw ?    ; 16, host ES selector 
.host.FS                dw ?    ; 16, host FS selector 
.host.GS                dw ?    ; 16, host GS selector 
.host.TR                dw ?    ; 16, host TR selector 
.host.MSR_SYSENTER_CS   dd ?    ; 32, host MSR_IA32_SYSENTER_CS 
.host.MSR_SYSENTER_ESP  dq ?    ; 64, host MSR_IA32_SYSENTER_ESP 
.host.MSR_SYSENTER_EIP  dq ?    ; 64, host MSR_IA32_SYSENTER_EIP 

;VM-execution control fields (2.6) 
.exec.controls          dd ?    ; 32, pin-based VM-execution controls           (2.6.1) 
.exec.proc              dd ?    ; 32, processor-based VM-execution controls     (2.6.2) 
.exec.exception         dd ?    ; 32, exception bitmap                          (2.6.3) 
.exec.IO_A              dq ?    ; 64, address of I/O-bitmap A                   (2.6.4) 
.exec.IO_B              dq ?    ; 64, address of I/O-bitmap B 
.exec.TSC               dq ?    ; 64, TimeStamp counter delta                   (2.6.5) 
;TODO: not sure about these, manual is not very clear here 
.exec.CR0_mask          dq ?    ; 64, quest/host mask for CR0                   (2.6.6) 
.exec.CR0_read_shadow   dq ?    ; 64, read shadow for CR0 
.exec.CR4_mask          dq ?    ; 64, quest/host mask for CR0 
.exec.CR4_read_shadow   dq ?    ; 64, read shadow for CR0 
.exec.CR3_target_1      dq ?    ; 64, target 1 for CR3 write                    (2.6.7) 
.exec.CR3_target_2      dq ?    ; 64, target 2 for CR3 write 
.exec.CR3_target_3      dq ?    ; 64, target 3 for CR3 write 
.exec.CR3_target_4      dq ?    ; 64, target 4 for CR3 write 
.exec.CR3_target_count  dd ?    ; 32, number of targets for CR3 write, bound by MSR_VMX_MISC 
.exec.APIC_address      dq ?    ; 64, physical address of virtual APIC page     (2.6.  
.exec.TPR_threshold     dd ?    ; 32, bits 3:0 = min threshold of TPR shadow 

;VM-exit control fields (2.7) 
.exit.controls          dd ?    ; 32, VM exit control bitfield                  (2.7.1) 
.exit.MSR_store_count   dd ?    ; 32, number of MSRs to store on exit, <=512    (2.7.2) 
.exit.MSR_store_address dq ?    ; 64, physical address of MSR store area 
.exit.MSR_load_count    dd ?    ; 32, number of MSRs to load on exit, <=512 
.exit.MSR_load_address  dq ?    ; 64, physical address of MSR store area 

;VM-entry control fiels (2.  
.entry.controls         dd ?    ; 32, VM entry control bitfield                 (2.8.1) 
.entry.MSR_load_count   dd ?    ; 32, number of MSRs to load on VM entry, <=512 (2.8.2) 
.entry.MSR_load_address dq ?    ; 64, physical address of MSR load area 
.entry.int_info         dd ?    ; 32, VM-entry interruption-information field   (2.8.3) 
.entry.exception_code   dd ?    ; 32, VM-entry exception error code 
.entry.instr_len        dd ?    ; 32, to determine RIP ??? 

;VM-exit information fields (2.9) 
.exit.reason            dd ?    ; 32, exit reason                               (2.9.1) 
.exit.qualification     dq ?    ; 64, exit qualification 
.exit.int_info          dd ?    ; 32, VM-exit interrupt information             (2.9.2) 
.exit.int_error_code    dd ?    ; 32, VM-exit interrupt error code 
.exit.IDT_vect_info     dd ?    ; 32, IDT-vectoring information                 (2.9.3) 
.exit.IDT_vect_error    dd ?    ; 32, IDT-vectoring error code 
.exit.instr_len         dd ?    ; 32, VM-exit instruction length                (2.9.4) 
.exit.guest_address     dq ?    ; 64, quest linear address 
.exit.VMX_instr_info    dd ?    ; 32, VMX instruction information 
.exit.VM_instr_error    dd ?    ; 32, VM-Instruction error field (2.9.5)

ends

end virtual
    


Image
Post 05 Apr 2007, 00:42
View user's profile Send private message Visit poster's website Reply with quote
HyperVista



Joined: 18 Apr 2005
Posts: 691
Location: Virginia, USA
HyperVista 05 Apr 2007, 14:28
Fyi, I changed the section:

Code:
section '.text' code readable executable 
    


to

Code:
section '.reloc' code readable executable 
    


and got the same exact result.

Maybe I need to set-up the VMCS and carve out the memory in the driver code (non-paged memory pool) instead of trying to do it in fasm....
Post 05 Apr 2007, 14:28
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 05 Apr 2007, 15:03
Excuse my ignorance but for what do you need the ORG? If possible try removing it and try again. Also note that you don't need the "virtual at 0" because the struct macro doesn't define any label, you have to do it later, something like:
Code:
align 4096
vmcs VMCS     


Note also that the structure is defined in code section where is only readable so you can't do any initialization actually.

Here my try:
Code:
format MS COFF

include 'win32a.inc'

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;; Structures declaration ;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

struct VMCS
; header
  .revision               dd ?    ; processor revision ID, found in low 32 bits of MSR 1152 (MSR_VMX_BASIC)
  .abort_indicator        dd ?    ; reason of VM exit

; guest state area (2.4)
  .guest.CR0              dq ?    ; 64, quest CR0
  .guest.CR3              dq ?    ; 64, quest CR3
  .guest.CR4              dq ?    ; 64, quest CR4
  .guest.DR7              dq ?    ; 64, quest DR7
  .guest.RSP              dq ?    ; 64, quest RSP
  .guest.RIP              dq ?    ; 64, quest RIP
  .guest.RFLAGS           dq ?    ; 64, quest RFLAGS
  .guest.CS.selector      dw ?    ; 16, quest CS selector
  .guest.CS.base          dq ?    ; 64, quest CS base address
  .guest.CS.limit         dd ?    ; 32, quest CS limit (in bytes)
  .guest.CS.rights        dd ?    ; 32, quest CS access rights
  .guest.SS.selector      dw ?    ; 16, quest SS selector
  .guest.SS.base          dq ?    ; 64, quest SS base address
  .guest.SS.limit         dd ?    ; 32, quest SS limit (in bytes)
  .guest.SS.rights        dd ?    ; 32, quest SS access rights
  .guest.DS.selector      dw ?    ; 16, quest DS selector
  .guest.DS.base          dq ?    ; 64, quest DS base address
  .guest.DS.limit         dd ?    ; 32, quest DS limit (in bytes)
  .guest.DS.rights        dd ?    ; 32, quest DS access rights
  .guest.ES.selector      dw ?    ; 16, quest ES selector
  .guest.ES.base          dq ?    ; 64, quest ES base address
  .guest.ES.limit         dd ?    ; 32, quest ES limit (in bytes)
  .guest.ES.rights        dd ?    ; 32, quest ES access rights
  .guest.FS.selector      dw ?    ; 16, quest FS selector
  .guest.FS.base          dq ?    ; 64, quest FS base address
  .guest.FS.limit         dd ?    ; 32, quest FS limit (in bytes)
  .guest.FS.rights        dd ?    ; 32, quest FS access rights
  .guest.GS.selector      dw ?    ; 16, quest GS selector
  .guest.GS.base          dq ?    ; 64, quest GS base address
  .guest.GS.limit         dd ?    ; 32, quest GS limit (in bytes)
  .guest.GS.rights        dd ?    ; 32, quest GS access rights
  .guest.LDTR.selector    dw ?    ; 16, quest LDTR selector
  .guest.LDTR.base        dq ?    ; 64, quest LDTR base address
  .guest.LDTR.limit       dd ?    ; 32, quest LDTR limit (in bytes)
  .guest.LDTR.rights      dd ?    ; 32, quest LDTR access rights
  .guest.TR.selector      dw ?    ; 16, quest TR selector
  .guest.TR.base          dq ?    ; 64, quest TR base address
  .guest.TR.limit         dd ?    ; 32, quest TR limit (in bytes)
  .guest.TR.rights        dd ?    ; 32, quest TR access rights
  .guest.GDTR.base        dq ?    ; 64, quest GDTR base address
  .guest.GDTR.limit       dd ?    ; 32, quest GDTR limit
  .guest.IDTR.base        dq ?    ; 64, quest IDTR base address
  .guest.IDTR.limit       dd ?    ; 32, quest IDTR limit
  .guest.MSR_DEBUGCTL     dq ?    ; 64, quest MSR_IA32_DEBUGCTL
  .guest.MSR_SYSENTER_CS  dd ?    ; 32, quest MSR_IA32_SYSENTER_CS
  .guest.MSR_SYSENTER_ESP dq ?    ; 64, quest MSR_IA32_SYSENTER_ESP
  .guest.MSR_SYSENTER_EIP dq ?    ; 64, quest MSR_IA32_SYSENTER_EIP
  .guest.activity_state   dd ?    ; 32, activity state (2.4.2)
  .guest.int_state        dd ?    ; 32, interruptibility state (2.4.2)
  .guest.debug_exceptions dq ?    ; 64, pending debug exceptions (table 2.4)
  .guest.VMCS_link        dq ?    ; 64, reserved, should be set to -1. (2.4.2)

; host state (2.5)
  .host.CR0               dq ?    ; 64, host CR0
  .host.CR3               dq ?    ; 64, host CR3
  .host.CR4               dq ?    ; 64, host CR4
  .host.RSP               dq ?    ; 64, host RSP
  .host.RIP               dq ?    ; 64, host RIP
  .host.CS                dw ?    ; 16, host CS selector
  .host.SS                dw ?    ; 16, host SS selector
  .host.DS                dw ?    ; 16, host DS selector
  .host.ES                dw ?    ; 16, host ES selector
  .host.FS                dw ?    ; 16, host FS selector
  .host.GS                dw ?    ; 16, host GS selector
  .host.TR                dw ?    ; 16, host TR selector
  .host.MSR_SYSENTER_CS   dd ?    ; 32, host MSR_IA32_SYSENTER_CS
  .host.MSR_SYSENTER_ESP  dq ?    ; 64, host MSR_IA32_SYSENTER_ESP
  .host.MSR_SYSENTER_EIP  dq ?    ; 64, host MSR_IA32_SYSENTER_EIP

; VM-execution control fields (2.6)
  .exec.controls          dd ?    ; 32, pin-based VM-execution controls           (2.6.1)
  .exec.proc              dd ?    ; 32, processor-based VM-execution controls     (2.6.2)
  .exec.exception         dd ?    ; 32, exception bitmap                          (2.6.3)
  .exec.IO_A              dq ?    ; 64, address of I/O-bitmap A                   (2.6.4)
  .exec.IO_B              dq ?    ; 64, address of I/O-bitmap B
  .exec.TSC               dq ?    ; 64, TimeStamp counter delta                   (2.6.5)
; TODO: not sure about these, manual is not very clear here
  .exec.CR0_mask          dq ?    ; 64, quest/host mask for CR0                   (2.6.6)
  .exec.CR0_read_shadow   dq ?    ; 64, read shadow for CR0
  .exec.CR4_mask          dq ?    ; 64, quest/host mask for CR0
  .exec.CR4_read_shadow   dq ?    ; 64, read shadow for CR0
  .exec.CR3_target_1      dq ?    ; 64, target 1 for CR3 write                    (2.6.7)
  .exec.CR3_target_2      dq ?    ; 64, target 2 for CR3 write
  .exec.CR3_target_3      dq ?    ; 64, target 3 for CR3 write
  .exec.CR3_target_4      dq ?    ; 64, target 4 for CR3 write
  .exec.CR3_target_count  dd ?    ; 32, number of targets for CR3 write, bound by MSR_VMX_MISC
  .exec.APIC_address      dq ?    ; 64, physical address of virtual APIC page     (2.6.
  .exec.TPR_threshold     dd ?    ; 32, bits 3:0 = min threshold of TPR shadow

; VM-exit control fields (2.7)
  .exit.controls          dd ?    ; 32, VM exit control bitfield                  (2.7.1)
  .exit.MSR_store_count   dd ?    ; 32, number of MSRs to store on exit, <=512    (2.7.2)
  .exit.MSR_store_address dq ?    ; 64, physical address of MSR store area
  .exit.MSR_load_count    dd ?    ; 32, number of MSRs to load on exit, <=512
  .exit.MSR_load_address  dq ?    ; 64, physical address of MSR store area

; VM-entry control fiels (2.
  .entry.controls         dd ?    ; 32, VM entry control bitfield                 (2.8.1)
  .entry.MSR_load_count   dd ?    ; 32, number of MSRs to load on VM entry, <=512 (2.8.2)
  .entry.MSR_load_address dq ?    ; 64, physical address of MSR load area
  .entry.int_info         dd ?    ; 32, VM-entry interruption-information field   (2.8.3)
  .entry.exception_code   dd ?    ; 32, VM-entry exception error code
  .entry.instr_len        dd ?    ; 32, to determine RIP ???

; VM-exit information fields (2.9)
  .exit.reason            dd ?    ; 32, exit reason                               (2.9.1)
  .exit.qualification     dq ?    ; 64, exit qualification
  .exit.int_info          dd ?    ; 32, VM-exit interrupt information             (2.9.2)
  .exit.int_error_code    dd ?    ; 32, VM-exit interrupt error code
  .exit.IDT_vect_info     dd ?    ; 32, IDT-vectoring information                 (2.9.3)
  .exit.IDT_vect_error    dd ?    ; 32, IDT-vectoring error code
  .exit.instr_len         dd ?    ; 32, VM-exit instruction length                (2.9.4)
  .exit.guest_address     dq ?    ; 64, quest linear address
  .exit.VMX_instr_info    dd ?    ; 32, VMX instruction information
  .exit.VM_instr_error    dd ?    ; 32, VM-Instruction error field (2.9.5)
ends

;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;; Code section ;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;

section '.text' code readable executable 

SET_VMCS: ; Returns FALSE on error and pVMCS==NULL, TRUE otherwise and
; Unfortunatelly we can't align a section to more than 8192 so we need
; to allocate the structure instead of just declaring it in data section
  invoke VirtualAlloc, NULL, sizeof.VMCS, MEM_COMMIT, PAGE_READWRITE ; Verify if you need "invoke" or "stdcall"
  mov    [pVMCS], eax
  test   eax, eax
  setnz  al
  movzx  eax, al
  ret
; Obviously the initialization code is missing here and goes after successful call to VirtualAlloc

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;; Imported functions ;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

extrn '__imp__VirtualAlloc@16' as VirtualAlloc:dword

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;; Exported functions ;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

public SET_VMCS as '_set_vmcs@0'

;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;; Data section ;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;

section '.data' data readable writable

pVMCS dd ?

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;; Exported global variables ;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

public pVMCS    
Post 05 Apr 2007, 15:03
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 05 Apr 2007, 16:11
Well, my code uses VirtualAlloc but you obviously can't because this is not user mode code.
Post 05 Apr 2007, 16:11
View user's profile Send private message Reply with quote
HyperVista



Joined: 18 Apr 2005
Posts: 691
Location: Virginia, USA
HyperVista 05 Apr 2007, 17:31
Thank you LocoDelAssembly! Even though your code uses VirtualAlloc, your example and guidance gave me a hint of which way I need to go. I'm at work now and can't play around with it much, but will kick it around this evening.

Thanks again.
Post 05 Apr 2007, 17:31
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.