Utilities


Now let s look at some of the other utilities that are useful when creating static, shared, or dynamic libraries.

file

The file utility tests the file argument for the purposes of identifying what it is. This utility is very useful in a number of different scenarios, but in this case it will provide us with a small amount of information about the shared object. Let s look at an interactive example:

 $  file /usr/local/lib/libmyrand.so  /usr/local/lib/libmyrand.so: ELF 32-bit LSB shared object,  Intel 80386, version 1 (SYSV), not stripped $ 

So, using file , we see that our shared library is a 32-bit ELF object for the Intel 80386 processor family. It has been defined as not stripped, which simply means that debugging information is present.

size

The size command provides us with a very simple way to understand the text , data , and bss section sizes for an object. An example of the size command on our shared library is shown here:

 $  size /usr/local/lib/libmyrand.so    text    data     bss     dec     hex filename   2013     264       4    2281     8e9 /usr/local/lib/libmyrand.so $ 

nm

To dig into the object, we use the nm command. This commands permits us to look at the symbols that are available within a given object file. Let s look at a simple example using grep to filter our results:

 $  nm -n /usr/local/lib/libmyrand.so  grep " T "  00000608 T _init 0000074c T initRand 00000784 T getSRand 000007be T getRand 00000844 T _fini $ 

In this example, we use nm to print the symbols within the shared library, but then only emit those with the tag " T " to stdout (those symbols that are part of the .text section, or code segments). We also use the -n option to sort the output numerically by address, rather than the default, which is alphabetically by symbol name . This gives us relative address information within the library; if we wanted to know the specific sizes of these .text sections, we could use the -S option, as:

 $  nm -n -S /usr/local/lib/libmyrand.so  grep " T "  00000608 T _init 0000074c 00000036 T initRand 00000784 0000003a T getSRand 000007be 00000050 T getRand 00000844 T _fini $ 

From this example, we can see that the initRand is located at relative offset 0 74c in the library and its size is 0 36 (decimal 54) bytes. Many other options are available; the nm mainpage provides more detail on this.

objdump

The objdump utility is similar to nm in that it provides the ability to dig in and inspect the contents of an object. Let s now look at some of the specialized functions of objdump .

One of the most interesting features of objdump is its ability to disassemble the object into the native instruction set. Here s an excerpt of objdump performing this capability:

 $  objdump -disassemble -S /usr/local/lib/libmyrand.so  ... 0000074c <initRand>:   74c:   55                      push   %ebp   74d:   89 e5                   mov    %esp,%ebp   74f:   53                      push   %ebx   750:   83 ec 04                sub 
 $  objdump -disassemble -S /usr/local/lib/libmyrand.so  ... 0000074c <initRand>:   74c: 55 push %ebp   74d: 89 e5 mov %esp,%ebp   74f: 53 push %ebx   750: 83 ec 04 sub $0x4,%esp   753: e8 00 00 00 00 call 758 <initRand+0xc>   758: 5b pop %ebx   759: 81 c3 f8 11 00 00 add $0x11f8,%ebx   75f: 83 ec 0c sub $0xc,%esp   762: 6a 00 push $0x0   764: e8 c7 fe ff ff call 630 <_init+0x28>   769: 83 c4 10 add $0x10,%esp   76c: 89 45 f8 mov %eax,0xfffffff8(%ebp)   76f: 83 ec 0c sub $0xc,%esp   772: ff 75 f8 pushl 0xfffffff8(%ebp)   775: e8 d6 fe ff ff call 650 <_init+0x48>   77a: 83 c4 10 add $0x10,%esp   77d: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   780: c9 leave   781: c3 ret   782: 90 nop   783: 90 nop ... $ 
