Width of symbols created by gcc's objectcopy - c

I am using objcopy to remove some necessary scripting to embed a resource file (zip file) in flash memory (ARM embedded thingy).
I am using objcopy like this:
arm-none-eabi-objcopy.exe -I binary -O elf32-littlearm -B arm --rename-section .data=.rodata input.zip input.zip.o
arm-none-eabi-nm.exe -S -t d input.zip.o
00006301 R _binary_input_zip_end
00006301 A _binary_input_zip_size
00000000 R _binary_input_zip_start
What I need to know is what is the width of the _end and _size symbols. I can only guess that the _start is an address which can be accessed like a byte array: extern uint8_t _binary_input_zip_start[];. And I am assuming that the _end and _size are of 'native' int-size, and I suppose I can safely assume I can interpret these as uint32_t.
However I can't be certain. I can't find anything "size" related in the docs of objcopy: https://sourceware.org/binutils/docs/binutils/objcopy.html

I'm not %100 sure if this will work, but try adding the option --sort-size to arm-none-eabi-nm. This is supposed to sort the symbols by size, by comparing them to the next symbol above. In combination with the -S option, it should print a size. Hopefully, this will help you deduce their width.
What ARM micro are you using? 32-bits is a good guess, but there are exceptions. If you happen to be using a Texas Instruments part, I can help a lot more.
I don't have an ARM project handy that I can test this on, but it's worth a shot. If that doesn't work, I'll keep digging.
Source: My knowledge, and double-checking via http://manned.org/arm-none-eabi-nm

Related

How to print message to stdout from GNU ld script?

I have quite large ld link script for embedded platform which is low on RAM and ROM. I want to know how much memory is left available after I have relocated all the code. Actually, I want to print out the value
of location counter . to stdout.
How can I do it? Is there some magic command like print(.)?
I have a post-link step in my projects that dumps the size of stuff so I can see how close I'm getting. Just add something along the lines of:
arm-none-eabi-size binary_image.axf
That will get you output like:
text data bss dec hex filename
204808 704 23188 228700 37d5c Foo.axf
On my cortex-m3 chip, this would be text+data = flash usage, data+bss = ram usage. dec/hex are useless values.
And as Olaf says, use a map file for more specific memory consumption. I have this added to my link step:
-Xlinker -Map=Foo.map
Another solution might be to add the following command to the linker:
-Xlinker --print-memory-usage
This gives me the following output:
Memory region Used Size Region Size %age Used
m_interrupts: 576 B 576 B 100.00%
m_text: 22988 B 32192 B 71.41%
m_data: 26552 B 32 KB 81.03%
Read the manual. There are no such commands - there cannot be.
Linker "scripts" are actually more like configuration/descriptor files. They are not "executed" like a script. There is also not a single . (how could be for different memory areas?).
You can, however, output a map which might exactly be what you need. Try option -M. If you have set up the memory regions in the linker script correctly, the linker will warn if some memory area overflows, which is actually what you want for automatic builds.
Update: You could grep/filter the map file if you want to insist seeing the section sizes on each build.
You can't print the value of a symbol while the script is being executed, but you can create a symbol and the look it up afterwards with nm. Like this:
value_of_dot = .;
Then
nm my_file.elf | grep value_of_dot
Edit: If you really want it printed to stdout you would have to modify the linker. E.g. for lld, add printfs in LinkerScript.cpp in LinkerScript::assignSymbol().
For your particular use-case of checking how much memory is used, it is probably better to use size, as escrafford suggested, or objdump -section-headers.

How to prohibit the use of global variables on compile time

Is there a way to prohibit the use of global variables?
I want GCC to generate an error on compile time when a global variable is defined.
We have a code that should be run per thread and want to allow only use of stack (which is thread safe)
Is there way to enforce it ?
Some GCC flag or other way to verify it ?
One approach would be to generate a linker map file (e.g. pass option -Wl,-Map,program.map to gcc), and examine the .data and .bss output sections for any contributions from the object files that you want to run without globals.
For instance, if my source file hello.c has:
static int gTable[100];
the linker map file will have something like this in it:
.bss 0x0000000000600940 0x1b0
*(.dynbss)
.dynbss 0x0000000000000000 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o
*(.bss .bss.* .gnu.linkonce.b.*)
.bss 0x0000000000600940 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o
.bss 0x0000000000600940 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o
.bss 0x0000000000600940 0x1 /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o
*fill* 0x0000000000600941 0x1f 00
.bss 0x0000000000600960 0x190 hello.o
You can see that hello.o is contributing 0x190 (400) bytes to the .bss section. I've used the approach of parsing a link map file with a Python script to generate code size and RAM usage metrics for an embedded project with reasonable success in the past; the text output format from the linker is pretty stable.
No such functionality in gcc. Some workaround would be to incorporate in the build process a static analysis tool which can detect globals. Still the compilation would not fail, but at least you would be warned in some way. I can see that PC-Lint (www.gimpel.com) has a check for
non const non volatile global variables, locating these can assist multi-threaded applications in detecting non re-entrant situations
Probably other tools may include similar functionality.
I would use ctags to extract the symbols from the source code and then search the output with a (perl or python) script for global variables.
E.g. following line would tell you whether a C soucre file hello.c contains global variables:
ctags -f- hello.c | perl -ne"#a=split(/\t/, $_); if ($a[3] eq qq(v)){ print qq(Has global variables.); exit 0; }"

Storing CRC into an AXF/ELF file

