xref: /llvm-project/libc/test/IntegrationTest/test.cpp (revision 5ff3ff33ff930e4ec49da7910612d8a41eb068cb)
1af1315c2SSiva Chandra Reddy //===-- Simple malloc and free for use with integration tests -------------===//
2af1315c2SSiva Chandra Reddy //
3af1315c2SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4af1315c2SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
5af1315c2SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6af1315c2SSiva Chandra Reddy //
7af1315c2SSiva Chandra Reddy //===----------------------------------------------------------------------===//
8af1315c2SSiva Chandra Reddy 
92efe3d7fSSchrodinger ZHU Yifan #include "src/__support/common.h"
10*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h"
11af1315c2SSiva Chandra Reddy #include <stddef.h>
12af1315c2SSiva Chandra Reddy #include <stdint.h>
13af1315c2SSiva Chandra Reddy 
14ffed34e0SJoseph Huber #ifdef LIBC_TARGET_ARCH_IS_AARCH64
15ffed34e0SJoseph Huber #include "src/sys/auxv/getauxval.h"
16ffed34e0SJoseph Huber #endif
17ffed34e0SJoseph Huber 
18929ad8bcSJoseph Huber // Integration tests rely on the following memory functions. This is because the
19929ad8bcSJoseph Huber // compiler code generation can emit calls to them. We want to map the external
20929ad8bcSJoseph Huber // entrypoint to the internal implementation of the function used for testing.
21929ad8bcSJoseph Huber // This is done manually as not all targets support aliases.
22929ad8bcSJoseph Huber 
23*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
24929ad8bcSJoseph Huber 
25929ad8bcSJoseph Huber int bcmp(const void *lhs, const void *rhs, size_t count);
26929ad8bcSJoseph Huber void bzero(void *ptr, size_t count);
27929ad8bcSJoseph Huber int memcmp(const void *lhs, const void *rhs, size_t count);
28929ad8bcSJoseph Huber void *memcpy(void *__restrict, const void *__restrict, size_t);
29929ad8bcSJoseph Huber void *memmove(void *dst, const void *src, size_t count);
30929ad8bcSJoseph Huber void *memset(void *ptr, int value, size_t count);
312e1c0ec6SJoseph Huber int atexit(void (*func)(void));
32929ad8bcSJoseph Huber 
33*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
34929ad8bcSJoseph Huber 
35929ad8bcSJoseph Huber extern "C" {
36929ad8bcSJoseph Huber 
37929ad8bcSJoseph Huber int bcmp(const void *lhs, const void *rhs, size_t count) {
38b6bc9d72SGuillaume Chatelet   return LIBC_NAMESPACE::bcmp(lhs, rhs, count);
39929ad8bcSJoseph Huber }
40b6bc9d72SGuillaume Chatelet void bzero(void *ptr, size_t count) { LIBC_NAMESPACE::bzero(ptr, count); }
41929ad8bcSJoseph Huber int memcmp(const void *lhs, const void *rhs, size_t count) {
42b6bc9d72SGuillaume Chatelet   return LIBC_NAMESPACE::memcmp(lhs, rhs, count);
43929ad8bcSJoseph Huber }
44929ad8bcSJoseph Huber void *memcpy(void *__restrict dst, const void *__restrict src, size_t count) {
45b6bc9d72SGuillaume Chatelet   return LIBC_NAMESPACE::memcpy(dst, src, count);
46929ad8bcSJoseph Huber }
47929ad8bcSJoseph Huber void *memmove(void *dst, const void *src, size_t count) {
48b6bc9d72SGuillaume Chatelet   return LIBC_NAMESPACE::memmove(dst, src, count);
49929ad8bcSJoseph Huber }
50929ad8bcSJoseph Huber void *memset(void *ptr, int value, size_t count) {
51b6bc9d72SGuillaume Chatelet   return LIBC_NAMESPACE::memset(ptr, value, count);
52929ad8bcSJoseph Huber }
53929ad8bcSJoseph Huber 
542e1c0ec6SJoseph Huber // This is needed if the test was compiled with '-fno-use-cxa-atexit'.
55b6bc9d72SGuillaume Chatelet int atexit(void (*func)(void)) { return LIBC_NAMESPACE::atexit(func); }
562e1c0ec6SJoseph Huber 
57929ad8bcSJoseph Huber } // extern "C"
58929ad8bcSJoseph Huber 
59af1315c2SSiva Chandra Reddy // Integration tests cannot use the SCUDO standalone allocator as SCUDO pulls
60af1315c2SSiva Chandra Reddy // various other parts of the libc. Since SCUDO development does not use
61af1315c2SSiva Chandra Reddy // LLVM libc build rules, it is very hard to keep track or pull all that SCUDO
62af1315c2SSiva Chandra Reddy // requires. Hence, as a work around for this problem, we use a simple allocator
63af1315c2SSiva Chandra Reddy // which just hands out continuous blocks from a statically allocated chunk of
64af1315c2SSiva Chandra Reddy // memory.
65af1315c2SSiva Chandra Reddy 
669417d9fcSJoseph Huber static constexpr uint64_t MEMORY_SIZE = 16384;
679417d9fcSJoseph Huber static uint8_t memory[MEMORY_SIZE];
68af1315c2SSiva Chandra Reddy static uint8_t *ptr = memory;
69af1315c2SSiva Chandra Reddy 
70af1315c2SSiva Chandra Reddy extern "C" {
71af1315c2SSiva Chandra Reddy 
72af1315c2SSiva Chandra Reddy void *malloc(size_t s) {
73af1315c2SSiva Chandra Reddy   void *mem = ptr;
74af1315c2SSiva Chandra Reddy   ptr += s;
759417d9fcSJoseph Huber   return static_cast<uint64_t>(ptr - memory) >= MEMORY_SIZE ? nullptr : mem;
76af1315c2SSiva Chandra Reddy }
77af1315c2SSiva Chandra Reddy 
78af1315c2SSiva Chandra Reddy void free(void *) {}
79af1315c2SSiva Chandra Reddy 
8043de233eSSiva Chandra Reddy void *realloc(void *ptr, size_t s) {
8143de233eSSiva Chandra Reddy   free(ptr);
8243de233eSSiva Chandra Reddy   return malloc(s);
8343de233eSSiva Chandra Reddy }
8443de233eSSiva Chandra Reddy 
855b1ad43cSSiva Chandra Reddy // Integration tests are linked with -nostdlib. BFD linker expects
865b1ad43cSSiva Chandra Reddy // __dso_handle when -nostdlib is used.
875b1ad43cSSiva Chandra Reddy void *__dso_handle = nullptr;
882efe3d7fSSchrodinger ZHU Yifan 
892efe3d7fSSchrodinger ZHU Yifan #ifdef LIBC_TARGET_ARCH_IS_AARCH64
902efe3d7fSSchrodinger ZHU Yifan // Due to historical reasons, libgcc on aarch64 may expect __getauxval to be
912efe3d7fSSchrodinger ZHU Yifan // defined. See also https://gcc.gnu.org/pipermail/gcc-cvs/2020-June/300635.html
922efe3d7fSSchrodinger ZHU Yifan unsigned long __getauxval(unsigned long id) {
932efe3d7fSSchrodinger ZHU Yifan   return LIBC_NAMESPACE::getauxval(id);
942efe3d7fSSchrodinger ZHU Yifan }
952efe3d7fSSchrodinger ZHU Yifan #endif
96af1315c2SSiva Chandra Reddy } // extern "C"
97