ARM: relocation out of range (when loading a module)
Russell King - ARM Linux
linux at arm.linux.org.uk
Thu Feb 10 10:43:22 EST 2011
On Thu, Jan 27, 2011 at 12:43:54AM -0500, Nicolas Pitre wrote:
> The MMU-less kernel should still favor allocations close to the kernel
> text for modules, and anything else away from the kernel going
> downwards.
>
> Otherwise a veneer should be created by the module symbol resolver such
> that if the branch distance to reach, say, printk is too large, then the
> following code would have to be dynamically generated right next to the
> module:
>
> ldr pc, [pc, #-4]
> .word <far_away_symbol>
>
> Then, in your module, you patch the branch relocation for printk so that
> it branches to the code above instead, and then store the address of
> printk at the location represented by the .word directive.
What you're suggesting is what we used to do with the old user-space
module tools, which would've been nice to carry forwards to the new
module code. I never found a way to do it.
The problems:
1. Where do you create those veneers?
2. How many veneers do you allocate space for?
3. How do you determine that you need a veneer?
While you can say "next to the module" for (1), you can only do that at
the point in time when the space for the module is allocated, and you
need to know at that point how much space you require.
For (2), you could always allocate space for one veneer per symbol present
in the module, but that's very wasteful.
(3) is almost impossible to know ahead of time as you don't have the
relocations, realistically you have to allocate one veneer per symbol,
and as you don't know whether it's a data or code symbol, you'll have
to allocate one veneer for every symbol in a module.
I really don't like it, and I don't see that this is sanely solvable
without giving architectures much more control over module loading,
which I don't think will ever happen. It's probably simpler to build
modules with whatever that magic option is to tell GCC to always generate
'far call' veneers for everything rather than trying to 'fix' the kernel
module loader.
More information about the linux-arm-kernel
mailing list