x4,%esp 753: e8 00 00 00 00 call 758 <initRand+0xc> 758: 5b pop %ebx 759: 81 c3 f8 11 00 00 add
 $  objdump -disassemble -S /usr/local/lib/libmyrand.so  ... 0000074c <initRand>:   74c: 55 push %ebp   74d: 89 e5 mov %esp,%ebp   74f: 53 push %ebx   750: 83 ec 04 sub $0x4,%esp   753: e8 00 00 00 00 call 758 <initRand+0xc>   758: 5b pop %ebx   759: 81 c3 f8 11 00 00 add $0x11f8,%ebx   75f: 83 ec 0c sub $0xc,%esp   762: 6a 00 push $0x0   764: e8 c7 fe ff ff call 630 <_init+0x28>   769: 83 c4 10 add $0x10,%esp   76c: 89 45 f8 mov %eax,0xfffffff8(%ebp)   76f: 83 ec 0c sub $0xc,%esp   772: ff 75 f8 pushl 0xfffffff8(%ebp)   775: e8 d6 fe ff ff call 650 <_init+0x48>   77a: 83 c4 10 add $0x10,%esp   77d: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   780: c9 leave   781: c3 ret   782: 90 nop   783: 90 nop ... $ 
x11f8,%ebx 75f: 83 ec 0c sub
 $  objdump -disassemble -S /usr/local/lib/libmyrand.so  ... 0000074c <initRand>:   74c: 55 push %ebp   74d: 89 e5 mov %esp,%ebp   74f: 53 push %ebx   750: 83 ec 04 sub $0x4,%esp   753: e8 00 00 00 00 call 758 <initRand+0xc>   758: 5b pop %ebx   759: 81 c3 f8 11 00 00 add $0x11f8,%ebx   75f: 83 ec 0c sub $0xc,%esp   762: 6a 00 push $0x0   764: e8 c7 fe ff ff call 630 <_init+0x28>   769: 83 c4 10 add $0x10,%esp   76c: 89 45 f8 mov %eax,0xfffffff8(%ebp)   76f: 83 ec 0c sub $0xc,%esp   772: ff 75 f8 pushl 0xfffffff8(%ebp)   775: e8 d6 fe ff ff call 650 <_init+0x48>   77a: 83 c4 10 add $0x10,%esp   77d: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   780: c9 leave   781: c3 ret   782: 90 nop   783: 90 nop ... $ 
xc,%esp 762: 6a 00 push
 $  objdump -disassemble -S /usr/local/lib/libmyrand.so  ... 0000074c <initRand>:   74c: 55 push %ebp   74d: 89 e5 mov %esp,%ebp   74f: 53 push %ebx   750: 83 ec 04 sub $0x4,%esp   753: e8 00 00 00 00 call 758 <initRand+0xc>   758: 5b pop %ebx   759: 81 c3 f8 11 00 00 add $0x11f8,%ebx   75f: 83 ec 0c sub $0xc,%esp   762: 6a 00 push $0x0   764: e8 c7 fe ff ff call 630 <_init+0x28>   769: 83 c4 10 add $0x10,%esp   76c: 89 45 f8 mov %eax,0xfffffff8(%ebp)   76f: 83 ec 0c sub $0xc,%esp   772: ff 75 f8 pushl 0xfffffff8(%ebp)   775: e8 d6 fe ff ff call 650 <_init+0x48>   77a: 83 c4 10 add $0x10,%esp   77d: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   780: c9 leave   781: c3 ret   782: 90 nop   783: 90 nop ... $ 
