Operating System - HP-UX
1834878 Members
2547 Online
110071 Solutions
New Discussion

help need with handling libraries loaded using shl_load

 
Premkumar P
Occasional Contributor

help need with handling libraries loaded using shl_load

hi,
i will start with what i am trying to do,
my program loads shared libraries using shl_load and then calls and exposed method called "Initilizer".

The code:
#include
#include
#include
#include
#include
#include

typedef long (*Function_T)(char *,...);

void* LoadandCall(char *libraryname)
{
shl_t dl_handle;
long bind_flags = BIND_DEFERRED;
struct shl_descriptor *desc;
int i, rc;
char imagename[20];
char buffer[512];
void *sym_adr = NULL;
void *entrypoint = NULL;

//append .sl to the end
strcpy(imagename, libraryname);
strcat(imagename, ".sl");

//load the library
dl_handle = shl_load( imagename, bind_flags, 0L );

if(dl_handle == 0 )
{
printf("unable to load %s %s\n", imagename, strerror(errno));
return 1;
}
else
{
printf("The address of the loaded function is %u \n", dl_handle);
}

//printf the filename loaded if the load is successfull
for ( i = 0; i < 512; i++ )
{
rc = shl_get( i, &desc );
if ( rc == 0 ) {
if ( dl_handle == desc->handle ) {
strcpy( buffer, desc->filename );
printf("The filename for the handle returned is: %s \n", buffer);
}
}
else
break;
}

sym_adr = 0;
entrypoint = 0;

rc = shl_findsym( &dl_handle, "Initilizer", TYPE_PROCEDURE, &sym_adr );

if(rc < 0) {
printf(" Error when trying to get Initilizer %d\n", rc);
return 1;
}

entrypoint = (DspatchFN_T)sym_adr;
((Function_T)entrypoint)(imagename,"Initialize");

//unload the library
/* shl_unload(dl_handle); */
return 0;
}

int main()
{
LoadandCall("A");
LoadandCall("B");
LoadandCall("C");
}

the problem:
the above program runs fine, but if i remove shl_unload, then the calls for B and C also end up calling the initilizer of A. The behaviour is strange
This is a test program, acutally i have to keep these libraries in memory at the same time.

is this the way loading is meant to be done ??

about the libraries:
the libraraies i am trying to load are c++ shared libs, having an exposed method that initilizes a c++ class withing which inturn initilizes a c++ class(this is different between the libs). the libraries might expose same symbols and stuff

The way all the c++ libs are created is just the same

advise please,

regards
6 REPLIES 6
Dennis Handly
Acclaimed Contributor

Re: help need with handling libraries loaded using shl_load

I have no problems with and without the shl_load with simple C functions.

>the libraries might expose same symbols and stuff

You can't do this except for your extern "C" function "Initilizer".

If you are going to use C++ classes, you need to make sure they are different in each of the shared libs, 3.2 ODR rule. With the way dld(5) works, each lib will call only the first symbols of that name, even if defined inside itself. While there are linker options to control this, you may be asking for trouble.

I would need more info on why you want to do this?
Premkumar P
Occasional Contributor

Re: help need with handling libraries loaded using shl_load

sorry! i was wrong, the class exports only the 'initilizer' function and 2 more functions 'attach' and 'detach' namely.

i will try my best to explain wht the libs are made of:
i have a base class lets call it as "SUPPOTCLASS", and then i have service classes lets call them "SERVICE",
we compile the SUPPORTCLASS class first, then we have differnt services which are linked to the SUPPORTCLASS class. and my program is calling the exposed initilizer which in turn creates and instance of the BASE class, which creates an instance of SERVICE class(which is differnt for differnt shared libraries)...

all the functionality common for the services are implemented in the SUPPORTCLASS and the services have some specific implemention for the type of service they provide..

it is a server environment wheren when u put the shared libraries and a corresponding configuration then it will automatically be loaded by the server program...

Dennis Handly
Acclaimed Contributor

Re: help need with handling libraries loaded using shl_load

>the class exports only the 'initilizer' function and 2 more functions 'attach' and 'detach' namely.

Did you mean "class" or the shlib exports?

By default, HP-UX exports EVERY global symbol in a shared lib.

>I have a base class lets call it as "SUPPORTCLASS", and then i have service classes lets call them "SERVICE",

If all 3 shlibs have the same class names, you are violating the ODR rule and this isn't supported.

>we compile the SUPPORTCLASS class first, then we have different services which are linked to the SUPPORTCLASS class. and my program is calling the exposed initilizer which in turn creates and instance of the BASE class, which creates an instance of SERVICE class (which is different for different shared libraries)...

Different names or different functionality?

This is something where you have to be an expert and can cause lots of problems if you don't know what you are doing.

