[U-Boot] [PATCH v3] x86: Wrap small helper functions from libgcc to avoid an ABI mismatch
Graeme Russ
graeme.russ at gmail.com
Wed Nov 30 12:03:12 CET 2011
Hi Gabe,
On 17/11/11 20:01, Gabe Black wrote:
> When gcc compiles some 64 bit operations on a 32 bit machine, it generates
> calls to small functions instead of instructions which do the job directly.
> Those functions are defined in libgcc and transparently provide whatever
> functionality was necessary. Unfortunately, u-boot can be built with a
> non-standard ABI when libgcc isn't. More specifically, u-boot uses
> -mregparm. When the u-boot and libgcc are linked together, very confusing
> bugs can crop up, for instance seemingly normal integer division or modulus
> getting the wrong answer or even raising a spurious divide by zero
> exception.
>
> This change borrows (steals) a technique and some code from coreboot which
> solves this problem by creating wrappers which translate the calling
> convention when calling the functions in libgcc. Unfortunately that means
> that these instructions which had already been turned into functions have
> even more overhead, but more importantly it makes them work properly.
>
> To find all of the functions that needed wrapping, u-boot was compiled
> without linking in libgcc. All the symbols the linker complained were
> undefined were presumed to be the symbols that are needed from libgcc.
> These were a subset of the symbols covered by the coreboot code, so it was
> used unmodified.
>
> To prevent symbols which are provided by libgcc but not currently wrapped
> (or even known about) from being silently linked against by code generated
> by libgcc, a new copy of libgcc is created where all the symbols are
> prefixed with __normal_. Without being purposefully wrapped, these symbols
> will cause linker errors instead of silently introducing very subtle,
> confusing bugs.
>
> Another approach would be to whitelist symbols from libgcc and strip out
> all the others. The problem with this approach is that it requires the
> white listed symbols to be specified three times, once for objcopy, once so
> the linker inserts the wrapped, and once to generate the wrapper itself,
> while this implementation needs it to be listed only twice. There isn't
> much tangible difference in what each approach produces, so this one was
> preferred.
>
> Signed-off-by: Gabe Black <gabeblack at chromium.org>
> ---
> Changes in v2:
> - Change the [x86] tag to x86:
> - Mention -mregparm in the commit message.
> - Get rid of a stray line which snuck in during a rebase.
>
> Changes in v3:
> - Prevent symbols from libgcc which aren't wrapped from getting silently
> picked up by the linker.
>
> arch/x86/config.mk | 7 +++++++
> arch/x86/lib/Makefile | 6 ++++++
> arch/x86/lib/gcc.c | 38 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 51 insertions(+), 0 deletions(-)
> create mode 100644 arch/x86/lib/gcc.c
Applied to u-boot-x86/master
Thanks,
Graeme
More information about the U-Boot
mailing list