x0 764: e8 c7 fe ff ff call 630 <_init+0x28> 769: 83 c4 10 add
 $  objdump -disassemble -S /usr/local/lib/libmyrand.so  ... 0000074c <initRand>:   74c: 55 push %ebp   74d: 89 e5 mov %esp,%ebp   74f: 53 push %ebx   750: 83 ec 04 sub $0x4,%esp   753: e8 00 00 00 00 call 758 <initRand+0xc>   758: 5b pop %ebx   759: 81 c3 f8 11 00 00 add $0x11f8,%ebx   75f: 83 ec 0c sub $0xc,%esp   762: 6a 00 push $0x0   764: e8 c7 fe ff ff call 630 <_init+0x28>   769: 83 c4 10 add $0x10,%esp   76c: 89 45 f8 mov %eax,0xfffffff8(%ebp)   76f: 83 ec 0c sub $0xc,%esp   772: ff 75 f8 pushl 0xfffffff8(%ebp)   775: e8 d6 fe ff ff call 650 <_init+0x48>   77a: 83 c4 10 add $0x10,%esp   77d: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   780: c9 leave   781: c3 ret   782: 90 nop   783: 90 nop ... $ 
x10,%esp 76c: 89 45 f8 mov %eax,0xfffffff8(%ebp) 76f: 83 ec 0c sub
 $  objdump -disassemble -S /usr/local/lib/libmyrand.so  ... 0000074c <initRand>:   74c: 55 push %ebp   74d: 89 e5 mov %esp,%ebp   74f: 53 push %ebx   750: 83 ec 04 sub $0x4,%esp   753: e8 00 00 00 00 call 758 <initRand+0xc>   758: 5b pop %ebx   759: 81 c3 f8 11 00 00 add $0x11f8,%ebx   75f: 83 ec 0c sub $0xc,%esp   762: 6a 00 push $0x0   764: e8 c7 fe ff ff call 630 <_init+0x28>   769: 83 c4 10 add $0x10,%esp   76c: 89 45 f8 mov %eax,0xfffffff8(%ebp)   76f: 83 ec 0c sub $0xc,%esp   772: ff 75 f8 pushl 0xfffffff8(%ebp)   775: e8 d6 fe ff ff call 650 <_init+0x48>   77a: 83 c4 10 add $0x10,%esp   77d: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   780: c9 leave   781: c3 ret   782: 90 nop   783: 90 nop ... $ 
xc,%esp 772: ff 75 f8 pushl 0xfffffff8(%ebp) 775: e8 d6 fe ff ff call 650 <_init+0x48> 77a: 83 c4 10 add
 $  objdump -disassemble -S /usr/local/lib/libmyrand.so  ... 0000074c <initRand>:   74c: 55 push %ebp   74d: 89 e5 mov %esp,%ebp   74f: 53 push %ebx   750: 83 ec 04 sub $0x4,%esp   753: e8 00 00 00 00 call 758 <initRand+0xc>   758: 5b pop %ebx   759: 81 c3 f8 11 00 00 add $0x11f8,%ebx   75f: 83 ec 0c sub $0xc,%esp   762: 6a 00 push $0x0   764: e8 c7 fe ff ff call 630 <_init+0x28>   769: 83 c4 10 add $0x10,%esp   76c: 89 45 f8 mov %eax,0xfffffff8(%ebp)   76f: 83 ec 0c sub $0xc,%esp   772: ff 75 f8 pushl 0xfffffff8(%ebp)   775: e8 d6 fe ff ff call 650 <_init+0x48>   77a: 83 c4 10 add $0x10,%esp   77d: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   780: c9 leave   781: c3 ret   782: 90 nop   783: 90 nop ... $ 
x10,%esp 77d: 8b 5d fc mov 0xfffffffc(%ebp),%ebx 780: c9 leave 781: c3 ret 782: 90 nop 783: 90 nop ... $

