Page 1 of 1

Creating a shared library

Posted: Fri Mar 05, 2010 10:10 am
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?

Re: Creating a shared library

Posted: Sat Mar 06, 2010 1:58 am
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)

Re: Creating a shared library

Posted: Sat Mar 06, 2010 6:02 am
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.

Re: Creating a shared library

Posted: Sat Mar 06, 2010 8:22 am
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.

Re: Creating a shared library

Posted: Mon Apr 12, 2010 11:01 am
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?

Re: Creating a shared library

Posted: Thu Apr 15, 2010 9:56 am
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?

Re: Creating a shared library

Posted: Thu Apr 15, 2010 10:01 am
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)

Re: Creating a shared library

Posted: Thu Apr 15, 2010 10:11 am
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.

Re: Creating a shared library

Posted: Fri Apr 16, 2010 10:07 am
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()

Re: Creating a shared library

Posted: Fri Apr 16, 2010 10:29 am
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.

Re: Creating a shared library

Posted: Fri Apr 16, 2010 12:55 pm
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.