Page 1 of 1

Peculiar issue with FreeBasic and linking

Posted: Fri Aug 07, 2015 9:35 pm
by pongozolin
Hello, this is my first post here (but I'm somewhat familiar with this forum already).

I chose to post here as opposed to the FreeBASIC forums, as OS development is newish/unexplored idea over there.

Now for the issue:

I decided to use assembly (NASM) and FreeBASIC to develop my OS. So far, I've only used assembly in the bootloader, but now I need both languages as I start my kernel. For my build process, I use a simple script (makefiles will eventually come) that assembles/compiles outdated sources. Then, I link them into a flat binary, put all files into an ISO image, and test things if necessary.

However, when I test my kernel code, I noticed that all sub/function calls between FB code acts strangely: calls are always off by a few bytes in memory (if I call a function at 0x100050, it jumps to 0x10005D, all functions are 16-byte-aligned with FB). This doesn't happen when NASM code calls FB code. I've already tweaked my linker script many times, and have tried both a cross-linking LD and JLoc, but the issue still remains.

The only time it stops is when I remove all "global" variables (those that start with Dim Shared, even though I just want variables visible in the whole translation unit), which removes the .ctors section(s). I know globals may require the runtime, but my linker doesn't complain about unresolved references, and rolling without globals is too annoying. Usually, I call the constructors myself by looping through the list of function pointers on startup.

My startup code (sorry for indentation issues):

Code: Select all

	kentry:	CLI
			LEA	ESP, [STACK_BASE + 0x2000]
			JMP	0x08:loadnew_gdt

	load_gdt:	MOV	AX, 0x10
			MOV	DS, AX
			MOV	ES, AX
			MOV	FS, AX
			MOV	GS, AX
			MOV	SS, AX

	clear_bss:	MOV	EDI, SBSS
			MOV	ECX, EBSS
			SUB	ECX, EDI
			SHR	ECX, 0x02
			XOR	EAX, EAX
			REP	STOSD

	do_ctors:	MOV	ESI, SCTORS
			MOV	ECX, ECTORS
			SUB	ECX, ESI
			SHR	ECX, 0x02

	.loop:		MOV	EAX, [ESI]
			CALL	EAX

			ADD	ESI, 0x04
			DEC	ECX
			JNZ	.loop

;
; call KernelMain with pHwit parameter in EBX; should not return
;

	gomain:	PUSH	EBX
			CALL	_kernelMain@4
			CLI
			HLT
and my LD linker script (based off of Bare Bones):

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY (kentry)

SECTIONS{
    . = 0x00100000;

    .text :{
        *(.stext)
        *(.text)
    }

    .rodata ALIGN (0x1000) : {
        *(.rodata)
        SCTORS = .;
        *(.ctors)
        ECTORS = .;
    }

    .data ALIGN (0x1000) : {
        *(.data)
    }

    .bss ALIGN (0x1000) : {
        SBSS = .;
        *(.bss)
        EBSS = .;
    }

	.stack ALIGN (0x1000) : {
		STACK_BASE = .;
		*(.stack)
		_KERNEL_END = .;
	}
}

Re: Peculiar issue with FreeBasic and linking

Posted: Fri Aug 07, 2015 10:15 pm
by FallenAvatar
What compiler are you using to compile your FreeBasic code? What commands (exactly) do you use to compile your FB code? What ABI does that compiler use/assume?

- Monk

Re: Peculiar issue with FreeBasic and linking

Posted: Fri Aug 07, 2015 10:50 pm
by pongozolin
What compiler are you using to compile your FreeBasic code?
I'm using the FreeBASIC compiler for Windows (Vista), version 1.03.0.
What commands (exactly) do you use to compile your FB code?
To compile 1 module, then link:

Code: Select all

FBC.EXE -nodeflibs -c -i <include paths> -o <name>.OBJ <name>.BAS
LD.EXE -T VGRKRNL.LD -o <output directory>\VGRKRNL.SYS ENTRY.OBJ VGRKRNL.OBJ ...
Usually, -nodeflibs doesn't change anything, but I use it anyway.
What ABI does that compiler use/assume?
Not exactly sure about this one, best way I can answer is to say it seems to make Windows-based assumptions (defaults to PE executables, outputs COFF objects, etc.)

I should also mention that the .stext section is only defined/present in the entry source file (where 'kentry' starts)

Re: Peculiar issue with FreeBasic and linking

Posted: Sat Aug 08, 2015 6:13 am
by Combuster
The one obvious error I found is the following:

Code: Select all

CALL   EAX    ; eax = return value, ecx, edx = garbage
ADD   ESI, 0x04
DEC   ECX     ; ecx = garbage - 1
JNZ   .loop   ; jump if lucky

Re: Peculiar issue with FreeBasic and linking

Posted: Sat Aug 08, 2015 8:35 am
by pongozolin
I suspected a problem with running that loop, but I left the code as is since each constructor only seems to RET without doing anything. Even when I remove the loop/preserve registers within the loop, the issue still stays. Almost as if the code doesn't know the constructors were put there, so relocation/alignment stages in linking fail, I guess.

Re: Peculiar issue with FreeBasic and linking

Posted: Sat Aug 08, 2015 11:24 am
by pongozolin
Decided to use FB compiler for running on DOS. Problem magically disappeared (hopefully for good) with any linker I use. Produced object files still have .ctors and look nearly identical.

Why Windows, why?