Книга: Embedded Linux Primer: A Practical, Real-World Approach
13.5.1. readelf
13.5.1. readelf
The readelf utility examines the composition of your target ELF binary file. This is particularly useful for building images targeted for ROM or Flash memory where explicit control of the image layout is required. It is also a great tool for learning how your toolchain builds images and for understanding the ELF file format.
For example, to display the symbol table in an ELF image, use this command:
$ readelf -s <elf-image>
To discover and display all the sections in your ELF image, use this command:
$ readelf -e <elf-image>
Use the -S flag to list the section headers in your ELF image. You might be surprised to learn that even a simple seven-line "hello world" program contains 38 separate sections. Some of them will be familiar to you, such as the .text and .data sections. Listing 13-15 contains a partial listing of sections from our "hello world" example. For simplicity, we have listed only those sections that are likely to be familiar or relevant to the embedded developer.
Listing 13-15. readelf Section Headers
$
ppc_82xx-readelf -S hello-ex
There are 38 section headers, starting at offset 0x32f4:
Section Headers:
[ Nr] Name Type Addr Off Size ES Flg Lk Inf Al
...
[11] .text PROGBITS 100002f0 0002f0 000568 00 AX 0 0 4
...
[13] .rodata PROGBITS 10000878 000878 000068 00 A 0 0 4
...
[15] .data PROGBITS 100108e0 0008e0 00000c 00 WA 0 0 4
...
[22] .sdata PROGBITS 100109e0 0009e0 00001c 00 WA 0 0 4
[23] .sbss NOBITS 100109fc 0009fc 000000 00 WA 0 0 1
...
[25] .bss NOBITS 10010a74 0009fc 00001c 00 WA 0 0 4
...
The .text section contains the executable program code. The .rodata section contains constant data in your program. The .data section generally contains initialized global data used by the C library prologue code and can contain large initialized data items from your application. The .sdata section is used for smaller initialized global data items and exists only on some architectures. Some processor architectures can make use of optimized data access when the attributes of the memory area are known. The .sdata and .sbss sections enable these optimizations. The .bss and .sbss sections contain uninitialized data in your program. These sections occupy no space in the program imagetheir memory space is allocated and initialized to zero on program startup by C library prologue code.
We can dump any of these sections and display the contents. Given this line in your C program declared outside of any function, we can examine how it is placed in the .rodata section:
char *hello_rodata = "This is a read-only data stringn";
Issue the readelf command specifying the section number we want to dump from Listing 13-15:
$ ppc_82xx-readelf -x 13 hello-ex
Hex dump of section '.rodata':
0x10000878 100189e0 10000488 1000050c 1000058c ................
0x10000888 00020001 54686973 20697320 61207265 ....This is a read-
0x10000898 61642d6f 6e6c7920 64617461 20737472 only data string
0x100008a8 696e670a 00000000 54686973 20697320 .....This is
0x100008b8 73746174 69632064 6174610a 00000000 static data.....
0x100008c8 48656c6c 6f20456d 62656464 65640a00 Hello Embedded..
0x100008d8 25730a00 25780a00 %s..%x..
We see that the initialized global variable that we declared is represented in the .rodata section, together with all the constant strings defined in the program.