> -----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]
-------------------------------------------- 

Reply via email to