LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-25-2008, 01:14 AM   #1
crackdownload
LQ Newbie
 
Registered: Dec 2008
Posts: 3

Rep: Reputation: 0
Question Calls the same shared library, but yields different result. Very strange!!!


First let's see the simple test code as follows:
------------- fn.c
#include <stdio.h>
int myfn()
{
printf("The myfn in main called\n");
return 8903;
}

------------- main.c
#include <stdio.h>
#include <dlfcn.h>

extern int myfn();

#ifdef TEST1
//the function declared in shared library
extern void testmyfn();
#endif

int main()
{
#ifdef TEST2
//call shared library function with dlopen and dlsym
void *handle;
void (*fptr)();

/* open the needed object */
handle = dlopen("./libdll.so", RTLD_LOCAL | RTLD_NOW);

/* find the address of function and data objects */
*(void **)(&fptr) = dlsym(handle, "testmyfn");

/* invoke function */
(*fptr)();
#endif

printf("calling myfn in main function...\n");
printf("myfn = %d\n\n", myfn());

#ifdef TEST1
//directly call shared library function
testmyfn();
#endif

return 0;

------------------------fndll.c
#include <stdio.h>
//another myfn function with the same prototype as that in file fn.c
int myfn()
{
printf("The myfn in dll called\n");
return 1234;
}

void testmyfn()
{
int x = myfn(); //intend to call the myfn function in shared library. But
//actually the myfn function in fn.c might be called. ???
printf("Calling myfn in dll...\n");
printf("myfn = %d\n\n", x);
}

Compile fndll.c to produce libdll.so. Compile fn.c and main.c to produce main executable test1 or test2, depending the following two makefiles.
-----------------Makefile.test1
OBJ=test1

CFLAGS=-O0 -ggdb -DTEST1

$(OBJ): libdll.so main.o fn.o
$(CC) -o$(OBJ) main.o fn.o -L./ -ldll
# $(CC) -o$(OBJ) main.o fn.o -ldl

main.o: main.c
$(CC) $(CFLAGS) -c -o main.o main.c

fn.o: fn.c
$(CC) $(CFLAGS) -c -o fn.o fn.c

libdll.so: fndll.c
$(CC) $(CFLAGS) --shared -o libdll.so fndll.c

clean:
rm -fr *.o *.so $(OBJ)

---------------------------Makefile.test2
OBJ=test2

CFLAGS=-O0 -ggdb -DTEST2

$(OBJ): libdll.so main2.o fn.o
# $(CC) -o$(OBJ) main2.o fn.o -L./ -ldll
$(CC) -o$(OBJ) main2.o fn.o -ldl

main2.o: main.c
$(CC) $(CFLAGS) -c -o main2.o main.c

fn.o: fn.c
$(CC) $(CFLAGS) -c -o fn.o fn.c

libdll.so: fndll.c
$(CC) $(CFLAGS) --shared -o libdll.so fndll.c

clean:
rm -fr *.o *.so $(OBJ)

Execute test1, and I find that the call to myfn function in the testmyfn function in shared library actually calls the one in fn.c, but not the one in fndll.c. I am surprised.
Execute test2, and I find that the call to myfn function in the testmyfn function in shared library calls the one in fndll.c. It is what people usually expect.

Any idea? Thanks first.
 
Old 12-25-2008, 05:19 AM   #2
crackdownload
LQ Newbie
 
Registered: Dec 2008
Posts: 3

Original Poster
Rep: Reputation: 0
assembly language

use objdump to view the assembly language code of libdll.so. I find that the call instruction is very strange.
----------------------------------
00000544 <myfn>:
#include <stdio.h>
//#include <stdlib.h>

int myfn()
{
544: 55 push %ebp
545: 89 e5 mov %esp,%ebp
547: 83 ec 08 sub $0x8,%esp
printf("The myfn in dll called\n");
54a: 83 ec 0c sub $0xc,%esp
54d: 68 de 05 00 00 push $0x5de
552: e8 fc ff ff ff call 553 <myfn+0xf>
557: 83 c4 10 add $0x10,%esp
return 1234;
55a: b8 d2 04 00 00 mov $0x4d2,%eax
}
55f: c9 leave
560: c3 ret

00000561 <testmyfn>:

void testmyfn()
{
561: 55 push %ebp
562: 89 e5 mov %esp,%ebp
564: 83 ec 08 sub $0x8,%esp
int x = myfn();
567: e8 fc ff ff ff call 568 <testmyfn+0x7>
56c: 89 45 fc mov %eax,0xfffffffc(%ebp)
printf("Calling myfn in dll...\n");
56f: 83 ec 0c sub $0xc,%esp
572: 68 f6 05 00 00 push $0x5f6
577: e8 fc ff ff ff call 578 <testmyfn+0x17>
57c: 83 c4 10 add $0x10,%esp
printf("myfn = %d\n\n", x);
57f: 83 ec 08 sub $0x8,%esp
582: ff 75 fc pushl 0xfffffffc(%ebp)
585: 68 0e 06 00 00 push $0x60e
58a: e8 fc ff ff ff call 58b <testmyfn+0x2a>
58f: 83 c4 10 add $0x10,%esp
}
592: c9 leave
593: c3 ret
-----------------------------------------------------------

Look at this line.
567: e8 fc ff ff ff call 568 <testmyfn+0x7>
It corresponds to the call to myfn function. "e8" means Intel i386 call instruction. "fc ff ff ff" should means the relative address. Obviously, the relatvie address does not means the myfn function in both fn.c and fndll.c. I guess the instruction calls a glibc function, which does some job I still don't know.

Else, people who understand the shared library loading mechanism can give me some hints.
 
Old 12-25-2008, 10:19 AM   #3
SciYro
Senior Member
 
Registered: Oct 2003
Location: hopefully not here
Distribution: Gentoo
Posts: 2,038

Rep: Reputation: 51
I cant get your code to run so I cant test this, so Ill just say that its probably those declarations at the start main.c. In the first test, the main is linked directly to the lib, so the linker is probably seeing the main's definition for the function first, and using that. In the second example, its not being linked, so the linker uses the definition found in the lib as it cant see inside the main.
 
Old 12-25-2008, 12:12 PM   #4
jiml8
Senior Member
 
Registered: Sep 2003
Posts: 3,171

Rep: Reputation: 116Reputation: 116
Quote:
Originally Posted by SciYro View Post
I cant get your code to run so I cant test this, so Ill just say that its probably those declarations at the start main.c. In the first test, the main is linked directly to the lib, so the linker is probably seeing the main's definition for the function first, and using that. In the second example, its not being linked, so the linker uses the definition found in the lib as it cant see inside the main.
That seems likely to me too.
 
Old 12-25-2008, 07:12 PM   #5
crackdownload
LQ Newbie
 
Registered: Dec 2008
Posts: 3

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by SciYro View Post
I cant get your code to run so I cant test this, so Ill just say that its probably those declarations at the start main.c. In the first test, the main is linked directly to the lib, so the linker is probably seeing the main's definition for the function first, and using that. In the second example, its not being linked, so the linker uses the definition found in the lib as it cant see inside the main.
I think the problem is not at link time, but at the time the shared library is being loaded.

You know, the shared library libdll.so is generated before test1. There is no chance that linker will link the myfn call in the shared library to the one in test1. Actually, I think the call to myfn function in shared library is relocated at the time the shared library is being loaded. Surprising, in test1, the call to myfn function in shared library is relocated to the first myfn function. In test2, the call is relocated to the second one. So I think the problem is the two different shared library loading mechanisms.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
gcc link shared library against another shared library qcp Linux - Newbie 1 07-25-2008 11:15 AM
Making a static library from a given shared library vro Programming 1 07-27-2007 04:07 PM
LINUX - linking archive (static library) with shared (dynamic) library gurkama Programming 5 03-04-2007 11:11 PM
strange linking error -- can not find shared library George2 Programming 1 07-10-2006 11:24 AM
howto compile bin with my library using all-static and shared linked standart library stpg Programming 4 06-29-2004 04:20 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:23 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration