Page 1 of 2

Undefined reference in asm-code

Posted: Sat May 05, 2007 2:37 am
by david-h
Hi,
I wanted to implement ISR´s like in Bran´s Kernel Development Tutorial. But my .asm file can´t call my fault_handler-function. The code that should call fault_handler looks like this:

Code: Select all

[extern _fault_handler

; ...

isr_common_stub:
    pusha
    push ds
    push es
    push fs
    push gs
    mov ax, 0x10   ; Load the Kernel Data Segment descriptor!
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov eax, esp   ; Push us the stack
    push eax
    mov eax, _fault_handler
    call eax       ; A special call, preserves the 'eip' register
    pop eax
    pop gs
    pop fs
    pop es
    pop ds
    popa
    add esp, 8     ; Cleans up the pushed error code and pushed ISR number
    iret           ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP!
fault_handler gets this struct as parameter:

Code: Select all

struct regs
{
	unsigned int gs, fs, es, ds;      /* pushed the segs last */
	unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;  /* pushed by 'pusha' */
	unsigned int int_no, err_code;    /* our 'push byte #' and ecodes do this */
	unsigned int eip, cs, eflags, useresp, ss;   /* pushed by the processor automatically */ 
};
The function itself just displays an error message on the screen.

Posted: Sat May 05, 2007 2:40 am
by pcmattman

Code: Select all

[extern _fault_handler
Should just be

Code: Select all

extern _fault_handler
Make sure you have a fault_handler() function.

The code in his tutorial works - I've used it twice now, and translated it to AT&T syntax. If you could say exactly what the problem is, it would be very helpful.

Posted: Sat May 05, 2007 2:47 am
by david-h
The problem is, that ld doesn´t link the .o files. I receive the following message:
Loader.o:Loader.o:<.test+0x1a1>: undefined reference to '_fault_handler'
The function is defined like this:

Code: Select all

void fault_handler(regs *r)
{
	if (r->int_no < 32)
	{
		std::cout << exception_messages[r->int_no];
		std::cout << "\nSystem halts now.";
		for(;;);
	}
}
I cna call other functions from my .asm file, like main().

Posted: Sat May 05, 2007 2:49 am
by urxae
If you're compiling to ELF (i.e. if you're using a cross-compiler to an ELF target, or the default compiler of most Linux systems), remove the leading underscore in the name.
If you're compiling from anything other than C, make sure fault_handler uses the C calling convention (i.e. use 'extern "C"' in C++ code, 'extern(C)' in D code, etc.).
EDIT: I didn't see your new post yet. That's clearly C++, so put extern "C" in front of that function.

Posted: Sat May 05, 2007 2:50 am
by pcmattman
Show us your makefile / command line.

Based on that we can help. Specifically, show the parts that compile the fault handler and the assembly code, and your LD command.

Posted: Sat May 05, 2007 2:54 am
by Brynet-Inc
This is just LAME!!

It's almost weekly someone posts about the "undefined reference" tidbit.

Solutions:
Change extern _fault_handler to extern fault_handler

Change mov eax, _fault_handler to mov eax, fault_handler

Actually, Remove ALL underscores from both C and ASM files and then add this to your GCC/G++ argument list:
-fno-leading-underscore

It's just foolish... This little piece of information should be a "Sticky" thread..

Posted: Sat May 05, 2007 2:59 am
by pcmattman
It's almost weekly someone posts about the "undefined reference" tidbit.
Almost weekly someone decides to make an OS and finds osdever.net.

And yes... I always forget about the leading underscores.

Someone has got to modify that tutorial - make it a bit more readable and not just a source for code.

Either that or do what Brynet suggested - put up a sticky!

Posted: Sat May 05, 2007 3:00 am
by david-h
urxae wrote:If you're compiling to ELF (i.e. if you're using a cross-compiler to an ELF target, or the default compiler of most Linux systems), remove the leading underscore in the name.
If you're compiling from anything other than C, make sure fault_handler uses the C calling convention (i.e. use 'extern "C"' in C++ code, 'extern(C)' in D code, etc.).
EDIT: I didn't see your new post yet. That's clearly C++, so put extern "C" in front of that function.
Thanks, it linked and compiled correctly with that. But the ISR´s don´t work. I wanted to test it with an 'int i = 10 / 0', but if the code starts I get an processor error. So here´s my command line:

