jump to c++ static function from assemble error?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
jinglexy
Posts: 15
Joined: Sat Mar 10, 2007 1:05 am

jump to c++ static function from assemble error?

Post by jinglexy »

at the first period of my hobby os, i jump out assemble to c function,

Code: Select all


	lidt	idt_descr
	call	start_kernel
	cli
start_kernel define as:

Code: Select all

extern "C" void start_kernel(void)
{
        CKernel::start_kernel();
}
i think the c function may instead of c++ static function, in the init/main.cpp,
the start process defined as:

Code: Select all

class CKernel
{
public:
	static void start_kernel(void);
};

void Ckernel::start_kernel(void)
{
	......
}
after assemble, the init/main.o created, i get the Ckernel::start_kernel() function name as:

Code: Select all

readelf -a init/main.o > grep start_kernel
the function name mangling by g++ is "_ZN7CKernel12start_kernel",
then i jump to the kernel as:

Code: Select all


	lidt	idt_descr
	call	_ZN7CKernel12start_kernel
	cli
when link, an error occur, the link can not find function "_ZN7CKernel12start_kernel", why?
Last edited by jinglexy on Fri Aug 17, 2007 5:21 am, edited 1 time in total.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

you have been mixing CKernel with Ckernel at occasions, which are two completely different things. Try fixing that first

Also, please use tags. blue on blue is incredibly difficult to read. (So is white on white :wink:)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

You probably don't want to be calling the C++ function immediately anyway. The initial C trampoline code is an ideal place to initialise and destroy global objects as defined in the .ctor and .dtor sections of your binary.

JamesM
jinglexy
Posts: 15
Joined: Sat Mar 10, 2007 1:05 am

Post by jinglexy »

hi, i also puzzled what difference of c and c++ static func, how do solve it?

thank you a lot.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

well did you declare the kernel function extern in you assembly file?

Code: Select all

 loader.s
.extern __ZN7CKernel12start_kernelEv;

entry:
    call    __ZN7CKernel12start_kernelEv;
    jmp     .
compile with 'as -o loader.o loader.s'

Code: Select all

 kernel.cc
class CKernel
{
public:
   static void start_kernel(void);
};

void CKernel::start_kernel(void)
{
}
compile with 'g++ -o kernel.o -c kernel.cc'

link together with 'g++ -o test.exe loader.o kernel.o -nostartfiles'

no problems encountered. difference with you btw is leading underscore
Last edited by os64dev on Fri Aug 17, 2007 5:45 am, edited 1 time in total.
Author of COBOS
jinglexy
Posts: 15
Joined: Sat Mar 10, 2007 1:05 am

Post by jinglexy »

in file head.S
.globl _ZN7CKernel12start_kernel

........
call call _ZN7CKernel12start_kernel
make output:
>>>>>> linking: vmjinix
ld -nostdlib -T /home/wyt/source/os/jinix-1.2.1/arch/i386/vmjinix.lds \
-o /home/wyt/source/os/jinix-1.2.1/arch/i386/vmjinix arch/i386/kernel/head.o arch/arch.t drivers/drivers.t fs/fs.t init/init.t ipc/ipc.t kernel/kernel.t lib/lib.t mm/mm.t net/net.t
arch/i386/kernel/head.o(.text+0xe6): In function `second_gdtr':
/home/wyt/source/os/jinix-1.2.1/arch/i386/kernel/head.S:121: undefined reference to `_ZN7CKernel12start_kernel'
make[1]: *** [vmjinix] error 1
make: *** [all] error 2
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

sorry i edited the post: solution above
Author of COBOS
jinglexy
Posts: 15
Joined: Sat Mar 10, 2007 1:05 am

Post by jinglexy »

thank you very much, the problem resolved:

wyt@kdc-media ~/source/os/jinix-1.2.1]$ readelf -a init/main.o | grep start_kernel
22: 00000000 225 FUNC GLOBAL DEFAULT 1 _ZN7CKernel12start_kernel
[wyt@kdc-media ~/source/os/jinix-1.2.1]$ nm init/main.o | grep start_kernel
00000000 T _ZN7CKernel12start_kernelEv

the function read by readelf is truncated,
only "nm" get the correct func name, that's strange of readelf.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

hi, i also puzzled what difference of c and c++ static func, how do solve it?

thank you a lot.
A C++ static member function is one which is a member of a class, but is called without a "this" pointer. So it does not have access to any member variables of a class instance.

A C (or C++) static global function is one who's symbol is not exported. So, if you had 2 files:

a.c:

Code: Select all

extern int func();
void main() {
  func();
}
b.c:

Code: Select all

static int func() {
 return 1;
}
This would not link, complaining of an undefined symbol - func. If func() was declared without the static modifier, it would link.

JamesM
Post Reply