Mandalika's scratchpad [ Work blog @Oracle | My Music Compositions ]

Old Posts: 09.04  10.04  11.04  12.04  01.05  02.05  03.05  04.05  05.05  06.05  07.05  08.05  09.05  10.05  11.05  12.05  01.06  02.06  03.06  04.06  05.06  06.06  07.06  08.06  09.06  10.06  11.06  12.06  01.07  02.07  03.07  04.07  05.07  06.07  08.07  09.07  10.07  11.07  12.07  01.08  02.08  03.08  04.08  05.08  06.08  07.08  08.08  09.08  10.08  11.08  12.08  01.09  02.09  03.09  04.09  05.09  06.09  07.09  08.09  09.09  10.09  11.09  12.09  01.10  02.10  03.10  04.10  05.10  06.10  07.10  08.10  09.10  10.10  11.10  12.10  01.11  02.11  03.11  04.11  05.11  07.11  08.11  09.11  10.11  11.11  12.11  01.12  02.12  03.12  04.12  05.12  06.12  07.12  08.12  09.12  10.12  11.12  12.12  01.13  02.13  03.13  04.13  05.13  06.13  07.13  08.13  09.13  10.13  11.13  12.13  01.14  02.14  03.14  04.14  05.14  06.14  07.14  09.14  10.14  11.14  12.14  01.15  02.15  03.15  04.15  06.15  09.15  12.15  01.16  03.16  04.16  05.16  06.16  07.16  08.16  09.16  12.16  01.17  02.17  03.17  04.17  06.17  07.17  08.17  09.17  10.17  12.17  01.18  02.18  03.18  04.18  05.18  06.18  07.18  08.18  09.18  11.18  12.18  01.19  02.19  05.19  06.19  08.19  10.19  11.19  05.20  10.20  11.20  12.20  09.21  11.21  12.22 


Wednesday, September 15, 2004
 
Solaris/S1S9: Scope of Symbols: Default scope contd.,

[Updated: 04/07/2006] Much accurate information is available in a better format at:
Reducing Symbol Scope with Sun Studio C/C++
__________________

Lets add one more local method called "addtentomyage()" in hidden.h

hidden.h
---------
bpte4500s001:/sunbuild1/giri/testcases/symbol-hiding/%cat hidden.c
#include
#include "hidden.h"

int age = 25;

int addtentomyage(int age)
{
return ((int) age + 10);
}

char *lastname(char *firstname)
{
return ((char *)"mandalika");
}

char firstchar(char *strings)
{
return (*strings);
}

int agefunc()
{
int finalage = 0;

finalage = addtentomyage(age);
return (finalage);
}


Create libhidden.so and run the driver program

bpte4500s001:/sunbuild1/giri/testcases/symbol-hiding/% CC -c hidden.c ; CC -G -o libhidden.so hidden.o ; CC -lhidden -o driver driver.c

bpte4500s001:/sunbuild1/giri/testcases/symbol-hiding/%./driver

lname = mandalika
age = 35
first char = c
Cool; got the expected result

Now lets introduce one more library called "libgeneric" with a buggy implementation for addtentomyage()

bpte4500s001:/sunbuild1/giri/testcases/symbol-hiding/%cat generic.c
#include "hidden.h"

int addtentomyage(int age)
{
return ((int) age + 100);
}
Compile & create a new library called "libgeneric"

bpte4500s001:/sunbuild1/giri/testcases/symbol-hiding/%CC -c generic.c ; CC -G -o libgeneric.so generic.o

Now link the new library (libgeneric) with the driver executable as follows (observe that libgeneric is placed before libhidden in the compile line):

bpte4500s001:/sunbuild1/giri/testcases/symbol-hiding/%CC -o driver -lgeneric -lhidden driver.c

Run the driver program and observe the result:
bpte4500s001:/sunbuild1/giri/testcases/symbol-hiding/%./driver

lname = mandalika
age = 125
first char = c
That's not good; the expected age was 35, but got 125! What's wrong?

Even though there is an implementation available inside the libhidden module itself, linker picked up the implementation from libgeneric by blindly following the left to right rule (ref: Linker & Libraries guide by Sun Microsystems). And in general references to global symbols within shared objects are not bound until runtime, even if definitions are available, so that definitions of the same symbol in an executable or other shared object can override the object's own definition

The tool "ldd" will be useful for dumping the dependency ordering
bpte4500s001:/sunbuild1/giri/testcases/symbol-hiding/%ldd driver
libgeneric.so => /sunbuild1/giri/testcases/symbol-hiding/libgeneric.so
libhidden.so => /sunbuild1/giri/testcases/symbol-hiding/libhidden.so
libCstd.so.1 => /usr/lib/libCstd.so.1
libCrun.so.1 => /usr/lib/libCrun.so.1
libm.so.1 => /usr/lib/libm.so.1
libw.so.1 => /usr/lib/libw.so.1
libc.so.1 => /usr/lib/libc.so.1
libdl.so.1 => /usr/lib/libdl.so.1
/usr/lib/cpu/sparcv8plus/libCstd_isa.so.1
/usr/platform/SUNW,Ultra-Enterprise/lib/libc_psr.so.1
Advantage:
The application can take advantage of interposing libraries i.e., if needed, the application can enjoy an alternate implementation for the same set of interfaces if available

Disadvantage:
Name collisions (just like the one shown in the example); due to the collision the application may break (our example shows that broken part - expected value: 35, but the returned value is: 125)

How to override this default behavior and make it pick the right implementation?

(to be continued ..)


Comments: Post a Comment



<< Home


2004-2019 

This page is powered by Blogger. Isn't yours?