Re: [RFC PATCH 0/3] Mark literal strings in __init / __exit code
From: Rasmus Villemoes
Date: Wed Jun 25 2014 - 03:35:58 EST
Mathias Krause <minipli@xxxxxxxxxxxxxx> writes:
> On 24 June 2014 16:31, Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx> wrote:
>> gcc already seems to contain infrastructure for this kind of thing, so
>> maybe it doesn't even require a plugin, but simply a little coordination
>> with the gcc folks. This snippet from gcc internals seems relevant:
>>
>> -- Target Hook: section * TARGET_ASM_FUNCTION_RODATA_SECTION (tree
>> DECL)
>> Return the readonly data section associated with 'DECL_SECTION_NAME
>> (DECL)'. The default version of this function selects
>> '.gnu.linkonce.r.name' if the function's section is
>> '.gnu.linkonce.t.name', '.rodata.name' if function is in
>> '.text.name', and the normal readonly-data section otherwise.
>>
>
> I don't think it's that easy. You cannot simply put all strings into
> the .init.rodata section when code currently gets emitted to
> .init.text. The reason is because strings used in __init code might be
> referenced later on, too. For example, the name passed to
> class_create() won't be copied.
Right, didn't think about that, so yes, the source would need
to be annotated some way or other, or gcc would need to learn the
semantics of certain kernel functions.
Speaking of dangling pointers: A similar disaster would happen if some
code containing pi_* calls gets copy-pasted to some non-__init
function. Could checkpatch learn to warn about calling these functions
from the wrong context?
Mathias Krause <minipli@xxxxxxxxxxxxxx> writes:
> Merging strings across multiple compilation units does not happen,
> anyway -- not now, not with the new macros.
Certainly string merging seems to happen, at least at -O1 and higher:
$ grep . *.c
a.c:const char *a(void) { return "654321"; }
b.c:const char *b(void) { return "4321"; }
c.c:const char *c(void) { return "654321"; }
main.c:#include <stdio.h>
main.c:const char *a(void);
main.c:const char *b(void);
main.c:const char *c(void);
main.c:int main(void)
main.c:{
main.c: printf("%p\n", a());
main.c: printf("%p\n", b());
main.c: printf("%p\n", c());
main.c: return 0;
main.c:}
$ gcc -O1 -c a.c && gcc -O1 -c b.c && gcc -O1 -c c.c
$ gcc -O1 main.c a.o b.o c.o
$ ./a.out
0x400630
0x400632
0x400630
So not only are identical strings merged; suffixes are also optimized.
Rasmus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/