Creating a shared library

Programming, for all ages and all languages.
Post Reply
FlashBurn
Member
Member
Posts: 313
Joined: Fri Oct 20, 2006 10:14 am

Creating a shared library

Post by FlashBurn »

I wanted to create a shared library ("ld -shared -o libfoo.so foo.o"), but I get errors from ld which I can´t explain. Creating a static library works!

errors:

Code: Select all

Cannot export foo: symbol not found
...
I created my object files with nasm and declared my functions global with "global foo:function" and if I use objdump there are the symbols which ld can´t find.

What am I doing wrong here?
FlashBurn
Member
Member
Posts: 313
Joined: Fri Oct 20, 2006 10:14 am

Re: Creating a shared library

Post by FlashBurn »

As it seems that no one here can help me, maybe you can help me with this.

One way to get it working would be to translate the asm code to c, but I don´t know how to do it.

Code: Select all

;----------------------------
global portCreate:function
align 0x10
portCreate:
	mov eax,SYSCALL_PORT_CREATE
	jmp [SYSCALL_CALL_ADDR]
;----------------------------
The problem is how can I write such code in C? I mean I want that there is no new stack frame and that I jump to the code, so that when my syscall returns it goes back to user code which called this stub. (the real problem is that my syscall expects that on the stack there first comes the return address and then the parameters for the function to be called)
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Creating a shared library

Post by Owen »

Just a check: Does removing the ":function" affect anything, and the functions are placed in .text?

As for doing it from C, I think GCC accepts __attribute__((naked)), which makes the function naked (i.e. generates no prologue or epilogue) and is designed exclusively for directly embedding inline ASM in.
FlashBurn
Member
Member
Posts: 313
Joined: Fri Oct 20, 2006 10:14 am

Re: Creating a shared library

Post by FlashBurn »

Ok, shame on me, I found the error, as always the error is in front of the monitor ;)

