Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22232

Prevent gcc from optimization/removal of variables when using -Wl,--gc-sections?

$
0
0

I have an ARM project, where I would like to keep certain unused variables and their data, until the time they are used.

I have seen prevent gcc from removing an unused variable :

__attribute__((used)) did not work for me with a global variable (the documentation does imply it only works on functions) (arm-none-eabi gcc 7), but putting the symbol in a different section via __attribute__((section(".data"))) did work. This is presumably because the linker's is only able to strip symbols when they are given their own section via -fdata-sections. I do not like it, but it worked.

So, I tried this approach, but the variables were not kept - and I think this is because something in that project enables -Wl,--gc-sections during linking. Here is a minimal example showing what I've tried to do (basically the main file only refers to the header where the variables to be "kept" are declared as extern - and other than that, main program has does not use these variables; and then those same variables are defined in a separate .c file):

test.c

#include <stdio.h>#include "test_opt.h"const char greeting[] = "Hello World - am used";int main(void) {  printf("%s!\n", greeting);  return 0;}

test_opt.h

#include <stdint.h>extern const char mystring[];struct MyStruct {  uint16_t param_one;  uint8_t param_two;  unsigned char param_three[32];};typedef struct MyStruct MyStruct_t;extern const MyStruct_t mystruct;

mystruct.c

#include "test_opt.h"const char __attribute__((section(".MYSTRING"))) mystring[] = "Me, mystring, I am not being used";const MyStruct_t __attribute__((section(".MYSTRUCT"))) mystruct = {  .param_one = 65535,  .param_two = 42,  .param_three = "myStructer here",};

Test with usual MINGW64 gcc

Let's first try without -Wl,--gc-sections:

$ gcc -Wall -g  mystruct.c test_opt.c -o test_opt.exe$ strings ./test_opt.exe | grep -i 'mystring\|mystruct'Me, mystring, I am not being used*myStructer heremystringMyStructMyStruct_tmystructmystruct.cmystruct.cmystruct.cmystruct.cmystringmystruct.MYSTRING.MYSTRUCT.MYSTRING.MYSTRUCT

Clearly, variables and content are visible here.

Now let's try -Wl,--gc-sections:

$ gcc -Wall -g -Wl,--gc-sections mystruct.c test_opt.c -o test_opt.exe$ strings ./test_opt.exe | grep -i 'mystring\|mystruct'mystringMyStructMyStruct_tmystructmystruct.cmystruct.cmystruct.cmystruct.cmystringmystruct

Apparently, here we still have some symbol debugging info left - but there are no sections, nor data being reported.


Test with ARM gcc

Let's re-do same experiment with ARM gcc - first without -Wl,--gc-sections:

$ arm-none-eabi-gcc -Wall -g test_opt.c mystruct.c -o test_opt.elf -lc -lnosys$ arm-none-eabi-strings ./test_opt.elf | grep -i 'mystring\|mystruct'Me, mystring, I am not being used*myStructer heremystruct.cMyStruct_tMyStructmystructmystruct.cmystringmystruct.cmystringmystruct.MYSTRING.MYSTRUCT

Same as before, variables, content and section names are visible.

Now let's try with -Wl,--gc-sections:

$ arm-none-eabi-gcc -Wall -g -Wl,--gc-sections test_opt.c mystruct.c -o test_opt.elf -lc -lnosys$ arm-none-eabi-strings ./test_opt.elf | grep -i 'mystring\|mystruct'

Note that, unlike the previous case, here there is neither any data content left, nor any debugging info/symbol names!


So, my question is: assuming that -Wl,--gc-sections is enabled in the project, and I otherwise do not want to remove it (because I like the functionality otherwise), can I somehow specify in code for some special variables, "keep these variables even if the are unused/unreferenced", in such a way that they are kept even with -Wl,--gc-sections enabled?

Note that adding keep to attributes, say:

const char __attribute__((keep,section(".MYSTRING"))) mystring[] = "Me, mystring, I am not being used";

... and compiling with (or without) -Wl,--gc-sections typically results with compiler warning:

mystruct.c:3:1: warning: 'keep' attribute directive ignored [-Wattributes]    3 | const char __attribute__((keep,section(".MYSTRING"))) mystring[] = "Me, mystring, I am not being used";      | ^~~~~

... I guess, because the variables are already declared const if I read that arrow correctly (or maybe because a section is already assumed to be "kept")? So attribute keep is definitely not the answer here ...


Viewing all articles
Browse latest Browse all 22232

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>