My environment is Tornado 2.2 with MIPS64gnu tool chain.
I am writing a simple function like below:
#include <stdio.h>
void main()
{
printf("\n Hello..");
}
When I compiled, it generated some "test.out". I have done "nmmips" on
"test.out".
It printed following information.
0000000000000000 t __gnu_compiled_c
0000000000000040 t __gnu_compiled_c
0000000000000000 D _ctors
0000000000000008 D _dtors
0000000000000000 t gcc2_compiled.
0000000000000040 t gcc2_compiled.
0000000000000000 T main
U printf
According to my understanding, here, "printf" is still undefined.
But when I downloaded this object to target, I am not getting any
unresolved symbols and function executes fine.
I would like to know how this printf function is resolved.
I think I put all necessary information.
Please let me know if any further information is needed.
Thank you !
Regards
Satish.
You want to know how dynamic linking works?
RTFM maybe? ;-)
HTH
GV
The target agent in your target resolves the reference dynamically for
you. As long as "printf" is in the VxWorks image living in your target,
the target agent finds it there and use it.
When you build a downloadable application module only a partial link is
performed as it is expected that OS functions are not yet available.
The printf() (and many other OS functions) code is in the VxWorks image
that is loaded (via one of several possible ways) on your target before
you download your test.out file. When test.out is downloaded, a final
link operation is performed, too, and the previously unresolved reference
to printf() gets resolved at that time.
It is good that you have discovered this early in your VxWorks experience
as you will now understand when builds generate no errors but downloads
fail due to unresolved symbols. This happens any time that your VxWorks
image does not include features that your application expects to be
available. The solution is to add the missing features to your kernel
and rebuild it.
--
========================================================================
Michael Kesti | "And like, one and one don't make
| two, one and one make one."
mrkesti at hotmail dot com | - The Who, Bargain
Hi All.
Thanks alot for your replies.
I have one more question. It will be helpful for me if anybody
clarifies me this.
I built one library "libtest.a" which has functions named func1,
func2, func3, func4, func5 , func6 in a single file.
And I built one application "app.out" which uses only one function
func5 from above library.
When I do "nmmips" on "app.out" , it is giving following information.
0000000000000000 t __gnu_compiled_c
0000000000000030 t __gnu_compiled_c
0000000000000030 T func1
0000000000000050 T func2
0000000000000070 T func3
0000000000000090 T func4
00000000000000b0 T func5
00000000000000e8 T func6
0000000000000000 t gcc2_compiled.
0000000000000030 t gcc2_compiled.
0000000000000000 T main
U printf
By above information, it is clear that it is linking all functions
from func1 to func6 in my application even if I am using only func5.
Is there any way to link only the function func5 in my application?
I thought of breaking each function into different file but this is
not effective solution for me.
Can you please tell me is there any other way to achieve this?
[X]
> Is there any way to link only the function func5 in my application?
>
> I thought of breaking each function into different file but this is
> not effective solution for me.
This is the only solution, as far as I know. The linker always links
whole compilation units, i.e., object files (*.o).
Why is this not effective for you?
This, for most linkers, is true for object files (*.o) but not for
libraries/archives. This can be observed in the VxWorks driver libs
where multiple drivers are archived per file but only those referenced
are linked into the output file.
Satish, you can help us help you by providing more information. What
tool set are you using? How did you build the library and how are you
linking it into you app.out. (Supplying actual command lines would be
a good way to answer the latter.)
You know, it could be that, because you are creating an application, the
partial linker rules are being used and the linker decides it cannot know
which functions are going to be ultimately referenced and therefore
includes them all.
>Why is this not effective for you?
Regardless of the answer to that question, this is an interesting
"academic" query!
Hi Michael,
I am using MIPS64gnu tool chain.
I built my library by setting archive in the "rules" tab.
Then, in my application project, I am giving following commands in
"rules" tab.
Target : app.out dependencies : test_app.a
$(LD) -EB -r -o app.out app.o -LD:/Satish-6-23-2008/test_lib\MIPS64gnu
-ltest
In above command, app.c is my application, libtest.a is my library.
Please let me know if I have any problem with commnd options.
Regards
Satish.
>On Jun 27, 7:32 am, "Michael R. Kesti" <michaelke...@nospam.net>
>wrote:
>
>> This, for most linkers, is true for object files (*.o) but not for
>> libraries/archives. This can be observed in the VxWorks driver libs
>> where multiple drivers are archived per file but only those referenced
>> are linked into the output file.
>>
>> Satish, you can help us help you by providing more information. What
>> tool set are you using? How did you build the library and how are you
>> linking it into you app.out. (Supplying actual command lines would be
>> a good way to answer the latter.)
>>
>> You know, it could be that, because you are creating an application, the
>> partial linker rules are being used and the linker decides it cannot know
>> which functions are going to be ultimately referenced and therefore
>> includes them all.
>
>I am using MIPS64gnu tool chain.
>
>I built my library by setting archive in the "rules" tab.
>
>Then, in my application project, I am giving following commands in
>"rules" tab.
>
>Target : app.out dependencies : test_app.a
>
>$(LD) -EB -r -o app.out app.o -LD:/Satish-6-23-2008/test_lib\MIPS64gnu
>-ltest
>
>In above command, app.c is my application, libtest.a is my library.
>
>Please let me know if I have any problem with commnd options.
I'm sorry to say that I find nothing wrong with any of that. I do see,
however, that you are using the -r option so this is a partial link. I
didn't find anywhere in the documentation that describes the linker's
behavior with regard to libraries when paritally linking but it is still
my hinch that it includes everything because it cannot know what will
ultimately be referenced. Being an application, however, you're pretty
much forced to use partial linking as there will be unresolved references
to OS components.
The bottom line: I dunno!
Hi Michael,
Thanks for your replies.
I have one question.
If you dont mind, Can you please clarify?
1. Here, in linking options, why we should use "-r" option ?
2. If my code is like below:
void main()
{
printf("\n Hello..");
}
and in my linking options, if I remove "-r" option, it gives following
error:
armips crus test_project.a @..\prjObjs.lst
ldmips -EB -o project.out test.o
\cygdrive\d\Tornado2.2_MIPS\Mips\host\x86-win32\bin\ldmips: warning:
cannot find entry sym
bol _start; defaulting to 0000000000400000
test.o: In function `main':
d:\test\test_project\MIPS64gnu\..\test.c:12: undefined reference to
`printf'
make: *** [project.out] Error 0x1
3. If my code is like below:
void main()
{
}
And in linking options, if "-r" option is not there, build log is like
below:
armips crus test_project.a @..\prjObjs.lst
ldmips -EB -o project.out test.o
\cygdrive\d\Tornado2.2_MIPS\Mips\host\x86-win32\bin\ldmips: warning:
cannot find entry sym
bol _start; defaulting to 0000000000400000
Done.
And this program can not run properly. What might be the reason for
this?
4. During the final link operation, Can we do any thing such that I
can avoid linking of unused functions?
>Hi Michael,
>
>Thanks for your replies.
You're welcome.
>I have one question.
>
>If you dont mind, Can you please clarify?
Sure. Or, at lease, I'll try!
>1. Here, in linking options, why we should use "-r" option ?
The -r option means that the linker's output is to be relinkable. This
is also known as partial linkage. This means several things including,
as previously discussed, not all symbols need to be resolved and, as
you have discovered, the entry symbol, _start, need not be defined.
There may be other differences between partial and full links, too.
Full linkage is typically used when building boot ROM and VxWorks images
because these builds must completely ready for execution and therefore
require resolution of all symbols and entry point (the _start symbol)
must be provided and set to a specific addresses.
Partial linkage is typically used to build downloadable application
images as they are expected to contain unresolved symbols and it is
not known at link time where in memory they might be loaded.
Library builds are not linked at all. Instead. the "ar" program is used
to write object files to the output (library) file.
>2. If my code is like below:
>
>void main()
>{
> printf("\n Hello..");
>}
>
>and in my linking options, if I remove "-r" option, it gives following
>error:
>
>armips crus test_project.a @..\prjObjs.lst
>ldmips -EB -o project.out test.o
>\cygdrive\d\Tornado2.2_MIPS\Mips\host\x86-win32\bin\ldmips: warning:
>cannot find entry sym
>bol _start; defaulting to 0000000000400000
>test.o: In function `main':
>d:\test\test_project\MIPS64gnu\..\test.c:12: undefined reference to
>`printf'
>make: *** [project.out] Error 0x1
This is all to be expected. Because the -r option has been omitted this
is a full link but your call to printf(), whose code is in a VxWorks
image rather than in test.o, cannot be resolved. Further, because test.o
does not define _start, the linker has supplied it and assigned it a
default address so that it can try to create an absolute image.
>3. If my code is like below:
>
>void main()
>{
>}
>
>And in linking options, if "-r" option is not there, build log is like
>below:
>
>armips crus test_project.a @..\prjObjs.lst
>ldmips -EB -o project.out test.o
>\cygdrive\d\Tornado2.2_MIPS\Mips\host\x86-win32\bin\ldmips: warning:
>cannot find entry sym
>bol _start; defaulting to 0000000000400000
>
>Done.
In this case you have eliminated the unresolved call to printf() but
the _start sysmbol is still not defined and is again supplied by the
linker and set to a default address.
>And this program can not run properly. What might be the reason for
>this?
I believe that this is because project.out was linked to an absolute
image that is to be loaded starting at address 0x400000 and, when this
file is downloaded to your target, it get loaded at that address. The
problem may be that this is also where your VxWorks image was loaded
and the VxWorks image is therefore partially overwritten. Once that
happens the system behavior is, as they say, unpredictable!
>4. During the final link operation, Can we do any thing such that I
>can avoid linking of unused functions?
Assuming that you are referring to the final link that occurs when a
partially linked application is downloaded to a target, I believe that
the only way is to arrange for the unused functions to not be included
in the partially linked application.
This is, at least, the case for VxWorks prior to version 6 which I
believe is your case as you said you're using Tornado 2.2. (Tornado is
replaced by Workbench in version 6.) Version 6 includes a new kind of
application called the real time process (RTP). One of the features
of RTPs is that they support shared libraries which, I believe, provide
the kind of operation you seek.