I used ld instead of i586-elf-ld :(

Now it works as expected, but maybe I will rewrite it for gcc. To use asm is easier because so I can create a shared and a static library out of the object files.
FlashBurn
Member
Member
Posts: 313
Joined: Fri Oct 20, 2006 10:14 am

Re: Creating a shared library

Post by FlashBurn »

So I´m back trying to write my libraries in C and what should I tell, I´m stuck :(

So this is my code:

Code: Select all

#define SYSCALL_VADDR 0xBFFFF000
#define SYSCALL_TIMER_QUERY_COUNTER 10

uint64t timerQueryCounter() __attribute__((naked));
uint64t timerQueryCounter() {
	uint64t res;
	
	asm volatile("jmp (%[addr])"
				:"=A"(res)
				:"a" (SYSCALL_TIMER_QUERY_COUNTER), [addr] "m"(*(uint32t *)SYSCALL_VADDR));
	
	return res;
}
Problems are, that gcc doesn´t support the attribute "naked" on x86 (and I haven´t found another one for x86) and that I don´t know how to write this:

Code: Select all

jmp dword[SYSCALL_VADDR]
in AT&T Syntax.

So help would be good.

Edit::

I just decided that it is easier at the moment to call my syscall stub instead of jumping to it, but this also doesn´t work like I want it to!

I have this code:

Code: Select all

uint64t timerQueryCounter() {
	uint64t res;
	
	asm volatile("call (%[addr])"
				:"=A"(res)
				:"a" (SYSCALL_TIMER_QUERY_COUNTER), [addr] "i"(SYSCALL_VADDR));
	
	return res;
}
But the "call (%[addr])" isn´t assembled into "call (0xBFFFF000)", but instead into "call (0xBFFFF009)". Why is that so?
FlashBurn
Member
Member
Posts: 313
Joined: Fri Oct 20, 2006 10:14 am

Re: Creating a shared library

Post by FlashBurn »

So now I´m able to call my syscall stub, but I can´t get gcc to not create a stack frame.

So here is the solution:

Code: Select all

uint64t timerQueryCounter() {
	uint64t res;
	
	asm volatile("call *%[addr]"
				:"=A"(res)
				:"a" (SYSCALL_TIMER_QUERY_COUNTER), [addr] "m"(*((uint32t *)SYSCALL_VADDR)));
	
	return res;
}
Isn´t there anyone who knows how to make a "naked" (w/o creating a stack frame) function? How create others such syscalls in their libraries?
Selenic
Member
Member
Posts: 123
Joined: Sat Jan 23, 2010 2:56 pm

Re: Creating a shared library

Post by Selenic »

FlashBurn wrote:So now I´m able to call my syscall stub, but I can´t get gcc to not create a stack frame.
Try putting the attribute declaration after the function definition (ie, before the opening '{'). I think it's meant to go there - the callee creates its own stack frame, the caller doesn't care.

You could also use a macro, but that's a bit overkill.

It's also possible that a minimal stack frame is required for some reason, which would prevent GCC from totally removing it (I don't know whether this is actually true; I don't see why it should be, but it might be)
FlashBurn
Member
Member
Posts: 313
Joined: Fri Oct 20, 2006 10:14 am

Re: Creating a shared library

Post by FlashBurn »

Sorry, but I didn´t understand a word from what you were saying :(

Edit::

I found the flag for disable the creating of stack frames (but I thought that this flag is enabled at all O-Levels), its "-fomit-frame-pointer".

So I just need to find out how to create a macro so that I can inline the functions and the compiler push the parameters to the stack.

Edit2::

And now I found a builtin (only for gcc >= 4.5.0) __builtin_unreachable which I can use so that the compiler knows that I´m not returning from my asm statement.
Selenic
Member
Member
Posts: 123
Joined: Sat Jan 23, 2010 2:56 pm

Re: Creating a shared library

Post by Selenic »

FlashBurn wrote:Sorry, but I didn´t understand a word from what you were saying :(
I'm saying that, instead of this (from your earlier post):

Code: Select all

uint64t timerQueryCounter() __attribute__((naked));
uint64t timerQueryCounter() {
...
}
You should have this:

Code: Select all

uint64t timerQueryCounter() __attribute__((naked)) {
...
}
(in fact, if you put declarations immediately above definitions like you had before, they're totally redundant. They're only useful in headers (for obvious reasons) and for declaring functions at the top of a file but defining them at the end, after functions which call them (depends on your style))
FlashBurn wrote:I found the flag for disable the creating of stack frames (but I thought that this flag is enabled at all O-Levels), its "-fomit-frame-pointer".
Just be aware that that option applies to *all* functions (apart from the ones that need it for some other purpose) and disables backtraces, which is a pain if you need to do any kind of debugging.
Also, I believe that flag is only enabled on -O3, which is basically -O2 plus some flags which are known to occasionally break stuff.
FlashBurn wrote:So I just need to find out how to create a macro so that I can inline the functions and the compiler push the parameters to the stack.
You can directly translate your code to a macro (this is GCC-specific; look up "statement exprs" in the GCC info page or the online manual)

Code: Select all

#define timerQueryCounter() ({ uint64_t res; asm volatile (...); res; })
FlashBurn wrote:And now I found a builtin (only for gcc >= 4.5.0) __builtin_unreachable which I can use so that the compiler knows that I´m not returning from my asm statement.
I think __attribute__ ((noreturn)) does the same thing (but more descriptively) and is used for functions like exit()
FlashBurn
Member
Member
Posts: 313
Joined: Fri Oct 20, 2006 10:14 am

Re: Creating a shared library

Post by FlashBurn »

Selenic wrote: You should have this:

Code: Select all

    uint64t timerQueryCounter() __attribute__((naked)) {
    ...
    }
(in fact, if you put declarations immediately above definitions like you had before, they're totally redundant. They're only useful in headers (for obvious reasons) and for declaring functions at the top of a file but defining them at the end, after functions which call them (depends on your style))
This wont work, because gcc only let you define attributes for functions when you declare them (I got an error as I tried it to do so). As I said, "naked" isn´t an attribute for x86 (it´s only for arm and some other cpus).
Selenic wrote: I think __attribute__ ((noreturn)) does the same thing (but more descriptively) and is used for functions like exit()
Nope. The problem is the asm statement. GCC doesn´t know that I´m not returning from it and assumes that the function does return and the other problem is that I have functions which return a value and there "noreturn" also doesn´t work. The macro also wont work, because I need that the parameters are pushed onto the stack.
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: Creating a shared library

Post by Gigasoft »

Save yourself the hassle and write your assembly language functions in assembly language, instead of trying to fit an icosahedron in a christmas tree shaped hole.
Post Reply