The recent gnulib updates require an implementation of abort(), but the current macro provided by changeset: cd37d3d3916c gnulib: Drop no-abort.patch to config.h.in does not work with the clang compiler since it doesn't provide a __builtin_trap() implementation, so this element of the changeset needs to be reverted, and replaced. After some discussion with Vladimir 'phcoder' Serbinenko and Daniel Kiper it was suggested to bring back in the change from the changeset: db7337a3d353 * grub-core/gnulib/regcomp.c (regerror): ... Which implements abort() as an inline call to grub_abort(), but since that was made static by changeset: a8f15bceeafe * grub-core/kern/misc.c (grub_abort): Make static it is also necessary to revert the specific part that makes it a static function too. Another implementation of abort() was found in grub-core/kern/compiler-rt.c which needs to also be removed to be consistent. Signed-off-by: Darren Kenny <darren.kenny@oracle.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
455 lines
8.4 KiB
C
455 lines
8.4 KiB
C
/* compiler-rt.c - compiler helpers. */
|
|
/*
|
|
* GRUB -- GRand Unified Bootloader
|
|
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010-2014 Free Software Foundation, Inc.
|
|
*
|
|
* GRUB is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* GRUB is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <grub/misc.h>
|
|
#include <grub/compiler-rt.h>
|
|
|
|
#ifndef GRUB_EMBED_DECOMPRESSOR
|
|
void * GRUB_BUILTIN_ATTR
|
|
memcpy (void *dest, const void *src, grub_size_t n)
|
|
{
|
|
return grub_memmove (dest, src, n);
|
|
}
|
|
void * GRUB_BUILTIN_ATTR
|
|
memmove (void *dest, const void *src, grub_size_t n)
|
|
{
|
|
return grub_memmove (dest, src, n);
|
|
}
|
|
int GRUB_BUILTIN_ATTR
|
|
memcmp (const void *s1, const void *s2, grub_size_t n)
|
|
{
|
|
return grub_memcmp (s1, s2, n);
|
|
}
|
|
void * GRUB_BUILTIN_ATTR
|
|
memset (void *s, int c, grub_size_t n)
|
|
{
|
|
return grub_memset (s, c, n);
|
|
}
|
|
|
|
#ifdef __APPLE__
|
|
|
|
void GRUB_BUILTIN_ATTR
|
|
__bzero (void *s, grub_size_t n)
|
|
{
|
|
grub_memset (s, 0, n);
|
|
}
|
|
|
|
#endif
|
|
|
|
#if GRUB_DIVISION_IN_SOFTWARE
|
|
|
|
grub_uint32_t
|
|
__udivsi3 (grub_uint32_t a, grub_uint32_t b)
|
|
{
|
|
return grub_divmod64 (a, b, 0);
|
|
}
|
|
|
|
grub_int32_t
|
|
__divsi3 (grub_int32_t a, grub_int32_t b)
|
|
{
|
|
return grub_divmod64s (a, b, 0);
|
|
}
|
|
|
|
grub_uint32_t
|
|
__umodsi3 (grub_uint32_t a, grub_uint32_t b)
|
|
{
|
|
grub_uint64_t ret;
|
|
grub_divmod64 (a, b, &ret);
|
|
return ret;
|
|
}
|
|
|
|
grub_int32_t
|
|
__modsi3 (grub_int32_t a, grub_int32_t b)
|
|
{
|
|
grub_int64_t ret;
|
|
grub_divmod64s (a, b, &ret);
|
|
return ret;
|
|
}
|
|
|
|
grub_uint64_t
|
|
__udivdi3 (grub_uint64_t a, grub_uint64_t b)
|
|
{
|
|
return grub_divmod64 (a, b, 0);
|
|
}
|
|
|
|
grub_uint64_t
|
|
__umoddi3 (grub_uint64_t a, grub_uint64_t b)
|
|
{
|
|
grub_uint64_t ret;
|
|
grub_divmod64 (a, b, &ret);
|
|
return ret;
|
|
}
|
|
|
|
grub_int64_t
|
|
__divdi3 (grub_int64_t a, grub_int64_t b)
|
|
{
|
|
return grub_divmod64s (a, b, 0);
|
|
}
|
|
|
|
grub_int64_t
|
|
__moddi3 (grub_int64_t a, grub_int64_t b)
|
|
{
|
|
grub_int64_t ret;
|
|
grub_divmod64s (a, b, &ret);
|
|
return ret;
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifdef NEED_CTZDI2
|
|
|
|
unsigned
|
|
__ctzdi2 (grub_uint64_t x)
|
|
{
|
|
unsigned ret = 0;
|
|
if (!x)
|
|
return 64;
|
|
if (!(x & 0xffffffff))
|
|
{
|
|
x >>= 32;
|
|
ret |= 32;
|
|
}
|
|
if (!(x & 0xffff))
|
|
{
|
|
x >>= 16;
|
|
ret |= 16;
|
|
}
|
|
if (!(x & 0xff))
|
|
{
|
|
x >>= 8;
|
|
ret |= 8;
|
|
}
|
|
if (!(x & 0xf))
|
|
{
|
|
x >>= 4;
|
|
ret |= 4;
|
|
}
|
|
if (!(x & 0x3))
|
|
{
|
|
x >>= 2;
|
|
ret |= 2;
|
|
}
|
|
if (!(x & 0x1))
|
|
{
|
|
x >>= 1;
|
|
ret |= 1;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
#ifdef NEED_CTZSI2
|
|
unsigned
|
|
__ctzsi2 (grub_uint32_t x)
|
|
{
|
|
unsigned ret = 0;
|
|
if (!x)
|
|
return 32;
|
|
|
|
if (!(x & 0xffff))
|
|
{
|
|
x >>= 16;
|
|
ret |= 16;
|
|
}
|
|
if (!(x & 0xff))
|
|
{
|
|
x >>= 8;
|
|
ret |= 8;
|
|
}
|
|
if (!(x & 0xf))
|
|
{
|
|
x >>= 4;
|
|
ret |= 4;
|
|
}
|
|
if (!(x & 0x3))
|
|
{
|
|
x >>= 2;
|
|
ret |= 2;
|
|
}
|
|
if (!(x & 0x1))
|
|
{
|
|
x >>= 1;
|
|
ret |= 1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif
|
|
|
|
#if (defined (__MINGW32__) || defined (__CYGWIN__))
|
|
void __register_frame_info (void)
|
|
{
|
|
}
|
|
|
|
void __deregister_frame_info (void)
|
|
{
|
|
}
|
|
|
|
void ___chkstk_ms (void)
|
|
{
|
|
}
|
|
|
|
void __chkstk_ms (void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
union component64
|
|
{
|
|
grub_uint64_t full;
|
|
struct
|
|
{
|
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
|
grub_uint32_t high;
|
|
grub_uint32_t low;
|
|
#else
|
|
grub_uint32_t low;
|
|
grub_uint32_t high;
|
|
#endif
|
|
};
|
|
};
|
|
|
|
#if defined (__powerpc__) || defined (__arm__) || defined(__mips__) || \
|
|
(defined(__riscv) && (__riscv_xlen == 32))
|
|
|
|
/* Based on libgcc2.c from gcc suite. */
|
|
grub_uint64_t
|
|
__lshrdi3 (grub_uint64_t u, int b)
|
|
{
|
|
if (b == 0)
|
|
return u;
|
|
|
|
const union component64 uu = {.full = u};
|
|
const int bm = 32 - b;
|
|
union component64 w;
|
|
|
|
if (bm <= 0)
|
|
{
|
|
w.high = 0;
|
|
w.low = (grub_uint32_t) uu.high >> -bm;
|
|
}
|
|
else
|
|
{
|
|
const grub_uint32_t carries = (grub_uint32_t) uu.high << bm;
|
|
|
|
w.high = (grub_uint32_t) uu.high >> b;
|
|
w.low = ((grub_uint32_t) uu.low >> b) | carries;
|
|
}
|
|
|
|
return w.full;
|
|
}
|
|
|
|
/* Based on libgcc2.c from gcc suite. */
|
|
grub_uint64_t
|
|
__ashrdi3 (grub_uint64_t u, int b)
|
|
{
|
|
if (b == 0)
|
|
return u;
|
|
|
|
const union component64 uu = {.full = u};
|
|
const int bm = 32 - b;
|
|
union component64 w;
|
|
|
|
if (bm <= 0)
|
|
{
|
|
/* w.high = 1..1 or 0..0 */
|
|
w.high = ((grub_int32_t) uu.high) >> (32 - 1);
|
|
w.low = ((grub_int32_t) uu.high) >> -bm;
|
|
}
|
|
else
|
|
{
|
|
const grub_uint32_t carries = ((grub_uint32_t) uu.high) << bm;
|
|
|
|
w.high = ((grub_int32_t) uu.high) >> b;
|
|
w.low = ((grub_uint32_t) uu.low >> b) | carries;
|
|
}
|
|
|
|
return w.full;
|
|
}
|
|
|
|
/* Based on libgcc2.c from gcc suite. */
|
|
grub_uint64_t
|
|
__ashldi3 (grub_uint64_t u, int b)
|
|
{
|
|
if (b == 0)
|
|
return u;
|
|
|
|
const union component64 uu = {.full = u};
|
|
const int bm = 32 - b;
|
|
union component64 w;
|
|
|
|
if (bm <= 0)
|
|
{
|
|
w.low = 0;
|
|
w.high = (grub_uint32_t) uu.low << -bm;
|
|
}
|
|
else
|
|
{
|
|
const grub_uint32_t carries = (grub_uint32_t) uu.low >> bm;
|
|
|
|
w.low = (grub_uint32_t) uu.low << b;
|
|
w.high = ((grub_uint32_t) uu.high << b) | carries;
|
|
}
|
|
|
|
return w.full;
|
|
}
|
|
|
|
/* Based on libgcc2.c from gcc suite. */
|
|
int
|
|
__ucmpdi2 (grub_uint64_t a, grub_uint64_t b)
|
|
{
|
|
union component64 ac, bc;
|
|
ac.full = a;
|
|
bc.full = b;
|
|
|
|
if (ac.high < bc.high)
|
|
return 0;
|
|
else if (ac.high > bc.high)
|
|
return 2;
|
|
|
|
if (ac.low < bc.low)
|
|
return 0;
|
|
else if (ac.low > bc.low)
|
|
return 2;
|
|
return 1;
|
|
}
|
|
|
|
#endif
|
|
|
|
#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || \
|
|
defined(__arm__) || defined(__riscv)
|
|
|
|
/* Based on libgcc2.c from gcc suite. */
|
|
grub_uint32_t
|
|
__bswapsi2 (grub_uint32_t u)
|
|
{
|
|
return ((((u) & 0xff000000) >> 24)
|
|
| (((u) & 0x00ff0000) >> 8)
|
|
| (((u) & 0x0000ff00) << 8)
|
|
| (((u) & 0x000000ff) << 24));
|
|
}
|
|
|
|
/* Based on libgcc2.c from gcc suite. */
|
|
grub_uint64_t
|
|
__bswapdi2 (grub_uint64_t u)
|
|
{
|
|
return ((((u) & 0xff00000000000000ull) >> 56)
|
|
| (((u) & 0x00ff000000000000ull) >> 40)
|
|
| (((u) & 0x0000ff0000000000ull) >> 24)
|
|
| (((u) & 0x000000ff00000000ull) >> 8)
|
|
| (((u) & 0x00000000ff000000ull) << 8)
|
|
| (((u) & 0x0000000000ff0000ull) << 24)
|
|
| (((u) & 0x000000000000ff00ull) << 40)
|
|
| (((u) & 0x00000000000000ffull) << 56));
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
#ifdef __arm__
|
|
grub_uint32_t
|
|
__aeabi_uidiv (grub_uint32_t a, grub_uint32_t b)
|
|
__attribute__ ((alias ("__udivsi3")));
|
|
grub_int32_t
|
|
__aeabi_idiv (grub_int32_t a, grub_int32_t b)
|
|
__attribute__ ((alias ("__divsi3")));
|
|
void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n)
|
|
__attribute__ ((alias ("grub_memcpy")));
|
|
void *__aeabi_memcpy4 (void *dest, const void *src, grub_size_t n)
|
|
__attribute__ ((alias ("grub_memcpy")));
|
|
void *__aeabi_memcpy8 (void *dest, const void *src, grub_size_t n)
|
|
__attribute__ ((alias ("grub_memcpy")));
|
|
void *__aeabi_memset (void *s, int c, grub_size_t n)
|
|
__attribute__ ((alias ("memset")));
|
|
|
|
void
|
|
__aeabi_memclr (void *s, grub_size_t n)
|
|
{
|
|
grub_memset (s, 0, n);
|
|
}
|
|
|
|
void __aeabi_memclr4 (void *s, grub_size_t n)
|
|
__attribute__ ((alias ("__aeabi_memclr")));
|
|
void __aeabi_memclr8 (void *s, grub_size_t n)
|
|
__attribute__ ((alias ("__aeabi_memclr")));
|
|
|
|
int
|
|
__aeabi_ulcmp (grub_uint64_t a, grub_uint64_t b)
|
|
{
|
|
return __ucmpdi2 (a, b) - 1;
|
|
}
|
|
|
|
grub_uint64_t
|
|
__aeabi_lasr (grub_uint64_t u, int b)
|
|
__attribute__ ((alias ("__ashrdi3")));
|
|
grub_uint64_t
|
|
__aeabi_llsr (grub_uint64_t u, int b)
|
|
__attribute__ ((alias ("__lshrdi3")));
|
|
|
|
grub_uint64_t
|
|
__aeabi_llsl (grub_uint64_t u, int b)
|
|
__attribute__ ((alias ("__ashldi3")));
|
|
|
|
#endif
|
|
|
|
#if defined(__mips__) || defined(__riscv) || defined(__sparc__)
|
|
/* Based on libgcc from gcc suite. */
|
|
int
|
|
__clzsi2 (grub_uint32_t val)
|
|
{
|
|
int i = 32;
|
|
int j = 16;
|
|
int temp;
|
|
|
|
for (; j; j >>= 1)
|
|
{
|
|
if ((temp = val >> j))
|
|
{
|
|
if (j == 1)
|
|
{
|
|
return (i - 2);
|
|
}
|
|
else
|
|
{
|
|
i -= j;
|
|
val = temp;
|
|
}
|
|
}
|
|
}
|
|
return (i - val);
|
|
}
|
|
#endif
|
|
|
|
#if defined(__mips__) || defined(__riscv) || defined(__sparc__)
|
|
int
|
|
__clzdi2 (grub_uint64_t val)
|
|
{
|
|
if (val >> 32)
|
|
{
|
|
return __clzsi2 (val >> 32);
|
|
}
|
|
else
|
|
{
|
|
return __clzsi2 (val) + 32;
|
|
}
|
|
}
|
|
#endif
|