Other than me saying "don't do this", I would have to have a small test case (attach it) that fails so I can add the next set of kludges to move you on.
Premkumar P
Occasional Contributor

Re: help need with handling libraries loaded using shl_load

hi dennis,
thank you, for your valuable time.

as i cant share the code i am taking about(company stuff),
i wrote a similar one just that it dosent do anytime, but still the problem can be found.

"i am upload the file as loader.tar"
content:
loader -- contains loader.c which loads and makes calls
support -- a archive library that is used by any service for base functionalities

services/service* - differnt services, shared libraries that are loaded by the loader

problem:
this is the output i got when is used shl_unload after making the necessary calls,

The address of the loaded function is 2139010832
the buffer content is service1.sl
got addre for proc and it is 2138878086
Dispatch function called with name service1.sl
Support initilizing
Initilizing class service 1
Service called for service1
The address of the loaded function is 2139010832
the buffer content is service2.sl
got addre for proc and it is 2138878070
Dispatch function called with name service2.sl
Support initilizing
Initilizing class service 2
Service called for service 2
The address of the loaded function is 2139010832
the buffer content is service3.sl
got addre for proc and it is 2138878086
Dispatch function called with name service3.sl
Support initilizing
Initilizing class service 3
Service called for service 3


but if i remove shl_unload, i get this output:
The address of the loaded function is 2139010832
the buffer content is service1.sl
got addre for proc and it is 2138878086
Dispatch function called with name service1.sl
Support initilizing
Initilizing class service 1
Service called for service1
The address of the loaded function is 2139012144
the buffer content is service2.sl
got addre for proc and it is 2139003802
Dispatch function called with name service2.sl
Support initilizing
Initilizing class service 1
Service called for service1
The address of the loaded function is 2139012472
the buffer content is service3.sl
got addre for proc and it is 2139004250
Dispatch function called with name service3.sl
Support initilizing
Initilizing class service 1
Service called for service1

note that the same service is being initlized though it says service 2 and service 3 ....

please let me know what is wrong in the code, the code i have attached is at max 50 lines.

thankx in advance...
Premkumar P
Occasional Contributor

Re: help need with handling libraries loaded using shl_load

hi,
the above problem can be solved by using
BIND_RESTRICTED and BIND_FIRST when loading the library using shl_load.

but i still dont understand why this happends, when the man pages for shl_findsym tells that it will search for the symbol only in the specified library(handle that is.)....

thankx
Dennis Handly
Acclaimed Contributor

Re: help need with handling libraries loaded using shl_load

As I mentioned what you are doing is illegal. You have 2 C++ functions that have exactly the same name in the 3 shlibs:
Invoke__7supportFv interface__Fv

As I mentioned dld.sl(5) binds to the first.
And by default, HP-UX exports EVERY global symbol in a shared lib.

>the above problem can be solved by using
BIND_RESTRICTED and BIND_FIRST when loading the library using shl_load.

BIND_RESTRICTED is may be what you want. This causes the symbols to be bound locally.

You should never ever use BIND_FIRST since it not standard and no other vendor supports it. BIND_FIRST would not work if you chose to call service1 twice. BIND_FIRST will get you into trouble on IPF.

>shl_findsym tells that it will search for the symbol only in the specified library(handle that is.)....

This part works fine. The problem is that function HookFun calls Invoke__7supportFv which dld binds to the first shlib. Similar problems with interface().

Changes in your test case:
You need to link your a.out with -z. It doesn't work on shlibs. Also add -lcl.

If you are printing out addresses, you must use %p. Do not use decimal.

Your link line for your services shlibs should be:
aCC -b -lstd_v2 -lCsup_v2 -lcl -Wl,-Bsymbolic

You had the -AP lib -lCsup and were missing -lcl. You also had the libs in the wrong order:
http://www.docs.hp.com/en/7762/5991-4874/distributing.htm#linking

(You'll need to link your a.out with -lcl, since you use -mt.)

But your immediate issue was either you need to use BIND_* or you need to use -Wl,-Bsymbolic, which causes calls in a shlib to bind locally if present.

If you call U_STACK_TRACE(), you would see what you were going:

extern "C" void U_STACK_TRACE();

Dispatch function called with name service3.sl
Support initilizing
Initilizing class service 1
( 0) 0xc033b8c0 __ct__8service1Fv_2 + 0x40 [service1.sl]
( 1) 0xc033b7b8 interface__Fv + 0x18 [service1.sl]
( 2) 0xc033bb14 Invoke__7supportFv + 0x1c [service1.sl]
( 3) 0xc0463a3c HookFun + 0x40 [service3.sl]
( 4) 0x00002ebc LoadandCall + 0x25c [./a.out]