In addition to -disassemble (to disassemble to the native instruction set), we also specified -S to output interspersed source code. The problem is that we compiled our object to exclude this information. We can easily fix this as follows , by adding -g to the compilation process.

 $  gcc -c -g -fPIC initapi.c  $  gcc -c -g -fPIC randapi.c  $  gcc   -shared initapi.o randapi.o -o libmyrand.so  $  objdump -disassemble -S libmyrand.so  ... 00000790 <initRand>:   *   */ void initRand() {   790:   55                      push   %ebp   791:   89 e5                   mov    %esp,%ebp   793:   53                      push   %ebx   794:   83 ec 04                sub 
 $  gcc -c -g -fPIC initapi.c  $  gcc -c -g -fPIC randapi.c  $  gcc   -shared initapi.o randapi.o -o libmyrand.so  $  objdump -disassemble -S libmyrand.so  ... 00000790 <initRand>:   *   */ void initRand() {   790: 55 push %ebp   791: 89 e5 mov %esp,%ebp   793: 53 push %ebx   794: 83 ec 04 sub $0x4,%esp   797: e8 00 00 00 00 call 79c <initRand+0xc>   79c: 5b pop %ebx   79d: 81 c3 fc 11 00 00 add $0x11fc,%ebx   time_t seed;   seed = time(NULL);   7a3: 83 ec 0c sub $0xc,%esp   7a6: 6a 00 push $0x0   7a8: e8 c7 fe ff ff call 674 <_init+0x28>   7ad: 83 c4 10 add $0x10,%esp   7b0: 89 45 f8 mov %eax,0xfffffff8(%ebp)   srand ( seed );   7b3: 83 ec 0c sub $0xc,%esp   7b6: ff 75 f8 pushl 0xfffffff8(%ebp)   7b9: e8 d6 fe ff ff call 694 <_init+0x48>   7be: 83 c4 10 add $0x10,%esp   return; }   7c1: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   7c4: c9 leave   7c5: c3 ret   7c6: 90 nop   7c7: 90 nop ... $ 
x4,%esp 797: e8 00 00 00 00 call 79c <initRand+0xc> 79c: 5b pop %ebx 79d: 81 c3 fc 11 00 00 add
 $  gcc -c -g -fPIC initapi.c  $  gcc -c -g -fPIC randapi.c  $  gcc   -shared initapi.o randapi.o -o libmyrand.so  $  objdump -disassemble -S libmyrand.so  ... 00000790 <initRand>:   *   */ void initRand() {   790: 55 push %ebp   791: 89 e5 mov %esp,%ebp   793: 53 push %ebx   794: 83 ec 04 sub $0x4,%esp   797: e8 00 00 00 00 call 79c <initRand+0xc>   79c: 5b pop %ebx   79d: 81 c3 fc 11 00 00 add $0x11fc,%ebx   time_t seed;   seed = time(NULL);   7a3: 83 ec 0c sub $0xc,%esp   7a6: 6a 00 push $0x0   7a8: e8 c7 fe ff ff call 674 <_init+0x28>   7ad: 83 c4 10 add $0x10,%esp   7b0: 89 45 f8 mov %eax,0xfffffff8(%ebp)   srand ( seed );   7b3: 83 ec 0c sub $0xc,%esp   7b6: ff 75 f8 pushl 0xfffffff8(%ebp)   7b9: e8 d6 fe ff ff call 694 <_init+0x48>   7be: 83 c4 10 add $0x10,%esp   return; }   7c1: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   7c4: c9 leave   7c5: c3 ret   7c6: 90 nop   7c7: 90 nop ... $ 
x11fc,%ebx time_t seed; seed = time(NULL); 7a3: 83 ec 0c sub
 $  gcc -c -g -fPIC initapi.c  $  gcc -c -g -fPIC randapi.c  $  gcc   -shared initapi.o randapi.o -o libmyrand.so  $  objdump -disassemble -S libmyrand.so  ... 00000790 <initRand>:   *   */ void initRand() {   790: 55 push %ebp   791: 89 e5 mov %esp,%ebp   793: 53 push %ebx   794: 83 ec 04 sub $0x4,%esp   797: e8 00 00 00 00 call 79c <initRand+0xc>   79c: 5b pop %ebx   79d: 81 c3 fc 11 00 00 add $0x11fc,%ebx   time_t seed;   seed = time(NULL);   7a3: 83 ec 0c sub $0xc,%esp   7a6: 6a 00 push $0x0   7a8: e8 c7 fe ff ff call 674 <_init+0x28>   7ad: 83 c4 10 add $0x10,%esp   7b0: 89 45 f8 mov %eax,0xfffffff8(%ebp)   srand ( seed );   7b3: 83 ec 0c sub $0xc,%esp   7b6: ff 75 f8 pushl 0xfffffff8(%ebp)   7b9: e8 d6 fe ff ff call 694 <_init+0x48>   7be: 83 c4 10 add $0x10,%esp   return; }   7c1: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   7c4: c9 leave   7c5: c3 ret   7c6: 90 nop   7c7: 90 nop ... $ 
xc,%esp 7a6: 6a 00 push
 $  gcc -c -g -fPIC initapi.c  $  gcc -c -g -fPIC randapi.c  $  gcc   -shared initapi.o randapi.o -o libmyrand.so  $  objdump -disassemble -S libmyrand.so  ... 00000790 <initRand>:   *   */ void initRand() {   790: 55 push %ebp   791: 89 e5 mov %esp,%ebp   793: 53 push %ebx   794: 83 ec 04 sub $0x4,%esp   797: e8 00 00 00 00 call 79c <initRand+0xc>   79c: 5b pop %ebx   79d: 81 c3 fc 11 00 00 add $0x11fc,%ebx   time_t seed;   seed = time(NULL);   7a3: 83 ec 0c sub $0xc,%esp   7a6: 6a 00 push $0x0   7a8: e8 c7 fe ff ff call 674 <_init+0x28>   7ad: 83 c4 10 add $0x10,%esp   7b0: 89 45 f8 mov %eax,0xfffffff8(%ebp)   srand ( seed );   7b3: 83 ec 0c sub $0xc,%esp   7b6: ff 75 f8 pushl 0xfffffff8(%ebp)   7b9: e8 d6 fe ff ff call 694 <_init+0x48>   7be: 83 c4 10 add $0x10,%esp   return; }   7c1: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   7c4: c9 leave   7c5: c3 ret   7c6: 90 nop   7c7: 90 nop ... $ 
x0 7a8: e8 c7 fe ff ff call 674 <_init+0x28> 7ad: 83 c4 10 add
 $  gcc -c -g -fPIC initapi.c  $  gcc -c -g -fPIC randapi.c  $  gcc   -shared initapi.o randapi.o -o libmyrand.so  $  objdump -disassemble -S libmyrand.so  ... 00000790 <initRand>:   *   */ void initRand() {   790: 55 push %ebp   791: 89 e5 mov %esp,%ebp   793: 53 push %ebx   794: 83 ec 04 sub $0x4,%esp   797: e8 00 00 00 00 call 79c <initRand+0xc>   79c: 5b pop %ebx   79d: 81 c3 fc 11 00 00 add $0x11fc,%ebx   time_t seed;   seed = time(NULL);   7a3: 83 ec 0c sub $0xc,%esp   7a6: 6a 00 push $0x0   7a8: e8 c7 fe ff ff call 674 <_init+0x28>   7ad: 83 c4 10 add $0x10,%esp   7b0: 89 45 f8 mov %eax,0xfffffff8(%ebp)   srand ( seed );   7b3: 83 ec 0c sub $0xc,%esp   7b6: ff 75 f8 pushl 0xfffffff8(%ebp)   7b9: e8 d6 fe ff ff call 694 <_init+0x48>   7be: 83 c4 10 add $0x10,%esp   return; }   7c1: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   7c4: c9 leave   7c5: c3 ret   7c6: 90 nop   7c7: 90 nop ... $ 
x10,%esp 7b0: 89 45 f8 mov %eax,0xfffffff8(%ebp) srand( seed ); 7b3: 83 ec 0c sub
 $  gcc -c -g -fPIC initapi.c  $  gcc -c -g -fPIC randapi.c  $  gcc   -shared initapi.o randapi.o -o libmyrand.so  $  objdump -disassemble -S libmyrand.so  ... 00000790 <initRand>:   *   */ void initRand() {   790: 55 push %ebp   791: 89 e5 mov %esp,%ebp   793: 53 push %ebx   794: 83 ec 04 sub $0x4,%esp   797: e8 00 00 00 00 call 79c <initRand+0xc>   79c: 5b pop %ebx   79d: 81 c3 fc 11 00 00 add $0x11fc,%ebx   time_t seed;   seed = time(NULL);   7a3: 83 ec 0c sub $0xc,%esp   7a6: 6a 00 push $0x0   7a8: e8 c7 fe ff ff call 674 <_init+0x28>   7ad: 83 c4 10 add $0x10,%esp   7b0: 89 45 f8 mov %eax,0xfffffff8(%ebp)   srand ( seed );   7b3: 83 ec 0c sub $0xc,%esp   7b6: ff 75 f8 pushl 0xfffffff8(%ebp)   7b9: e8 d6 fe ff ff call 694 <_init+0x48>   7be: 83 c4 10 add $0x10,%esp   return; }   7c1: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   7c4: c9 leave   7c5: c3 ret   7c6: 90 nop   7c7: 90 nop ... $ 
xc,%esp 7b6: ff 75 f8 pushl 0xfffffff8(%ebp) 7b9: e8 d6 fe ff ff call 694 <_init+0x48> 7be: 83 c4 10 add
 $  gcc -c -g -fPIC initapi.c  $  gcc -c -g -fPIC randapi.c  $  gcc   -shared initapi.o randapi.o -o libmyrand.so  $  objdump -disassemble -S libmyrand.so  ... 00000790 <initRand>:   *   */ void initRand() {   790: 55 push %ebp   791: 89 e5 mov %esp,%ebp   793: 53 push %ebx   794: 83 ec 04 sub $0x4,%esp   797: e8 00 00 00 00 call 79c <initRand+0xc>   79c: 5b pop %ebx   79d: 81 c3 fc 11 00 00 add $0x11fc,%ebx   time_t seed;   seed = time(NULL);   7a3: 83 ec 0c sub $0xc,%esp   7a6: 6a 00 push $0x0   7a8: e8 c7 fe ff ff call 674 <_init+0x28>   7ad: 83 c4 10 add $0x10,%esp   7b0: 89 45 f8 mov %eax,0xfffffff8(%ebp)   srand ( seed );   7b3: 83 ec 0c sub $0xc,%esp   7b6: ff 75 f8 pushl 0xfffffff8(%ebp)   7b9: e8 d6 fe ff ff call 694 <_init+0x48>   7be: 83 c4 10 add $0x10,%esp   return; }   7c1: 8b 5d fc mov 0xfffffffc(%ebp),%ebx   7c4: c9 leave   7c5: c3 ret   7c6: 90 nop   7c7: 90 nop ... $ 
x10,%esp return; } 7c1: 8b 5d fc mov 0xfffffffc(%ebp),%ebx 7c4: c9 leave 7c5: c3 ret 7c6: 90 nop 7c7: 90 nop ... $

Having compiled our source code with -g , we now have the ability to understand the C source to machine code mapping.

Numerous other capabilities are provided with objdump . The GNU/Linux mainpage lists the plethora of other options.

ranlib

The ranlib utility is one of the most important utilities when creating static libraries. This utility creates an index of the contents of the library and stores it in the library file itself. When this index is present in the library, the linking stage of building an image can be sped up considerably. Therefore, the ranlib utility should be performed whenever a new static library is created. An example of using ranlib is shown here:

 $  ranlib libmyrand.a  $ 

Note that the same thing can be performed using the ar command with the -s option, as:

 $  ar -s libmyrand.a  $ 



GNU/Linux Application Programming
GNU/Linux Application Programming (Programming Series)
ISBN: 1584505680
EAN: 2147483647
Year: 2006
Pages: 203
Authors: M. Tim Jones

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net