Re: objtool query: section start/end symbols?
From: Rasmus Villemoes
Date: Fri Jun 07 2024 - 05:39:55 EST
On 06/06/2024 20.42, Linus Torvalds wrote:
> So this is related to my currently very ugly hack at
>
> https://lore.kernel.org/all/CAHk-=whFSz=usMPHHGAQBnJRVAFfuH4gFHtgyLe0YET75zYRzA@xxxxxxxxxxxxxx/
>
> where I'm trying to do "runtime constants". That patch actually works,
> but it's flawed in many ways, and one of the ways it is flawed is that
> I really want to put the "this is the use for symbol X" in a section
> of its own for each X.
>
> Now, creating the sections is trivial, that's not the problem. I'd
> just make the asm do
>
> ".pushsection .static_const." #sym ",\"a\"\n\t" \
> ...
> ".popsection"
>
> and the linker script will just do
>
> KEEP(*(.static_const.*))
>
> and I'm done. Nice individual sections for each of the runtime constant symbols.
I'm probably missing something, but isn't this exactly what you get for
free if you avoid using dots and other non-identifier symbols in the
section names, i.e. make it "__static_const__" #sym or whatnot:
https://sourceware.org/binutils/docs/ld/Input-Section-Example.html
If an output section's name is the same as the input section's name
and is representable as a C identifier, then the linker will
automatically *note PROVIDE:: two symbols: __start_SECNAME and
__stop_SECNAME, where SECNAME is the name of the section. These
indicate the start address and end address of the output section
respectively. Note: most section names are not representable as C
identifiers because they contain a '.' character.
And this tiny test program suggests that works as advertised, though I
don't know if we use some linker flag or the fact that we use our own
linker script then somehow suppresses that behaviour:
#include <stdio.h>
#define x(name, val) asm(".pushsection __test__" #name ",\"a\"\n\t" \
".long " #val "\n\t" \
".popsection\n")
extern char __start___test__foo[];
extern char __stop___test__foo[];
extern char __start___test__bar[];
extern char __stop___test__bar[];
int main(int argc, char *argv[])
{
int *p;
x(foo, 10);
x(bar, 12);
x(foo, 47);
printf("Contents of foo section:\n");
for (p = (int*)__start___test__foo; p < (int*)__stop___test__foo; ++p)
printf("%d\n", *p);
printf("Contents of bar section:\n");
for (p = (int*)__start___test__bar; p < (int*)__stop___test__bar; ++p)
printf("%d\n", *p);
return 0;
}
Rasmus