[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