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; }"
Related
My application calls some functions which are placed in an external static library. I link the external static library to my application and everything works (in this case I'm using GCC).
Nevertheless, the locations (addresses) of text, .data and .bss sections of the library are chosen by the linker. I can choose/change their locations by modifying the linker script, but it's tedious as I have to specify all the functions, variables, etc. of the library. What I mean it's something like:
. = 0x1000; /* new location */
KEEP(*(.text.library_function1));
KEEP(*(.text.library_function2));
[...]
An alternative solution is to build the external library by placing a section attribute for each function/variable, and then modifying the linker by re-locating the whole section. Something like:
/* C source file */
unsigned char __attribute__((section (".myLibrarySection"))) variable1[10];
unsigned char __attribute__((section (".myLibrarySection"))) variable2[10];
/* Linker script */
. = 0x1000;
KEEP(*(.myLibrarySection))
However, I'd like to be able to relocate entire .text, .data and .bss segments of an external static library without the need of using these tricks.
I'd like something like this (in linker script):
. = 0x1000;
KEEP(*(.text.library_file_name))
Is it possible using GCC toolchain?
Is it possible using other toolchains (IAR, Keil, etc.)?
You can use the archive:filename syntax in ld.
First place all the .o files from your external library into a static library .a file, if they aren't already. That is the normal way static library binaries are distributed.
Then in the linker script, specify:
.text.special : {
. = 0x1000;
*libspecial.a:*(.text .text.*)
}
.text {
*(.text .text.*)
}
The wildcard will pick all the files coming from libspecial.a and place them in the first section. The later wildcard will then pick anything left over. If there is a need to place the .text.special section after the normal section, you can use EXCLUDE_FILE directive in a similar way.
Can you just postprocess your lib to rename sections?
# Untested!
TMP=`mktemp -d`
trap "rm -rf $TMP" EXIT
cd $TMP
ar x path/to/your/lib.a
for o in *.o; do
for s in text data bss; do
objcopy --rename-section .$s=.mynew$s $o
done
done
ar rcs path/to/your/lib.a *.o
My application calls some functions which are placed in an external static library. I link the external static library to my application and everything works (in this case I'm using GCC).
Nevertheless, the locations (addresses) of text, .data and .bss sections of the library are chosen by the linker. I can choose/change their locations by modifying the linker script, but it's tedious as I have to specify all the functions, variables, etc. of the library. What I mean it's something like:
. = 0x1000; /* new location */
KEEP(*(.text.library_function1));
KEEP(*(.text.library_function2));
[...]
An alternative solution is to build the external library by placing a section attribute for each function/variable, and then modifying the linker by re-locating the whole section. Something like:
/* C source file */
unsigned char __attribute__((section (".myLibrarySection"))) variable1[10];
unsigned char __attribute__((section (".myLibrarySection"))) variable2[10];
/* Linker script */
. = 0x1000;
KEEP(*(.myLibrarySection))
However, I'd like to be able to relocate entire .text, .data and .bss segments of an external static library without the need of using these tricks.
I'd like something like this (in linker script):
. = 0x1000;
KEEP(*(.text.library_file_name))
Is it possible using GCC toolchain?
Is it possible using other toolchains (IAR, Keil, etc.)?
You can use the archive:filename syntax in ld.
First place all the .o files from your external library into a static library .a file, if they aren't already. That is the normal way static library binaries are distributed.
Then in the linker script, specify:
.text.special : {
. = 0x1000;
*libspecial.a:*(.text .text.*)
}
.text {
*(.text .text.*)
}
The wildcard will pick all the files coming from libspecial.a and place them in the first section. The later wildcard will then pick anything left over. If there is a need to place the .text.special section after the normal section, you can use EXCLUDE_FILE directive in a similar way.
Can you just postprocess your lib to rename sections?
# Untested!
TMP=`mktemp -d`
trap "rm -rf $TMP" EXIT
cd $TMP
ar x path/to/your/lib.a
for o in *.o; do
for s in text data bss; do
objcopy --rename-section .$s=.mynew$s $o
done
done
ar rcs path/to/your/lib.a *.o
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
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.
I compiled a Hello World C file and need just one section (only the hello world function) of it.
The compiled file has the format elf32-i386 and contains 4 sections: .rodata, .text.hello, .comment, .eh_frame.
I tried to use objcopy to extract only the .text.hello section: http://www.thegeekstuff.com/2013/01/objcopy-examples/ example 3.
It fails, reporting:
BFD: hello_new: symbol `.rodata' required but not present
objcopy:hello_new: No symbols
How to solve it?
First, you mentioned you need only the the .text section - for the purpose of runtime execution? That is not right: if that hello functions has strings hardcoded inside, all these strings will be located inside .rodata section, so are u going to ignore this section?
.eh_frame is for debugger, and .comment i think is not needed, but .data is also needed.
Another thing is the relocation table - if the fucntion is to be dynamically loaded into some arbitrary memory region, then lots of area INSIDE the function may need to be patched.....check objdump -r of your ELF to find out if there is any relocation entries. if not, u are safe.
Also, anything inside your function declared as "const" will also go into the .rodata section - global data of course. Variables or constants local to the function are on the stack. And all global data are located inside .data section.
But coming back to the original error, the reason is because the example 3 in the original URL does not have cross-referencing (the .interp section) and therefore objdump -s will not have error. Your case, .text does have cross-referencing to .rodata section, but is not available after you have extracted just the .text section out.