> -----Original Message-----
> From: Scott C. Gray [mailto:[EMAIL PROTECTED]]
> Sent: Monday, August 14, 2000 4:18 AM
> To: [EMAIL PROTECTED]
> Subject: Tables of function pointers
>
>
>
> I realize this is only partially libtool related, but I figured
> that this is probably a good forum for this question.
>
> I have a shared library built with libtool, in which there is
> a module that is roughly defined as so:
>
> static int function_0 (int arg1);
> static int function_1 (int arg1);
> static int function_2 (int arg1);
> static int function_3 (int arg1);
>
> typedef int (funcptr) (int arg1);
>
> static funcptr *sg_func_table[] = {
> function_0,
> function_1,
> function_2,
> function_3,
> };
>
> int call_function(int funcnbr, int arg)
> {
> return sg_func_table[funcnbr](arg);
> }
>
> static int function_0(int arg1)
> {
> ...
> }
>
> ...
>
> The problem that I am encountering is that, on Linux call_function()
> works just great, but on Solaris 2.7 (gcc 2.95.1, ld 3.0), it
> consistantly core dumps.
>
> When pulled up in the debugger, displaying the address of
> function_0 gives something like 0xff35cd60, but when
> displaying the address that is stored in sg_func_table[0]
> I get 0x35cd60:
>
> (gdb) p function_0
> $1 = {int (int)} 0xff35cd60 <function_0>
> (gdb) p sg_func_table[0]
> $1 = (funcptr *) 0x35cd60
>
> Any ideas why I get this behavior? When statically linking
> my program everything works just dandy as well. It looks to
> me that, for some reason, the addresses stored in sg_func_table[]
> are not PIC addresses.
>
Maybe I'm wrong, or building on old assumptions, but I think the problem is
that in tha table you get PIC offsets in the '.so' to the functions and your
'.so' was mapped at address 0xff000000 ;-(
Probably the simplest (and more protable) cure would be to have an
'init_function_table' function that initialize the function array, like:
void init_function_table() {
static int initialized = 0;
if (initialized) return;
sg_func_table[0] = function_0;
sg_func_table[1] = function_1;
sg_func_table[2] = function_2;
sg_func_table[3] = function_3;
initialized = 1;
}
and either call it at the very beginning of your main program or, if it is a
general purpose library used in numerous programs and performance is not too
critical, call it at the very beginning of call_function (anyway any good C
compiler like gcc should be able to integrate it in-line, especially if
declared static, so the cost is only a test and branch).
HTH,
Bernard
--------------------------------------------
Bernard Dautrevaux
Microprocess Ingéniérie
97 bis, rue de Colombes
92400 COURBEVOIE
FRANCE
Tel: +33 (0) 1 47 68 80 80
Fax: +33 (0) 1 47 88 97 85
e-mail: [EMAIL PROTECTED]
[EMAIL PROTECTED]
--------------------------------------------