Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 6 additions & 28 deletions src/custommem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2911,33 +2911,19 @@ void* find31bitBlockNearHint(void* hint_, size_t size, uintptr_t mask)
{
// first, check if program break as changed
catchup_brk_protection();
uint32_t prot;
uintptr_t hint = (uintptr_t)hint_;
if(hint_<LOWEST) hint = (uintptr_t)WINE_LOWEST;
uintptr_t bend = 0;
uintptr_t cur = (uintptr_t)hint;
uintptr_t upper = 0xc0000000LL;
if(cur>upper) upper = 0x100000000LL;
if(!mask) mask = 0xffff;
while(cur<upper) {
if(!rb_get_end(mapallmem, cur, &prot, &bend)) {
if(bend-cur>=size)
return (void*)cur;
}
// granularity 0x10000
cur = (bend+mask)&~mask;
}
if(rb_find_free_range(mapallmem, cur, upper, size, mask, &cur))
return (void*)cur;
if(hint_)
return NULL;
cur = (uintptr_t)LOWEST;
while(cur<(uintptr_t)hint) {
if(!rb_get_end(mapallmem, cur, &prot, &bend)) {
if(bend-cur>=size)
return (void*)cur;
}
// granularity 0x10000
cur = (bend+mask)&~mask;
}
if(rb_find_free_range(mapallmem, cur, hint, size, mask, &cur))
return (void*)cur;
return NULL;
}

Expand All @@ -2962,19 +2948,11 @@ void* find47bitBlockNearHint(void* hint, size_t size, uintptr_t mask)
{
// first, check if program break as changed
catchup_brk_protection();
uint32_t prot;
if(hint<LOWEST) hint = LOWEST;
uintptr_t bend = 0;
uintptr_t cur = (uintptr_t)hint;
if(!mask) mask = 0xffff;
while(bend<0x800000000000LL) {
if(!rb_get_end(mapallmem, cur, &prot, &bend)) {
if(bend-cur>=size)
return (void*)cur;
}
// granularity 0x10000
cur = (bend+mask)&~mask;
}
if(rb_find_free_range(mapallmem, cur, 0x800000000000LL, size, mask, &cur))
return (void*)cur;
return NULL;
}
void* find47bitBlockElf(size_t size, int mainbin, uintptr_t mask)
Expand Down
15 changes: 15 additions & 0 deletions src/include/rbtree.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#ifndef RBTREE_H
#define RBTREE_H

#include <stddef.h>
#include <stdint.h>

typedef struct rbtree rbtree_t;
Expand Down Expand Up @@ -136,6 +137,20 @@ int rb_get_end(rbtree_t* tree, uintptr_t addr, uint32_t* val, uintptr_t* end);
*/
int rb_get_end_64(rbtree_t* tree, uintptr_t addr, uint64_t* val, uintptr_t* end);

/**
* rb_find_free_range() - Finds the first suitably aligned free address range.
* @tree: Tree containing the occupied address ranges.
* @start: Inclusive lower bound for the search.
* @upper: Exclusive upper bound for the search.
* @size: Required size of the free range.
* @align_mask: Alignment mask applied after occupied ranges are skipped.
* @result: Pointer receiving the start of the first matching range.
*
* This function performs one tree descent followed by an in-order traversal.
* Return: 1 if a matching range was found, otherwise 0.
*/
int rb_find_free_range(rbtree_t* tree, uintptr_t start, uintptr_t upper, size_t size, uintptr_t align_mask, uintptr_t* result);

/**
* rb_set() - Set an address range in a red-black tree.
* @tree: Pointer to the red-black tree where the address range will be set.
Expand Down
40 changes: 40 additions & 0 deletions src/tools/rbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,46 @@ int rb_get_end_64(rbtree_t* tree, uintptr_t addr, uint64_t* val, uintptr_t* end)
return 0;
}

int rb_find_free_range(rbtree_t* tree, uintptr_t start, uintptr_t upper, size_t size, uintptr_t align_mask, uintptr_t* result)
{
if (!tree || !result || start >= upper || size > upper - start)
return 0;

uintptr_t cur = start;
rbnode *node = tree->root, *next = NULL;

while (node) {
if (node->end <= cur) {
node = node->right;
} else {
next = node;
node = node->left;
}
}

node = next;
while (node && cur < upper) {
if (node->start >= upper)
break;
if (cur < node->start && size <= node->start - cur) {
*result = cur;
return 1;
}
if (cur < node->end) {
if (node->end >= upper)
return 0;
cur = (node->end + align_mask) & ~align_mask;
}
node = succ_node(node);
}

if (cur < upper && size <= upper - cur) {
*result = cur;
return 1;
}
return 0;
}

int rb_set_64(rbtree_t *tree, uintptr_t start, uintptr_t end, uint64_t data) {
// printf("rb_set( "); rbtree_print(tree); printf(" , 0x%lx, 0x%lx, %hhu);\n", start, end, data); fflush(stdout);
dynarec_log(LOG_DEBUG, "set %s: 0x%lx, 0x%lx, 0x%x\n", tree->name, start, end, data);
Expand Down
Loading