Skip to content

Commit da6d1a5

Browse files
authored
Merge pull request cea-sec#1153 from aguinet/hack/div
Include missing functions from llvm's compiler-rt into Jitllvm
2 parents 1cc93ac + 11397af commit da6d1a5

File tree

11 files changed

+793
-3
lines changed

11 files changed

+793
-3
lines changed

miasm/jitter/jitcore_llvm.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
from miasm.jitter import Jitllvm
1111
import platform
1212

13+
import llvmlite
14+
llvmlite.binding.load_library_permanently(Jitllvm.__file__)
15+
1316
is_win = platform.system() == "Windows"
1417

1518
class JitCore_LLVM(jitcore.JitCore):

miasm/runtime/divti3.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* ===-- divti3.c - Implement __divti3 -------------------------------------===
2+
*
3+
* The LLVM Compiler Infrastructure
4+
*
5+
* This file is dual licensed under the MIT and the University of Illinois Open
6+
* Source Licenses. See LICENSE.TXT for details.
7+
*
8+
* ===----------------------------------------------------------------------===
9+
*
10+
* This file implements __divti3 for the compiler_rt library.
11+
*
12+
* ===----------------------------------------------------------------------===
13+
*/
14+
15+
#if __x86_64
16+
17+
#include "int_lib.h"
18+
#include "export.h"
19+
20+
tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
21+
22+
/* Returns: a / b */
23+
24+
ti_int
25+
__divti3(ti_int a, ti_int b)
26+
{
27+
const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1;
28+
ti_int s_a = a >> bits_in_tword_m1; /* s_a = a < 0 ? -1 : 0 */
29+
ti_int s_b = b >> bits_in_tword_m1; /* s_b = b < 0 ? -1 : 0 */
30+
a = (a ^ s_a) - s_a; /* negate if s_a == -1 */
31+
b = (b ^ s_b) - s_b; /* negate if s_b == -1 */
32+
s_a ^= s_b; /* sign of quotient */
33+
return (__udivmodti4(a, b, (tu_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */
34+
}
35+
36+
#endif

miasm/runtime/export.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef MIASM_RT_EXPORT_H
2+
#define MIASM_RT_EXPORT_H
3+
4+
#ifdef _WIN32
5+
#define _MIASM_EXPORT __declspec(dllexport)
6+
#else
7+
#define _MIASM_EXPORT __attribute__((visibility("default")))
8+
#endif
9+
10+
#endif

miasm/runtime/int_endianness.h

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//===-- int_endianness.h - configuration header for compiler-rt -----------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file is a configuration header for compiler-rt.
10+
// This file is not part of the interface of this library.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef INT_ENDIANNESS_H
15+
#define INT_ENDIANNESS_H
16+
17+
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
18+
defined(__ORDER_LITTLE_ENDIAN__)
19+
20+
// Clang and GCC provide built-in endianness definitions.
21+
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
22+
#define _YUGA_LITTLE_ENDIAN 0
23+
#define _YUGA_BIG_ENDIAN 1
24+
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
25+
#define _YUGA_LITTLE_ENDIAN 1
26+
#define _YUGA_BIG_ENDIAN 0
27+
#endif // __BYTE_ORDER__
28+
29+
#else // Compilers other than Clang or GCC.
30+
31+
#if defined(__SVR4) && defined(__sun)
32+
#include <sys/byteorder.h>
33+
34+
#if defined(_BIG_ENDIAN)
35+
#define _YUGA_LITTLE_ENDIAN 0
36+
#define _YUGA_BIG_ENDIAN 1
37+
#elif defined(_LITTLE_ENDIAN)
38+
#define _YUGA_LITTLE_ENDIAN 1
39+
#define _YUGA_BIG_ENDIAN 0
40+
#else // !_LITTLE_ENDIAN
41+
#error "unknown endianness"
42+
#endif // !_LITTLE_ENDIAN
43+
44+
#endif // Solaris and AuroraUX.
45+
46+
// ..
47+
48+
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
49+
defined(__minix)
50+
#include <sys/endian.h>
51+
52+
#if _BYTE_ORDER == _BIG_ENDIAN
53+
#define _YUGA_LITTLE_ENDIAN 0
54+
#define _YUGA_BIG_ENDIAN 1
55+
#elif _BYTE_ORDER == _LITTLE_ENDIAN
56+
#define _YUGA_LITTLE_ENDIAN 1
57+
#define _YUGA_BIG_ENDIAN 0
58+
#endif // _BYTE_ORDER
59+
60+
#endif // *BSD
61+
62+
#if defined(__OpenBSD__)
63+
#include <machine/endian.h>
64+
65+
#if _BYTE_ORDER == _BIG_ENDIAN
66+
#define _YUGA_LITTLE_ENDIAN 0
67+
#define _YUGA_BIG_ENDIAN 1
68+
#elif _BYTE_ORDER == _LITTLE_ENDIAN
69+
#define _YUGA_LITTLE_ENDIAN 1
70+
#define _YUGA_BIG_ENDIAN 0
71+
#endif // _BYTE_ORDER
72+
73+
#endif // OpenBSD
74+
75+
// ..
76+
77+
// Mac OSX has __BIG_ENDIAN__ or __LITTLE_ENDIAN__ automatically set by the
78+
// compiler (at least with GCC)
79+
#if defined(__APPLE__) || defined(__ellcc__)
80+
81+
#ifdef __BIG_ENDIAN__
82+
#if __BIG_ENDIAN__
83+
#define _YUGA_LITTLE_ENDIAN 0
84+
#define _YUGA_BIG_ENDIAN 1
85+
#endif
86+
#endif // __BIG_ENDIAN__
87+
88+
#ifdef __LITTLE_ENDIAN__
89+
#if __LITTLE_ENDIAN__
90+
#define _YUGA_LITTLE_ENDIAN 1
91+
#define _YUGA_BIG_ENDIAN 0
92+
#endif
93+
#endif // __LITTLE_ENDIAN__
94+
95+
#endif // Mac OSX
96+
97+
// ..
98+
99+
#if defined(_WIN32)
100+
101+
#define _YUGA_LITTLE_ENDIAN 1
102+
#define _YUGA_BIG_ENDIAN 0
103+
104+
#endif // Windows
105+
106+
#endif // Clang or GCC.
107+
108+
// .
109+
110+
#if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN)
111+
#error Unable to determine endian
112+
#endif // Check we found an endianness correctly.
113+
114+
#endif // INT_ENDIANNESS_H

miasm/runtime/int_lib.h

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
//===-- int_lib.h - configuration header for compiler-rt -----------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file is a configuration header for compiler-rt.
10+
// This file is not part of the interface of this library.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef INT_LIB_H
15+
#define INT_LIB_H
16+
17+
// Assumption: Signed integral is 2's complement.
18+
// Assumption: Right shift of signed negative is arithmetic shift.
19+
// Assumption: Endianness is little or big (not mixed).
20+
21+
// ABI macro definitions
22+
23+
#if __ARM_EABI__
24+
#ifdef COMPILER_RT_ARMHF_TARGET
25+
#define COMPILER_RT_ABI
26+
#else
27+
#define COMPILER_RT_ABI __attribute__((__pcs__("aapcs")))
28+
#endif
29+
#else
30+
#define COMPILER_RT_ABI
31+
#endif
32+
33+
#define AEABI_RTABI __attribute__((__pcs__("aapcs")))
34+
35+
#if defined(_MSC_VER) && !defined(__clang__)
36+
#define ALWAYS_INLINE __forceinline
37+
#define NOINLINE __declspec(noinline)
38+
#define NORETURN __declspec(noreturn)
39+
#define UNUSED
40+
#else
41+
#define ALWAYS_INLINE __attribute__((always_inline))
42+
#define NOINLINE __attribute__((noinline))
43+
#define NORETURN __attribute__((noreturn))
44+
#define UNUSED __attribute__((unused))
45+
#endif
46+
47+
#define STR(a) #a
48+
#define XSTR(a) STR(a)
49+
#define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name
50+
51+
#if defined(__ELF__) || defined(__MINGW32__) || defined(__wasm__)
52+
#define COMPILER_RT_ALIAS(name, aliasname) \
53+
COMPILER_RT_ABI __typeof(name) aliasname __attribute__((__alias__(#name)));
54+
#elif defined(__APPLE__)
55+
#if defined(VISIBILITY_HIDDEN)
56+
#define COMPILER_RT_ALIAS_VISIBILITY(name) \
57+
__asm__(".private_extern " SYMBOL_NAME(name));
58+
#else
59+
#define COMPILER_RT_ALIAS_VISIBILITY(name)
60+
#endif
61+
#define COMPILER_RT_ALIAS(name, aliasname) \
62+
__asm__(".globl " SYMBOL_NAME(aliasname)); \
63+
COMPILER_RT_ALIAS_VISIBILITY(aliasname) \
64+
__asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \
65+
COMPILER_RT_ABI __typeof(name) aliasname;
66+
#elif defined(_WIN32)
67+
#define COMPILER_RT_ALIAS(name, aliasname)
68+
#else
69+
#error Unsupported target
70+
#endif
71+
72+
#if defined(__NetBSD__) && (defined(_KERNEL) || defined(_STANDALONE))
73+
//
74+
// Kernel and boot environment can't use normal headers,
75+
// so use the equivalent system headers.
76+
//
77+
#include <machine/limits.h>
78+
#include <sys/stdint.h>
79+
#include <sys/types.h>
80+
#else
81+
// Include the standard compiler builtin headers we use functionality from.
82+
#include <float.h>
83+
#include <limits.h>
84+
#include <stdbool.h>
85+
#include <stdint.h>
86+
#endif
87+
88+
// Include the commonly used internal type definitions.
89+
#include "int_types.h"
90+
91+
// Include internal utility function declarations.
92+
#include "int_util.h"
93+
94+
COMPILER_RT_ABI si_int __paritysi2(si_int a);
95+
COMPILER_RT_ABI si_int __paritydi2(di_int a);
96+
97+
COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b);
98+
COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b);
99+
COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d);
100+
101+
COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int *rem);
102+
COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem);
103+
#ifdef CRT_HAS_128BIT
104+
COMPILER_RT_ABI si_int __clzti2(ti_int a);
105+
COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem);
106+
#endif
107+
108+
// Definitions for builtins unavailable on MSVC
109+
#if defined(_MSC_VER) && !defined(__clang__)
110+
#include <intrin.h>
111+
112+
uint32_t __inline __builtin_ctz(uint32_t value) {
113+
unsigned long trailing_zero = 0;
114+
if (_BitScanForward(&trailing_zero, value))
115+
return trailing_zero;
116+
return 32;
117+
}
118+
119+
uint32_t __inline __builtin_clz(uint32_t value) {
120+
unsigned long leading_zero = 0;
121+
if (_BitScanReverse(&leading_zero, value))
122+
return 31 - leading_zero;
123+
return 32;
124+
}
125+
126+
#if defined(_M_ARM) || defined(_M_X64)
127+
uint32_t __inline __builtin_clzll(uint64_t value) {
128+
unsigned long leading_zero = 0;
129+
if (_BitScanReverse64(&leading_zero, value))
130+
return 63 - leading_zero;
131+
return 64;
132+
}
133+
#else
134+
uint32_t __inline __builtin_clzll(uint64_t value) {
135+
if (value == 0)
136+
return 64;
137+
uint32_t msh = (uint32_t)(value >> 32);
138+
uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF);
139+
if (msh != 0)
140+
return __builtin_clz(msh);
141+
return 32 + __builtin_clz(lsh);
142+
}
143+
#endif
144+
145+
#define __builtin_clzl __builtin_clzll
146+
#endif // defined(_MSC_VER) && !defined(__clang__)
147+
148+
#endif // INT_LIB_H

0 commit comments

Comments
 (0)