Code: Select all

C:\nasm\nasmw.exe -f aout Sourcecode/Loader.asm -o Loader.o
...
gxx -c Sourcecode/IDT.cpp -I Sourcecode/include -nostdlib -fno-builtin -fno-rtti -fno-exceptions
gxx -c Sourcecode/ISRs.cpp -I Sourcecode/include -I Sourcecode/stdlib -nostdlib -fno-builtin -fno-rtti -fno-exceptions
...
ld -T Link.ld -o Kernel.bin Loader.o Support.o IDT.o ISRs.o iostream.o GDT.o Kernel.o Video.o System.o
Here´s the Link.ld:

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
  .text 0x100000 :
  {
    code = .; _code = .; __code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  
  .data : 
  {
     __CTOR_LIST__ = .; LONG((__CTOR_END__ -
    __CTOR_LIST__) / 4 - 2)*(.ctors)  LONG(0) __CTOR_END__
    = .;
    
    __DTOR_LIST__ = .; LONG((__DTOR_END__ -
   __DTOR_LIST__) / 4 - 2)*(.dtors)  LONG(0) __DTOR_END__ =
   .;
   
    data = .; _data = .; __data = .;
    *(.data)
    . = ALIGN(4096);
  }
  
  .bss :
  {
    bss = .; _bss = .; __bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  
  end = .; _end = .; __end = .;
}

Any other ideas?

Posted: Sat May 05, 2007 3:11 am
by urxae
david-h wrote:Thanks, it linked and compiled correctly with that. But the ISR´s don´t work. I wanted to test it with an 'int i = 10 / 0', but if the code starts I get an processor error.
Ehm... Isn't that exactly what you want to happen on a divide by zero? Or are you getting some error other than ISR #0? (In which case, you might want to be more specific about what error you get...)

Posted: Sun May 06, 2007 9:42 am
by david-h
I did the thing with the underscores. Everything compiles and links correctly, but the ISR´s still don´t work.

I don´t get an error message from my kernel, I get a messagebox from Virtual PC saying something like processor error, your Virtual PC will be reseted.

Posted: Sun May 06, 2007 7:31 pm
by neon
I don´t get an error message from my kernel, I get a messagebox from Virtual PC saying something like processor error, your Virtual PC will be reseted
What is the exact error? I dont use Virtual PC, but I assume it logs
the current state of the processor?

Posted: Mon May 07, 2007 9:04 am
by david-h
The exact error message is in german. I tried to translate it:

"Unrecoverable processor error!

The Virtual PC will now be reseted"

I can´t find any logs, neither in User\AppData nor in Program Files\Microsoft Virtual PC. Maybe I should Bochs?

Posted: Mon May 07, 2007 9:35 am
by Brynet-Inc
david-h wrote:The exact error message is in german. I tried to translate it:

"Unrecoverable processor error!

The Virtual PC will now be reseted"

I can´t find any logs, neither in User\AppData nor in Program Files\Microsoft Virtual PC. Maybe I should Bochs?
Virtual PC sounds like an emulator for users.. Not developers.. Try QEMU or Bochs.

Posted: Fri May 11, 2007 6:03 am
by david-h
In the attachment you can find my protocoll file of Bochs. Could anyone take a look at it and say what is wrong?

I guess the problem is that it doesn´t load the ISRs into the processor but I´m not sure.

Posted: Fri May 11, 2007 6:20 am
by AJ
Have you added anything more than just ints 0 - 31? Looks like you haven't set up the IDT properly - could be an unhandled IRQ firing...