1 | //===-- Simple malloc and free for use with integration tests -------------===// |
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 | #include <stddef.h> |
10 | #include <stdint.h> |
11 | |
12 | // Integration tests rely on the following memory functions. This is because the |
13 | // compiler code generation can emit calls to them. We want to map the external |
14 | // entrypoint to the internal implementation of the function used for testing. |
15 | // This is done manually as not all targets support aliases. |
16 | |
17 | namespace LIBC_NAMESPACE { |
18 | |
19 | int bcmp(const void *lhs, const void *rhs, size_t count); |
20 | void bzero(void *ptr, size_t count); |
21 | int memcmp(const void *lhs, const void *rhs, size_t count); |
22 | void *memcpy(void *__restrict, const void *__restrict, size_t); |
23 | void *memmove(void *dst, const void *src, size_t count); |
24 | void *memset(void *ptr, int value, size_t count); |
25 | int atexit(void (*func)(void)); |
26 | |
27 | } // namespace LIBC_NAMESPACE |
28 | |
29 | extern "C" { |
30 | |
31 | int bcmp(const void *lhs, const void *rhs, size_t count) { |
32 | return LIBC_NAMESPACE::bcmp(lhs, rhs, count); |
33 | } |
34 | void bzero(void *ptr, size_t count) { LIBC_NAMESPACE::bzero(ptr, count); } |
35 | int memcmp(const void *lhs, const void *rhs, size_t count) { |
36 | return LIBC_NAMESPACE::memcmp(lhs, rhs, count); |
37 | } |
38 | void *memcpy(void *__restrict dst, const void *__restrict src, size_t count) { |
39 | return LIBC_NAMESPACE::memcpy(dst, src, count); |
40 | } |
41 | void *memmove(void *dst, const void *src, size_t count) { |
42 | return LIBC_NAMESPACE::memmove(dst, src, count); |
43 | } |
44 | void *memset(void *ptr, int value, size_t count) { |
45 | return LIBC_NAMESPACE::memset(ptr, value, count); |
46 | } |
47 | |
48 | // This is needed if the test was compiled with '-fno-use-cxa-atexit'. |
49 | int atexit(void (*func)(void)) { return LIBC_NAMESPACE::atexit(func); } |
50 | |
51 | } // extern "C" |
52 | |
53 | // Integration tests cannot use the SCUDO standalone allocator as SCUDO pulls |
54 | // various other parts of the libc. Since SCUDO development does not use |
55 | // LLVM libc build rules, it is very hard to keep track or pull all that SCUDO |
56 | // requires. Hence, as a work around for this problem, we use a simple allocator |
57 | // which just hands out continuous blocks from a statically allocated chunk of |
58 | // memory. |
59 | |
60 | static constexpr uint64_t MEMORY_SIZE = 16384; |
61 | static uint8_t memory[MEMORY_SIZE]; |
62 | static uint8_t *ptr = memory; |
63 | |
64 | extern "C" { |
65 | |
66 | void *malloc(size_t s) { |
67 | void *mem = ptr; |
68 | ptr += s; |
69 | return static_cast<uint64_t>(ptr - memory) >= MEMORY_SIZE ? nullptr : mem; |
70 | } |
71 | |
72 | void free(void *) {} |
73 | |
74 | void *realloc(void *ptr, size_t s) { |
75 | free(ptr); |
76 | return malloc(s); |
77 | } |
78 | |
79 | // Integration tests are linked with -nostdlib. BFD linker expects |
80 | // __dso_handle when -nostdlib is used. |
81 | void *__dso_handle = nullptr; |
82 | } // extern "C" |
83 | |