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 <gabebl...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot