20 #include "pedigree/kernel/core/cppsupport.h" 21 #include "pedigree/kernel/Log.h" 22 #include "pedigree/kernel/compiler.h" 23 #include "pedigree/kernel/core/SlamAllocator.h" 24 #include "pedigree/kernel/processor/types.h" 25 #include "pedigree/kernel/utilities/utility.h" 29 #define DEBUG_ALLOCATOR_CHECK_UNDERFLOWS 33 extern "C" void *__dso_handle;
37 extern uintptr_t start_kernel_ctors;
38 extern uintptr_t end_kernel_ctors;
39 extern uintptr_t start_kernel_dtors;
40 extern uintptr_t end_kernel_dtors;
44 void initialiseConstructors()
49 uintptr_t *iterator = &start_kernel_ctors;
50 while (iterator < &end_kernel_ctors)
52 void (*fp)(void) =
reinterpret_cast<void (*)(
void)
>(*iterator);
58 void runKernelDestructors()
60 uintptr_t *iterator = &start_kernel_dtors;
61 while (iterator < &end_kernel_dtors)
63 void (*fp)(void) =
reinterpret_cast<void (*)(
void)
>(*iterator);
69 #ifndef MEMORY_TRACING 70 static bool traceAllocations =
false;
74 static bool traceAllocations =
true;
75 void startTracingAllocations()
77 traceAllocations =
true;
80 void stopTracingAllocations()
82 traceAllocations =
false;
85 void toggleTracingAllocations()
87 traceAllocations = !traceAllocations;
90 static volatile int g_TraceLock = 0;
93 void *ptr, MemoryTracing::AllocationTrace type,
size_t size)
96 if (!traceAllocations)
102 case MemoryTracing::Allocation:
103 case MemoryTracing::Free:
104 case MemoryTracing::Metadata:
112 MemoryTracing::AllocationTraceEntry entry;
113 entry.data.type = type;
114 entry.data.sz = size & 0xFFFFFFFFU;
115 entry.data.ptr =
reinterpret_cast<uintptr_t
>(ptr);
116 for (
size_t i = 0; i < MemoryTracing::num_backtrace_entries; ++i)
118 entry.data.bt[i] = 0;
121 #define BT_FRAME(M, N) \ 124 if (M && !entry.data.bt[M - 1]) \ 126 void *frame_addr = __builtin_frame_address(N); \ 127 if (!(frame_addr && va.isMapped(frame_addr))) \ 129 entry.data.bt[M] = 0; \ 133 reinterpret_cast<uintptr_t>(__builtin_return_address(N)) & \ 139 if (MemoryTracing::num_backtrace_entries >= 1)
141 if (MemoryTracing::num_backtrace_entries >= 2)
143 if (MemoryTracing::num_backtrace_entries >= 3)
145 if (MemoryTracing::num_backtrace_entries >= 4)
147 if (MemoryTracing::num_backtrace_entries >= 5)
150 __asm__ __volatile__(
"pushfq; cli" :::
"memory");
152 for (
size_t i = 0; i <
sizeof entry.buf; ++i)
154 __asm__ __volatile__(
155 "outb %%al, %%dx" ::
"Nd"(0x2E8),
"a"(entry.buf[i]));
158 __asm__ __volatile__(
"popf" :::
"memory");
174 if(!Machine::instance().isInitialised())
182 ByteSet(buf, 0, 128);
186 const MemoryTracing::AllocationTrace type = MemoryTracing::Metadata;
188 MemoryCopy(&buf[off], &type, 1);
190 MemoryCopy(&buf[off], static_cast<const char *>(str), str.length());
192 MemoryCopy(&buf[off], &p1,
sizeof(
void*));
193 off +=
sizeof(
void*);
194 MemoryCopy(&buf[off], &p2,
sizeof(
void*));
195 off +=
sizeof(
void*);
197 for(
size_t i = 0; i < off; ++i)
199 pSerial->write(buf[i]);
206 #define ATEXIT __aeabi_atexit 208 #define ATEXIT atexit 212 extern "C" EXPORTED_PUBLIC void ATEXIT(
void (*f)(
void *),
void *p,
void *d);
213 void ATEXIT(
void (*f)(
void *),
void *p,
void *d)
220 void __cxa_pure_virtual()
222 FATAL_NOLOCK(
"Pure virtual function call made");
226 #if !HAS_THREAD_SANITIZER 230 int __cxa_guard_acquire()
234 void __cxa_guard_release()
240 #if !(defined(HOSTED) && defined(HOSTED_SYSTEM_MALLOC)) 242 #define MALLOC _malloc 243 #define CALLOC _calloc 245 #define REALLOC _realloc 247 #define MALLOC malloc 248 #define CALLOC calloc 250 #define REALLOC realloc 253 extern "C" void *MALLOC(
size_t sz)
255 return reinterpret_cast<void *
>(
new uint8_t[sz]);
258 extern "C" void *CALLOC(
size_t num,
size_t sz)
260 void *result =
reinterpret_cast<void *
>(
new uint8_t[num * sz]);
261 ByteSet(result, 0, num * sz);
265 extern "C" void FREE(
void *p)
270 delete[]
reinterpret_cast<uint8_t *
>(p);
273 extern "C" void *REALLOC(
void *p,
size_t sz)
285 SlamAllocator::instance().allocSize(reinterpret_cast<uintptr_t>(p)) -
291 void *tmp = MALLOC(sz);
292 MemoryCopy(tmp, p, copySz);
298 void *
operator new(
size_t size) noexcept
301 reinterpret_cast<void *
>(SlamAllocator::instance().
allocate(size));
304 void *
operator new[](
size_t size) noexcept
307 reinterpret_cast<void *
>(SlamAllocator::instance().
allocate(size));
310 void *
operator new(
size_t size,
void *memory) noexcept
314 void *
operator new[](
size_t size,
void *memory) noexcept
318 static void delete_shared(
void *p) noexcept
322 uintptr_t
mem =
reinterpret_cast<uintptr_t
>(p);
326 if (traceAllocations || SlamAllocator::instance().isPointerValid(mem))
328 SlamAllocator::instance().free(mem);
332 if (SlamAllocator::instance().isWithinHeap(mem))
334 FATAL(
"delete_shared failed as pointer was invalid: " << p);
340 "delete_shared failed as pointer was not in the kernel heap: " 345 void operator delete(
void *p) noexcept
349 void operator delete[](
void *p) noexcept
353 void operator delete(
void *p,
size_t sz) noexcept
357 void operator delete[](
void *p,
size_t sz) noexcept
361 void operator delete(
void *p,
void *q) noexcept
365 void operator delete[](
void *p,
void *q) noexcept
373 void *__wrap_malloc(
size_t sz)
378 void *__wrap_realloc(
void *p,
size_t sz)
380 return _realloc(p, sz);
383 void __wrap_free(
void *p)
uintptr_t allocate(size_t nBytes)
virtual Serial * getSerial(size_t n)=0
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()