Page 1 of 2

ASM function calling error (wrong efective address)

Posted: Wed Jul 02, 2008 7:39 pm
by suthers
when I call an extern assembler function from C, I don't get any compiler/liner errors, but the address that the linker puts in as the address of the asm function is completely wrong... The address that is given instead of the wrong address is always quite close to the address of the call itself, oten resulting in infinite loops...
I have made sure that all the externs are deined as global in the asm and that their in the .text section...
And I don't think my linker scripts at fault but here it is just in case:

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(main)
SECTIONS
{
  .text 0x100000 : AT(0x100000) {
    code = .; 
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data  : AT(0x100000 + (data - code)){
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss  : AT(0x100000 + (bss - code)){ 	
    bss = .;				
    *(.bss)
    . = ALIGN(4096);
    end_of_bss = .;
  }
  end = .;
}
I can't see anything wrong with that...
Anybody see what I'm doing wrong?
Thanks in advance,

Jules

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 6:51 am
by Omega
Looks like we are both using grub, maybe not. But, just in case this is what I use, so try this:

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(main)
phys = 0x00100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;_end = .; __end = .;
}
Hope this helps.

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 8:14 am
by suthers
I tried that, but it didn't make a difference, (their effectively the same except you use a symbol for the origin, where as I have it physically typed in.... and you have a few extra symbols..., but I tried it anyway, just added one extra symbol (end_of_bbs) I need that to clear my .bss section...) I don't use grub by the way....
I've made a temporary fix by doing this:

Code: Select all

void enable_paging()
{
	(write_cr3 - 0x18EB)(((unsigned long)(page_directory)));
	(write_cr0 - 0x18FD )((read_cr0 - 0x18F0)() | 0x80000000);
	k_printf("\npaging enabled.", 0x07);
	return;
};
I've been converting my paging enabling to C....
But it's only a temporary fix as it wont work anymore if I add any more assembler code before that function and adding some may change the address calculated for the asm function, so the values I negate would become wrong....
So I still need a fix, but this allows it to work....
Any ideas?
Thanks in advance,

Jules

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 8:44 am
by midir
I've had similar problems calling functions within the same C source file, before even getting to assembler. I eventually resolved all my linker woes by setting up the following model, with no padding whatsoever:

Code: Select all

ENTRY( _multiboot_entry )

SECTIONS
{
	. = 0x00100000;
	
	.text : {
		*(.text)
		*(.rdata)
		*(.rodata)
		*(.data)
	}
	
	.bss : {
		*(.bss)
	}
}
If that doesn't fix it, is your assembler perhaps expecting a certain origin or summat and mis-compensating?

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 8:55 am
by suthers
Thanks midir,

I tried that linker script (again I just added the symbols that are necessary for my kernel...).
But it still didn't, work...
Anybody have any ideas what else I could try to fix this?
Thanks in advance,

Jules

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 9:05 am
by midir
Have you tried asking the linker to create a map file? It was a huge help when I realised linkers could do this, because it's very useful in diagnosing this sort of linkage problem. Add the option -Map kernel.map.txt onto the LD command line. The kernel.map.txt file will contain details on the offsets of every global function, among other things. Then you can check that the pointers to the assembler functions within the C code are the same as where the linker is actually putting them.

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 9:16 am
by suthers
I had no idea that linkers could do that thanks....
But the weird thing is that the linker map shows the right addresses for the functions:

Code: Select all

                0x00100264                _write_cr0
                0x0010026c                _write_cr3
                0x0010025c                _read_cr0
Weird...
The linker seems to know where they really are, but when it comes to placing them in the code generated from C, it messes up....
Any ideas what could be causing this?
Thanks in advance,

Jules

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 9:21 am
by eax
Im going to try that kernal map thing as well :) , will maybe aid my understanding a bit. Anyway hope you get that fixed suthers. (I am not near as far on as yourself so cant be any help, still just thought I would mention that this post has helped me as well)

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 9:37 am
by suthers
Thanks, I'm happy it helped you :D ....
But I have to say, I don't consider that I'm that far either....
I was going on to some more advance drivers, but I encountered memory management problems, so I decided to migrate my memory management from asm to C to make it easier to manipulate....
But I had coded it in asm in the first place because I couldn't link to asm functions... (I found this out some time ago now, but I didn't do anything about it, I just used workarounds...), but now I have to be able to link to asm to do these things (I tried to do it using inline asm, but I couldn't figure it out... :oops: )
Well, I still haven't got any deeper into this mystery, so any help would be appreciated....
Thanks in advance,

Jules

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 9:50 am
by Combuster
Time to use the good ole' GCC Cross-Compiler

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 10:02 am
by suthers
Combuster wrote:Time to use the good ole' GCC Cross-Compiler
No, No, take it away....
I can't make a cross compiler, when I install cygwin, for some reason, the gcc that it is installed with can't generate executables....
It only ever worked the first time I installed...
You said that the only way to fix was to individually check each binutils NO.... :cry:
Thanks,

Jules

P.S. Just out of interest, why is the cross compiler so much better than the cygwin port?
I don't get that, surely they should be the same...

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 10:14 am
by Combuster
Cygwin targets windows and all its bloat, MinGW targets windows and all its bloat. A crosscompiler is bloat free, and therefore causes less annoyances.

While you remind me about it, I still haven't seen you debug your environment thoroughly. If it says GCC can't make executables, at least have a look what it can create. There are just too many stupid errors that can cause this to list them all.

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 10:18 am
by suthers
Combuster wrote:Cygwin targets windows and all its bloat, MinGW targets windows and all its bloat. A crosscompiler is bloat free, and therefore causes less annoyances.

While you remind me about it, I still haven't seen you debug your environment thoroughly. If it says GCC can't make executables, at least have a look what it can create. There are just too many stupid errors that can cause this to list them all.
I have a feeling this is going to take a long time (since I don't know that much about the cygwin environment....
Jules

edit: a starting point would be nice... :wink: ...

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 10:40 am
by midir
The linker seems to know where they really are, but when it comes to placing them in the code generated from C, it messes up....
Honestly, that's really very strange. I presume you're importing the external functions with a line like:
unsigned int read_cr0();
or
extern "C" unsigned int read_cr0();
or something, right?

You can get a more or less clean environment not targeted at Windows by adding some or all of the following options to the GCC or G++ command line:

Code: Select all

-ffreestanding -nostdlib -nostartfiles -nodefaultlibs -fno-rtti -fno-exceptions
Try that. It should avoid needing a cross-compiler, although the linker will still output Windows *.exe files.

Re: ASM function calling error (wrong efective address)

Posted: Thu Jul 03, 2008 11:22 am
by Combuster
Maybe its better to put you out of your misery :(
http://dimensionalrift.homelinux.net/co ... in.tar.bz2

At least I get to know if it works elsewhere :)