this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[xtrace] Use Linux Implementation Of "malloc", "free", and "realloc"

Instead of using a custom implementation, we will use `_elfcalls` to call the native/Linux implementation of "malloc", "free", and "realloc".

Thomas A fd903083 fd1a1d59

+45 -503
+4
src/startup/mldr/elfcalls/elfcalls.c
··· 102 102 calls->get_errno = get_errno; 103 103 calls->exit = exit; 104 104 105 + calls->malloc = malloc; 106 + calls->free = free; 107 + calls->realloc = realloc; 108 + 105 109 calls->sysconf = sysconf; 106 110 107 111 *((void**)&calls->sem_open) = sem_open;
+5
src/startup/mldr/elfcalls/elfcalls.h
··· 53 53 54 54 void (*exit)(int ec); 55 55 56 + // Memory allocation 57 + void* (*malloc)(size_t size); 58 + void (*free)(void *ptr); 59 + void* (*realloc)(void *ptr, size_t size); 60 + 56 61 // POSIX sysconf 57 62 long (*sysconf)(int name); 58 63
+1 -1
src/xtrace/CMakeLists.txt
··· 15 15 bsd_trace.cpp 16 16 mig_trace.cpp 17 17 tls.cpp 18 - malloc.cpp 18 + memory.cpp 19 19 lock.cpp 20 20 posix_spawn_args.cpp 21 21 )
-485
src/xtrace/malloc.cpp
··· 1 - #define PRIVATE 1 2 - #include <sys/cdefs.h> 3 - 4 - #include <darling/emulation/ext/for-xtrace.h> 5 - #include <stdint.h> 6 - #include <stdbool.h> 7 - #include <string.h> 8 - #include <sys/queue.h> 9 - 10 - #include "malloc.h" 11 - #include "lock.h" 12 - #include <darling/emulation/simple.h> 13 - 14 - #ifndef XTRACE_MALLOC_DEBUG 15 - #define XTRACE_MALLOC_DEBUG 0 16 - #endif 17 - 18 - #if XTRACE_MALLOC_DEBUG 19 - #define xtrace_malloc_debug(x, ...) xtrace_log(x "\n", ## __VA_ARGS__) 20 - #undef XTRACE_INLINE 21 - #define XTRACE_INLINE 22 - #else 23 - #define xtrace_malloc_debug(x, ...) 24 - #endif 25 - 26 - // we can't rely on libmalloc because: 27 - // 1. we should be invisible to everyone but libkernel 28 - // 2. libmalloc might need to `thread_switch(2)`, which will recurse back into xtrace, blowing up the stack 29 - // so let's roll our own malloc! (using Linux's mmap) 30 - 31 - // all blocks will be allocated in multiples of this size 32 - #define BLOCK_SIZE_MULTIPLE (4096ULL) 33 - 34 - #define LIST_PREV(elm, link) ({ \ 35 - __typeof(elm) elm_cache = elm; \ 36 - __typeof((elm_cache)->link)* as_link = __container_of(elm_cache->link.le_prev, __typeof((elm_cache)->link), le_next); \ 37 - elm_cache = __container_of(as_link, __typeof(*elm_cache), link); \ 38 - elm_cache; \ 39 - }) 40 - 41 - typedef LIST_HEAD(xtrace_memory_fragment_head, xtrace_memory_fragment) xtrace_memory_fragment_head_t; 42 - typedef LIST_ENTRY(xtrace_memory_fragment) xtrace_memory_fragment_entry_t; 43 - 44 - // 45 - // xtrace_memory_fragment 46 - // 47 - 48 - #define XTRACE_MEMORY_FRAGMENT_FLAG_IN_USE (1ULL << 63) 49 - #define XTRACE_MEMORY_FRAGMENT_FLAG_IS_MMAP_BASE (1ULL << 62) 50 - #define XTRACE_MEMORY_FRAGMENT_FLAG_BIT_COUNT (2) 51 - #define XTRACE_MEMORY_FRAGMENT_SIZE_MASK (0xffffffffffffffffULL >> XTRACE_MEMORY_FRAGMENT_FLAG_BIT_COUNT) 52 - 53 - typedef struct xtrace_memory_fragment* xtrace_memory_fragment_t; 54 - struct xtrace_memory_fragment { 55 - uint64_t flags; 56 - xtrace_memory_fragment_entry_t block_link; 57 - xtrace_memory_fragment_entry_t free_link; 58 - char memory[]; 59 - }; 60 - 61 - XTRACE_INLINE 62 - bool xtrace_memory_fragment_in_use(xtrace_memory_fragment_t fragment) { 63 - return fragment->flags & XTRACE_MEMORY_FRAGMENT_FLAG_IN_USE; 64 - }; 65 - 66 - XTRACE_INLINE 67 - void xtrace_memory_fragment_set_in_use(xtrace_memory_fragment_t fragment, bool in_use) { 68 - if (in_use) { 69 - fragment->flags |= XTRACE_MEMORY_FRAGMENT_FLAG_IN_USE; 70 - } else { 71 - fragment->flags &= ~XTRACE_MEMORY_FRAGMENT_FLAG_IN_USE; 72 - } 73 - }; 74 - 75 - XTRACE_INLINE 76 - bool xtrace_memory_fragment_is_mmap_base(xtrace_memory_fragment_t fragment) { 77 - return fragment->flags & XTRACE_MEMORY_FRAGMENT_FLAG_IS_MMAP_BASE; 78 - }; 79 - 80 - XTRACE_INLINE 81 - void xtrace_memory_fragment_set_is_mmap_base(xtrace_memory_fragment_t fragment, bool is_mmap_base) { 82 - if (is_mmap_base) { 83 - fragment->flags |= XTRACE_MEMORY_FRAGMENT_FLAG_IS_MMAP_BASE; 84 - } else { 85 - fragment->flags &= ~XTRACE_MEMORY_FRAGMENT_FLAG_IS_MMAP_BASE; 86 - } 87 - }; 88 - 89 - XTRACE_INLINE 90 - size_t xtrace_memory_fragment_size(xtrace_memory_fragment_t fragment) { 91 - return fragment->flags & XTRACE_MEMORY_FRAGMENT_SIZE_MASK; 92 - }; 93 - 94 - XTRACE_INLINE 95 - void xtrace_memory_fragment_set_size(xtrace_memory_fragment_t fragment, size_t new_size) { 96 - fragment->flags = (fragment->flags & ~XTRACE_MEMORY_FRAGMENT_SIZE_MASK) | (new_size & XTRACE_MEMORY_FRAGMENT_SIZE_MASK); 97 - }; 98 - 99 - XTRACE_INLINE 100 - void xtrace_memory_fragment_init(xtrace_memory_fragment_t fragment, size_t size) { 101 - xtrace_malloc_debug("initializing fragment of %llu bytes at %p", size, fragment); 102 - fragment->flags = size & XTRACE_MEMORY_FRAGMENT_SIZE_MASK; 103 - fragment->block_link.le_next = NULL; 104 - fragment->block_link.le_prev = NULL; 105 - fragment->free_link.le_next = NULL; 106 - fragment->free_link.le_prev = NULL; 107 - }; 108 - 109 - // 110 - // xtrace_memory_block 111 - // 112 - 113 - typedef struct xtrace_memory_block* xtrace_memory_block_t; 114 - struct xtrace_memory_block { 115 - uint64_t size; 116 - xtrace_memory_fragment_head_t fragment_list; 117 - struct xtrace_memory_fragment fragment; 118 - }; 119 - 120 - XTRACE_INLINE 121 - bool xtrace_memory_block_in_use(xtrace_memory_block_t block) { 122 - // the block is in use if either: 123 - // * the first fragment is in use, or 124 - // * the block has been fragmented 125 - return xtrace_memory_fragment_in_use(&block->fragment) || (block->size != xtrace_memory_fragment_size(&block->fragment)); 126 - }; 127 - 128 - XTRACE_INLINE 129 - void xtrace_memory_block_init(xtrace_memory_block_t block, size_t size) { 130 - block->size = size; 131 - LIST_INIT(&block->fragment_list); 132 - xtrace_memory_fragment_init(&block->fragment, block->size); 133 - xtrace_memory_fragment_set_is_mmap_base(&block->fragment, true); 134 - LIST_INSERT_HEAD(&block->fragment_list, &block->fragment, block_link); 135 - }; 136 - 137 - // 138 - // global variables 139 - // 140 - 141 - // list of available fragments 142 - static xtrace_memory_fragment_head_t free_list = LIST_HEAD_INITIALIZER(free_list); 143 - // lock for free_list 144 - static xtrace_lock_t free_lock = XTRACE_LOCK_INITIALIZER; 145 - 146 - // 147 - // internal functions 148 - // 149 - 150 - static xtrace_memory_fragment_t allocate_fragment(size_t required_size); 151 - static void release_fragment(xtrace_memory_fragment_t fragment); 152 - static bool shrink_fragment(xtrace_memory_fragment_t fragment, size_t new_size); 153 - static bool expand_fragment(xtrace_memory_fragment_t fragment, size_t new_size); 154 - 155 - // borrowed from libgmalloc 156 - XTRACE_INLINE 157 - size_t round_up(size_t size, size_t increment) { 158 - if ((size & (increment - 1)) == 0) { 159 - return size; 160 - } 161 - return (size | (increment - 1)) + 1; 162 - } 163 - 164 - static xtrace_memory_fragment_t allocate_fragment(size_t required_size) { 165 - xtrace_memory_fragment_t viable_fragment = NULL; 166 - size_t viable_fragment_size = 0; 167 - xtrace_memory_fragment_t loop_var = NULL; 168 - xtrace_lock_lock(&free_lock); 169 - 170 - // look for the smallest free fragment 171 - LIST_FOREACH(loop_var, &free_list, free_link) { 172 - size_t loop_var_size = xtrace_memory_fragment_size(loop_var); 173 - 174 - // 1. always make sure the current fragment is large enough 175 - // 2. we'll prefer the current fragment over the previous candidate if either: 176 - // * we don't currently have a candidate fragment, or 177 - // * the current fragment is smaller than the previous candidate 178 - if (loop_var_size > required_size && (viable_fragment == NULL || loop_var_size < viable_fragment_size)) { 179 - viable_fragment = loop_var; 180 - viable_fragment_size = loop_var_size; 181 - xtrace_malloc_debug("found viable fragment with address %p and size %llu", viable_fragment->memory, viable_fragment_size); 182 - } 183 - } 184 - 185 - // if we didn't find a viable candidate... 186 - if (viable_fragment == NULL) { 187 - // ...allocate some memory 188 - size_t allocation_size = round_up(required_size, BLOCK_SIZE_MULTIPLE); 189 - xtrace_memory_block_t block = (xtrace_memory_block_t)_mmap_for_xtrace(NULL, allocation_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); 190 - 191 - xtrace_malloc_debug("mmap for %llu bytes returned %p", allocation_size, block); 192 - 193 - // check if return value is an error code 194 - // see similar check in libkernel's `mman.c` 195 - if ((unsigned long)block > (unsigned long)-4096) { 196 - // we failed to allocate the memory, we can't do anything else 197 - xtrace_malloc_debug("mmap result was failure"); 198 - goto out; 199 - } 200 - 201 - // initialize it 202 - xtrace_memory_block_init(block, allocation_size - sizeof(struct xtrace_memory_block)); 203 - 204 - // add it to the free list 205 - LIST_INSERT_HEAD(&free_list, &block->fragment, free_link); 206 - 207 - // and set `viable_fragment` so our code below can handle it the same way as the no-mmap case 208 - viable_fragment = &block->fragment; 209 - } 210 - 211 - // at this point, `viable_fragment` is guaranteed to have a value 212 - xtrace_malloc_debug("final fragment for allocation: %llu bytes at %p", xtrace_memory_fragment_size(viable_fragment), viable_fragment->memory); 213 - 214 - // shrink the fragment (if possible) 215 - shrink_fragment(viable_fragment, required_size); 216 - 217 - // set the in_use bit 218 - xtrace_memory_fragment_set_in_use(viable_fragment, true); 219 - 220 - // finally, remove the viable fragment from the free list 221 - LIST_REMOVE(viable_fragment, free_link); 222 - 223 - out: 224 - xtrace_lock_unlock(&free_lock); 225 - 226 - return viable_fragment; 227 - }; 228 - 229 - static void release_fragment(xtrace_memory_fragment_t fragment) { 230 - xtrace_lock_lock(&free_lock); 231 - 232 - xtrace_malloc_debug("releasing fragment of %llu bytes at %p", xtrace_memory_fragment_size(fragment), fragment->memory); 233 - 234 - // clear the in_use bit 235 - xtrace_memory_fragment_set_in_use(fragment, false); 236 - 237 - // add it to the free list 238 - LIST_INSERT_HEAD(&free_list, fragment, free_link); 239 - 240 - // try to defragment the block 241 - while (true) { 242 - xtrace_memory_fragment_t prev_frag = xtrace_memory_fragment_is_mmap_base(fragment) ? NULL : LIST_PREV(fragment, block_link); 243 - xtrace_memory_fragment_t next_frag = LIST_NEXT(fragment, block_link); 244 - bool defragged = false; 245 - 246 - if (prev_frag && !xtrace_memory_fragment_in_use(prev_frag)) { 247 - xtrace_malloc_debug("defragmenting with previous fragment (%llu bytes at %p)", xtrace_memory_fragment_size(prev_frag), prev_frag->memory); 248 - defragged = true; 249 - 250 - // remove the current fragment from the free list 251 - LIST_REMOVE(fragment, free_link); 252 - 253 - // remove the current fragment from the block list 254 - LIST_REMOVE(fragment, block_link); 255 - 256 - // expand the previous fragment 257 - xtrace_memory_fragment_set_size(prev_frag, xtrace_memory_fragment_size(prev_frag) + sizeof(struct xtrace_memory_fragment) + xtrace_memory_fragment_size(fragment)); 258 - 259 - // `fragment` is now gone; set it to `prev_frag` 260 - fragment = prev_frag; 261 - } 262 - 263 - if (next_frag && !xtrace_memory_fragment_in_use(next_frag)) { 264 - xtrace_malloc_debug("defragmenting with next fragment (%llu bytes at %p)", xtrace_memory_fragment_size(fragment), fragment->memory); 265 - defragged = true; 266 - 267 - // remove the next fragment from the free list 268 - LIST_REMOVE(next_frag, free_link); 269 - 270 - // remove the next fragment from the block list 271 - LIST_REMOVE(next_frag, block_link); 272 - 273 - // expand the current fragment 274 - xtrace_memory_fragment_set_size(fragment, xtrace_memory_fragment_size(fragment) + sizeof(struct xtrace_memory_fragment) + xtrace_memory_fragment_size(next_frag)); 275 - 276 - // `next_frag` is now gone 277 - } 278 - 279 - // if we didn't defragment anything on this loop, we can't defragment any more 280 - if (!defragged) { 281 - xtrace_malloc_debug("cannot defragment any further"); 282 - break; 283 - } else { 284 - // otherwise, keep looping to try to defragment more 285 - xtrace_malloc_debug("doing another defragmentation iteration"); 286 - } 287 - } 288 - 289 - xtrace_malloc_debug("final releasing fragment is %llu bytes at %p", xtrace_memory_fragment_size(fragment), fragment->memory); 290 - 291 - // if `fragment` is the mmap base fragment... 292 - if (xtrace_memory_fragment_is_mmap_base(fragment)) { 293 - xtrace_memory_block_t block = __container_of(fragment, struct xtrace_memory_block, fragment); 294 - xtrace_malloc_debug("releasing fragment is base fragment"); 295 - 296 - // ...and we managed to defragment the entire block... 297 - if (!xtrace_memory_block_in_use(block)) { 298 - // ...unmap it! 299 - xtrace_malloc_debug("unmapping completely freed block (%llu bytes at %p)", block->size, block->fragment.memory); 300 - 301 - // start off by removing all traces of this block in the free list. 302 - // at this point, only the base fragment should be in the free list, so remove it 303 - LIST_REMOVE(fragment, free_link); 304 - 305 - // and now, just unmap it 306 - _munmap_for_xtrace(block, block->size + sizeof(struct xtrace_memory_block)); 307 - // and we ignore errors 308 - } 309 - } 310 - 311 - out: 312 - xtrace_lock_unlock(&free_lock); 313 - }; 314 - 315 - // must be called with free_lock held 316 - static bool shrink_fragment(xtrace_memory_fragment_t fragment, size_t new_size) { 317 - xtrace_malloc_debug("shrink to %llu bytes requested for fragment of %llu bytes at %p", new_size, xtrace_memory_fragment_size(fragment), fragment->memory); 318 - 319 - // calculate the remaining size if we were to shrink this fragment 320 - size_t remaining_size = xtrace_memory_fragment_size(fragment) - new_size; 321 - 322 - // if we would have enough space to create another fragment after shrinking this one... 323 - if (remaining_size > sizeof(struct xtrace_memory_fragment)) { 324 - xtrace_malloc_debug("fragment eligible; shrinking..."); 325 - 326 - // ...shrink it... 327 - xtrace_memory_fragment_set_size(fragment, new_size); 328 - 329 - // ...and create the new fragment 330 - xtrace_memory_fragment_t new_fragment = (xtrace_memory_fragment_t)(fragment->memory + new_size); 331 - xtrace_memory_fragment_init(new_fragment, remaining_size - sizeof(struct xtrace_memory_fragment)); 332 - 333 - // add it to the block list 334 - LIST_INSERT_AFTER(fragment, new_fragment, block_link); 335 - 336 - xtrace_malloc_debug("old fragment shrunk to %llu bytes at %p", xtrace_memory_fragment_size(fragment), fragment->memory); 337 - xtrace_malloc_debug("new fragment of %llu bytes created at %p", xtrace_memory_fragment_size(new_fragment), new_fragment->memory); 338 - 339 - // insert it into the free list 340 - LIST_INSERT_HEAD(&free_list, new_fragment, free_link); 341 - 342 - return true; 343 - } else { 344 - // otherwise, we don't want to shrink this one to avoid holes in our block 345 - xtrace_malloc_debug("fragment ineligible for shrinking (not enough space after it)"); 346 - } 347 - 348 - return false; 349 - }; 350 - 351 - // must be called with free_lock held 352 - static bool expand_fragment(xtrace_memory_fragment_t fragment, size_t new_size) { 353 - xtrace_malloc_debug("expansion to %llu bytes requested for fragment of %llu bytes at %p", new_size, xtrace_memory_fragment_size(fragment), fragment->memory); 354 - 355 - size_t available_size = xtrace_memory_fragment_size(fragment); 356 - xtrace_memory_fragment_t loop_var = fragment; 357 - xtrace_memory_fragment_t end_frag = NULL; 358 - 359 - while ((end_frag = LIST_NEXT(loop_var, block_link)) != NULL) { 360 - // if the fragment is in use... 361 - if (xtrace_memory_fragment_in_use(end_frag)) { 362 - // ...we've reached a limit 363 - xtrace_malloc_debug("insufficient free fragments for expansion"); 364 - break; 365 - } 366 - 367 - available_size += xtrace_memory_fragment_size(end_frag) + sizeof(struct xtrace_memory_fragment); 368 - loop_var = end_frag; 369 - 370 - // if we've got enough... 371 - if (available_size >= new_size) { 372 - xtrace_malloc_debug("found enough free fragments for expansion"); 373 - // ...we're done; we don't need to keep looking for more 374 - break; 375 - } 376 - } 377 - 378 - if (end_frag && available_size >= new_size) { 379 - xtrace_memory_fragment_t terminating_value = LIST_NEXT(end_frag, block_link); 380 - 381 - while (LIST_NEXT(fragment, block_link) != terminating_value) { 382 - xtrace_memory_fragment_t dying_fragment = LIST_NEXT(fragment, block_link); 383 - 384 - xtrace_malloc_debug("absorbing fragment of %llu bytes at %p", xtrace_memory_fragment_size(dying_fragment), dying_fragment->memory); 385 - 386 - // remove the dying fragment from the free list 387 - LIST_REMOVE(dying_fragment, free_link); 388 - 389 - // remove the dying fragment from the block list 390 - LIST_REMOVE(dying_fragment, block_link); 391 - 392 - // expand the surviving fragment 393 - xtrace_memory_fragment_set_size(fragment, xtrace_memory_fragment_size(fragment) + sizeof(struct xtrace_memory_fragment) + xtrace_memory_fragment_size(dying_fragment)); 394 - 395 - // `dying_fragment` is now gone 396 - } 397 - 398 - xtrace_malloc_debug("expanded fragment is %llu bytes at %p; trying to shrink...", xtrace_memory_fragment_size(fragment), fragment->memory); 399 - 400 - // try to shrink it so that we leave space for other possible fragments 401 - shrink_fragment(fragment, new_size); 402 - 403 - xtrace_malloc_debug("final fragment is %llu bytes at %p", xtrace_memory_fragment_size(fragment), fragment->memory); 404 - 405 - return true; 406 - } 407 - 408 - xtrace_malloc_debug("ineligible for expansion"); 409 - 410 - return false; 411 - }; 412 - 413 - // 414 - // api functions 415 - // 416 - 417 - extern "C" 418 - void* xtrace_malloc(size_t size) { 419 - if (size == 0) { 420 - return NULL; 421 - } 422 - xtrace_memory_fragment_t fragment = allocate_fragment(size); 423 - if (fragment == NULL) { 424 - return NULL; 425 - } 426 - return fragment->memory; 427 - }; 428 - 429 - extern "C" 430 - void xtrace_free(void* pointer) { 431 - if (pointer == NULL) { 432 - return; 433 - } 434 - xtrace_memory_fragment_t fragment = __container_of((const char (*)[])pointer, struct xtrace_memory_fragment, memory); 435 - release_fragment(fragment); 436 - }; 437 - 438 - extern "C" 439 - void* xtrace_realloc(void* old_pointer, size_t new_size) { 440 - xtrace_memory_fragment_t fragment = __container_of((const char (*)[])old_pointer, struct xtrace_memory_fragment, memory); 441 - size_t old_size = xtrace_memory_fragment_size(fragment); 442 - 443 - xtrace_lock_lock(&free_lock); 444 - 445 - // if we're shrinking, we can always do that 446 - if (new_size < old_size) { 447 - // we don't really care if it succeeds or not 448 - shrink_fragment(fragment, new_size); 449 - goto out; 450 - } else if (new_size == old_size) { 451 - // likewise, we can always keep it the same 452 - goto out; 453 - } 454 - 455 - // but otherwise, we're expanding 456 - 457 - // try to see if we can expand the fragment first 458 - if (expand_fragment(fragment, new_size)) { 459 - // if we expanded it successfully, we're done! 460 - goto out; 461 - } else { 462 - // otherwise, we need to allocate a new fragment 463 - xtrace_lock_unlock(&free_lock); // `allocate_fragment` takes the lock, so we need to drop it 464 - xtrace_memory_fragment_t new_fragment = allocate_fragment(new_size); 465 - if (new_fragment == NULL) { 466 - return NULL; 467 - } 468 - 469 - // copy the old contents to the new fragment 470 - memcpy(new_fragment->memory, fragment->memory, old_size); 471 - 472 - // and release the old fragment 473 - release_fragment(fragment); 474 - 475 - // assign the new pointer to the return variable and we're done! 476 - old_pointer = new_fragment->memory; 477 - goto out_unlocked; 478 - } 479 - 480 - out: 481 - xtrace_lock_unlock(&free_lock); 482 - 483 - out_unlocked: 484 - return old_pointer; 485 - };
-15
src/xtrace/malloc.h
··· 1 - #ifndef _XTRACE_MALLOC_H_ 2 - #define _XTRACE_MALLOC_H_ 3 - 4 - #include <stddef.h> 5 - #include "base.h" 6 - 7 - XTRACE_DECLARATIONS_C_BEGIN 8 - 9 - void* xtrace_malloc(size_t size); 10 - void xtrace_free(void* pointer); 11 - void* xtrace_realloc(void* old_pointer, size_t new_size); 12 - 13 - XTRACE_DECLARATIONS_C_END 14 - 15 - #endif // _XTRACE_MALLOC_H_
+18
src/xtrace/memory.cpp
··· 1 + #include <elfcalls.h> 2 + 3 + extern struct elf_calls* _elfcalls; 4 + 5 + extern "C" 6 + void* xtrace_malloc(size_t size) { 7 + return _elfcalls->malloc(size); 8 + } 9 + 10 + extern "C" 11 + void xtrace_free(void *ptr) { 12 + _elfcalls->free(ptr); 13 + } 14 + 15 + extern "C" 16 + void* xtrace_realloc(void *ptr, size_t size) { 17 + return _elfcalls->realloc(ptr, size); 18 + }
+15
src/xtrace/memory.h
··· 1 + #ifndef XTRACE_MEMORY 2 + #define XTRACE_MEMORY 3 + 4 + #include "base.h" 5 + #include <stddef.h> 6 + 7 + XTRACE_DECLARATIONS_C_BEGIN 8 + 9 + void* xtrace_malloc(size_t size); 10 + void xtrace_free(void *ptr); 11 + void* xtrace_realloc(void *ptr, size_t size); 12 + 13 + XTRACE_DECLARATIONS_C_END 14 + 15 + #endif // XTRACE_MEMORY
+1 -1
src/xtrace/tls.cpp
··· 1 1 #include <stdlib.h> 2 2 #include <darling/emulation/ext/for-xtrace.h> 3 3 #include "tls.h" 4 - #include "malloc.h" 4 + #include "memory.h" 5 5 #include "lock.h" 6 6 #include <darling/emulation/simple.h> 7 7 #include <pthread/tsd_private.h>
+1 -1
src/xtrace/xtracelib.cpp
··· 9 9 #include "mig_trace.h" 10 10 #include "tls.h" 11 11 #include "lock.h" 12 - #include "malloc.h" 12 + #include "memory.h" 13 13 #include <limits.h> 14 14 15 15 #include <darling/emulation/ext/for-xtrace.h>