Closed kamalesh-babulal closed 1 year ago
Such local objects are simplified by the assembler in .toc
reloc to .data + offset
. The idea being that this potentially reduces the number of unnecessary local symbols.
One idea is to modify the .toc
reloc, from .data+off
preferably to an absolute kernel symbol plus the appropriate offset, or omit the symbol and just use the absolute address as the addend. The difficulty
is in figuring out how to map patched .o file .data
to a kernel address. One way to find where the original .o file .data
is placed would be to generate a linker map file when linking the kernel and use the linker map to find the absolute address of .data + 0
.
So __crcu_array[]
is a local variable. That's why GCC doesn't make a symbol for it. It doesn't make sense to make symbols for local variables, unless they're static.
But local variables are supposed to be allocated on the stack. So why does GCC put it in .data
? Is this a weird ppc64le ABI thing? Or is it a weird GCC optimization? Either way it's weird :-)
Anyway, because this array is a local variable, I don't think it makes sense to try to find it in the kernel after all.
Instead, the array belongs to the patched function in the patch module. So leaving it alone, as a normal relocation, sounds like the right thing to do.
Of course the problem with that is, then we need to include the .data
section, but we don't support that because .data
is normally used for global data, and we don't support global data changes.
So it would be good to understand why GCC is putting local "stack" data in .data
, and if there's anything we can do to change that. Maybe by setting some gcc flag to disable the "feature"? Or maybe by using the gcc plugin to put the array in another section? I don't know...
But local variables are supposed to be allocated on the stack. So why does GCC put it in .data? Is this a weird ppc64le ABI thing? Or is it a weird GCC optimization? Either way it's weird :-)
Thanks for looking at the issue. It's GCC optimization, the idea being that this potentially reduces the number of unnecessary local symbols.
So it would be good to understand why GCC is putting local "stack" data in .data, and if there's anything we can do to change that. Maybe by setting some gcc flag to disable the "feature"?
I doubt there is a GCC flag to disable this optimization. I will try to dig more on hints.
But local variables are supposed to be allocated on the stack. So why does GCC put it in .data? Is this a weird ppc64le ABI thing? Or is it a weird GCC optimization? Either way it's weird :-)
Thanks for looking at the issue. It's GCC optimization, the idea being that this potentially reduces the number of unnecessary local symbols.
But stack variables don't have ELF symbols anyway. So that doesn't explain why the array was put in .data instead of the stack.
But stack variables don't have ELF symbols anyway. So that doesn't explain why the array was put in .data instead of the stack.
One assumption is when, compiler runs into code like:
void (*fp)(void) = foo;
To cope with a function pointer in .data
or possibly other sections. The compiler might do the brace initialization, gcc is effectively introducing a temporary variable like the above user code, ie. as if the first part of the _wait_rcu_gp macro
expansion was
static call_rcu_func_t temp_arr[] = {call_rcu, call_rcu_sched};
call_rcu_func_t __crcu_array[] = temp_arr;
As per toolchains developers, It isn't unreasonable for a compiler to do this. There is no way to force gcc to not to do such initialization.
This issue has been open for 30 days with no activity and no assignee. It will be closed in 7 days unless a comment is added.
This issue was closed because it was inactive for 7 days after being marked stale.
Consider
core.c
, where functionsched_cpu_deactivate()
calls another functionsynchronize_rcu_mult()
, which expects two function pointers as its arguments.Code snippet for the above array of function pointer is:
Attempt to replace sym reference
.data + 0
in.toc + 460
section fails inkpatch_replace_sections_syms()
as theSTT_OBJECT
or array name__crcu_array
is not generated. The question is how to resolve.toc section + 0x458
to the original array in core.c, whenSTT_OBJECT
for__crcu_array
is not generated.