I'm currently working on a C program in the LPCXpresso (eclipse-based) tool-chain on Windows 7, an IDE with gcc targeting the an NXP Cortex M3 microprocessor. It provides a simple way to compile-link-program the microprocessor over JTAG. The result of a build is an AXF file (ELF format) that is loaded by a debug configuration.
The loaded program resides in Flash memory from 0x00000 to 0x3FFFB. I'd like to include a 4-byte CRC-32 at 0x3FFFC to validate the program at start-up. I added another section and use the gcc __attribute__ directive to access that memory location.
uint32_t crc32_build __attribute__ ((section(".text_MFlashCRC")));
To compute and store the CRC-32 value, my plan was to use SRecord with the following post-build steps:
arm-none-eabi-size "${BuildArtifactFileName}"
arm-none-eabi-objcopy -O binary "${BuildArtifactFileName}" "${BuildArtifactFileBaseName}.bin"
checksum -p ${TargetChip} -d "${BuildArtifactFileBaseName}.bin"
../util/srec_cat "${BuildArtifactFileBaseName}.bin" -binary -crop 0 0x3FFFC -fill 0xFF 0x00000 0x3FFFC -crc32-b-e 0x3FFFC -o "${BuildArtifactFileBaseName}.crc.bin" -binary
echo ""
echo "CRC32:"
../util/srec_cat "${BuildArtifactFileBaseName}.crc.bin" -binary -crop 0x3FFFC 0x40000 -o - -hex-dump
This creates a binary with a checksum (necessary for bootloader) and then computes the CRC over the used Flash memory, storing the CRC value at 0x3FFFC.
However, I don't think I can load the binary file using the debugger. There is a built in programming utility with LPCXpresso that can load the modified binary file, however, that doesn't let me debug. I believe I can then try to start a debugging session with the original AXF file using "attach-only" mode, however, this becomes cumbersome.
I've been able to use readelf to inspect the crc32_build variable in the AXF file. Is there a way to edit the variable in the AXF file? Is there an industry-standard approach to inserting a CRC as a post-build step?
There is no industry standard that I am aware of. There are various techniques to do this. I would suggest that you use the crc32_build as an extern in 'C' and define it via a linker script. For instance,
$ cat ld.script
.text : {
_start_crc_region = .;
*(.text);
_end_crc_region = .;
crc32_build = .;
LONG(CALC_CRC);
}
You pass the value CALC_CRC as zero for a first invocation and then relink with the value set. For instance,
$ ld --defsym=CALC_CRC=0 -T ld.script *.o -o phony.elf
$ objcopy -j sections phony.elf -o phony.bin # sections means checksum 'areas'
$ ld --defsym=CALC_CRC=`crc32 phony.bin` -T ld.script *.o -o target.elf
I use this technique to add digital signing to images; it should apply equally well to crc values. The linker script allows you to position the variable, which is often important for integrity checks like a CRC, but wouldn't matter for a simple checksum. A linker script also allows you to define symbols for both the start and end of the region. Without a script, you need some elf introspection.
You can of course extend the idea to include init data and other allocated sections. At some point you need to use objcopy to extract the sections and do the integrity check at build time. The sections may have various alignment constraints and you need to mimic this (in phony.bin above) on the host when doing the build time crc calculation.
As a bonus, everything is already done when you generate an srec file.
If you have trouble with --defsym, you can just pre-process the ld.script with sed, awk, perl, python, etc and substitute text with a hex value where CALC_CRC is.

Tool to analyze size of ELF sections and symbol

I need a way to analyze output file of my GCC compiler for ARM. I am compiling for bare metal and I am quite concerned with size. I can use arm-none-eabi-objdump provided by the cross-compiler but parsing the output is not something I would be eager to do if there exists a tool for this task. Do you know of such a tool existing? My search turned out no results.
One more thing, every function in my own code is in its own section.
You can use nm and size to get the size of functions and ELF sections.
To get the size of the functions (and objects with static storage duration):
$ nm --print-size --size-sort --radix=d tst.o
The second column shows the size in decimal of function and objects.
To get the size of the sections:
$ size -A -d tst.o
The second column shows the size in decimal of the sections.
The readelf utility is handy for displaying a variety of section information, including section sizes, e.g.:
arm-none-eabi-readelf -e foo.o
If you're interested in the run-time memory footprint, you can ignore the sections that do not have the 'A' (allocate) flag set.
When re-visiting this question 10 years later one must mention the little Python-based wrapper for readelf and nm that is elf-size-analyze:
puncover uses objdump and a few other gcc tools to generate html pages you can easily browse to figure out where your code and data space is going.
It's a much nicer frontend than the text output of the gcc tools.

List global variables in executable

How can I dump all the global variables and the address offsets in my executable?
This is on os x, app developed with xcode compiled with gcc.
Thank you
If Compiled to Mach-O
Either use otool or the cctools.
If Compiled to ELF
You should be able to do this with objdump and/or readelf.
I don't have a *nix system at hand here, but objdump -s -j .data should be getting you rather close enough.
An easy way to get a list of global variables and their offsets from an executable on macOS (original question) is to use the nm tool. Without any additional keys, it gives the variables and their offsets.
Example:
$ nm <some binary>
...
U __ZTVN10__cxxabiv117__class_type_infoE
U __ZTVN10__cxxabiv120__si_class_type_infoE
000000010006e248 s __ZTVN7testing17TestEventListenerE
000000010006e1c0 s __ZTVN7testing22EmptyTestEventListenerE
000000010006dfa8 s __ZTVN7testing31TestPartResultReporterInterfaceE
000000010006d860 S __ZTVN7testing32ScopedFakeTestPartResultReporterE
000000010006d8d8 S __ZTVN7testing4TestE
...
Check man nm for the explanation of the codes like U, s, S, etc.
In case you also want to look for string constants, there is another tool strings:
$ strings <some binary> -o -t x
will give you a list of string literals and their offsets.
See man strings for more details.

Resources