As you may know gcc always placing string literals in section .rodata. Let's assume what we want to change
this outrageous behavior - for example for shellcode literals used in function init_module (contained in section .init.text)
We can start with dumping of gcc RTL - for something like printf("some string") RTL will be symbol_ref <var_decl addr *.LC1> and in .S file this looks like
.section .rodata
.LC1:
.string "some string"
That unnamed VAR_DECL has attribute DECL_IN_CONSTANT_POOL. Probably it is possible to make gcc plugin to collect such literals referring from functions inside specific section and instead of DECL_IN_CONSTANT_POOL patch them section attribute. However this requires too many labour so lets try something more lazy
Possible solutions is to explicitly set section via gcc __attribute__:
#define RSection __attribute__ ((__section__ (".init.text")))
#define _RN(name) static const char rn_##name##__[] RSection =
#define _GN(name) rn_##name##__
...
_RN(dummy_str) "some string";
printf("%s\n", _GN(dummy_str));
Looks very ugly, especially because gcc cannot expand macro like "##name##" in double quotes. And even worse - this raises compilation error:
error: ‘rn_dummy_str__’ causes a section type conflict with ‘init_module’
11 | #define _RN(name) static const char rn_##name##__[] __attribute__ ((section (".init.text"))) =
How we can fix this problem? My first thought was to write quick and dirty Perl script to scan sources for _RN markers and produce .S file where all strings were placed in right section. But then I decided to overcome my laziness and made patch for gcc - it just checks if passed declaration is initialized with STRING_CST value. Surprisingly, it works!
However, returning to the original task - all of this was in vain bcs linux kernel (unlike Windows) cannot discard .init.text sections after driver loading. I wrote simple Perl script to gather some stat about sections of loaded modules and it gave me
perl ms.pl | grep init.text
116 .init.text
opensource is disgusting as usually