ntdll: Move find_function_info() to the CPU backends.

This commit is contained in:
Alexandre Julliard 2024-02-13 11:56:51 +01:00
parent 215a8e68d3
commit 02ebacca0c
6 changed files with 97 additions and 37 deletions

View file

@ -626,42 +626,6 @@ RUNTIME_FUNCTION *lookup_dynamic_function_table( ULONG_PTR pc, ULONG_PTR *base,
return ret;
}
/* helper for lookup_function_info() */
RUNTIME_FUNCTION *find_function_info( ULONG_PTR pc, ULONG_PTR base,
RUNTIME_FUNCTION *func, ULONG size )
{
int min = 0;
int max = size - 1;
while (min <= max)
{
#ifdef __x86_64__
int pos = (min + max) / 2;
if (pc < base + func[pos].BeginAddress) max = pos - 1;
else if (pc >= base + func[pos].EndAddress) min = pos + 1;
else
{
func += pos;
while (func->UnwindData & 1) /* follow chained entry */
func = (RUNTIME_FUNCTION *)(base + (func->UnwindData & ~1));
return func;
}
#elif defined(__arm__)
int pos = (min + max) / 2;
if (pc < base + (func[pos].BeginAddress & ~1)) max = pos - 1;
else if (pc >= base + get_runtime_function_end( &func[pos], base )) min = pos + 1;
else return func + pos;
#else /* __aarch64__ */
int pos = (min + max) / 2;
if (pc < base + func[pos].BeginAddress) max = pos - 1;
else if (pc >= base + get_runtime_function_end( &func[pos], base )) min = pos + 1;
else return func + pos;
#endif
}
return NULL;
}
#endif /* __x86_64__ || __arm__ || __aarch64__ */

View file

@ -86,7 +86,6 @@ extern void (WINAPI *pWow64PrepareForException)( EXCEPTION_RECORD *rec, CONTEXT
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
extern RUNTIME_FUNCTION *lookup_dynamic_function_table( ULONG_PTR pc, ULONG_PTR *base, ULONG *count );
extern RUNTIME_FUNCTION *find_function_info( ULONG_PTR pc, ULONG_PTR base, RUNTIME_FUNCTION *func, ULONG size );
#endif
/* debug helpers */

View file

@ -1113,6 +1113,32 @@ static void *unwind_full_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION *f
return NULL;
}
/**********************************************************************
* find_function_info
*/
static RUNTIME_FUNCTION *find_function_info( ULONG_PTR pc, ULONG_PTR base,
RUNTIME_FUNCTION *func, ULONG size )
{
int min = 0;
int max = size - 1;
while (min <= max)
{
int pos = (min + max) / 2;
ULONG_PTR start = base + (func[pos].BeginAddress & ~1);
if (pc >= start)
{
struct unwind_info *info = (struct unwind_info *)(base + func[pos].UnwindData);
if (pc < start + 2 * (func[pos].Flag ? func[pos].FunctionLength : info->function_length))
return func + pos;
min = pos + 1;
}
else max = pos - 1;
}
return NULL;
}
/***********************************************************************
* RtlVirtualUnwind (NTDLL.@)
*/

View file

@ -1014,6 +1014,33 @@ static void *unwind_full_data( ULONG_PTR base, ULONG_PTR pc, RUNTIME_FUNCTION *f
}
/**********************************************************************
* find_function_info
*/
static RUNTIME_FUNCTION *find_function_info( ULONG_PTR pc, ULONG_PTR base,
RUNTIME_FUNCTION *func, ULONG size )
{
int min = 0;
int max = size - 1;
while (min <= max)
{
int pos = (min + max) / 2;
ULONG_PTR start = base + func[pos].BeginAddress;
if (pc >= start)
{
ULONG len = func[pos].Flag ? func[pos].FunctionLength :
((IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA *)(base + func[pos].UnwindData))->FunctionLength;
if (pc < start + 4 * len) return func + pos;
min = pos + 1;
}
else max = pos - 1;
}
return NULL;
}
/**********************************************************************
* RtlVirtualUnwind (NTDLL.@)
*/

View file

@ -229,6 +229,28 @@ static void context_arm_to_x64( CONTEXT *ctx, const ARM64_NT_CONTEXT *arm_ctx )
memcpy( ec_ctx->V, arm_ctx->V, sizeof(ec_ctx->V) );
}
static RUNTIME_FUNCTION *find_function_info( ULONG_PTR pc, ULONG_PTR base,
RUNTIME_FUNCTION *func, ULONG size )
{
int min = 0;
int max = size - 1;
while (min <= max)
{
int pos = (min + max) / 2;
if (pc < base + func[pos].BeginAddress) max = pos - 1;
else if (pc >= base + func[pos].EndAddress) min = pos + 1;
else
{
func += pos;
while (func->UnwindData & 1) /* follow chained entry */
func = (RUNTIME_FUNCTION *)(base + (func->UnwindData & ~1));
return func;
}
}
return NULL;
}
/*******************************************************************
* syscalls

View file

@ -249,6 +249,28 @@ static void dump_scope_table( ULONG64 base, const SCOPE_TABLE *table )
(char *)base + table->ScopeRecord[i].JumpTarget );
}
static RUNTIME_FUNCTION *find_function_info( ULONG_PTR pc, ULONG_PTR base,
RUNTIME_FUNCTION *func, ULONG size )
{
int min = 0;
int max = size - 1;
while (min <= max)
{
int pos = (min + max) / 2;
if (pc < base + func[pos].BeginAddress) max = pos - 1;
else if (pc >= base + func[pos].EndAddress) min = pos + 1;
else
{
func += pos;
while (func->UnwindData & 1) /* follow chained entry */
func = (RUNTIME_FUNCTION *)(base + (func->UnwindData & ~1));
return func;
}
}
return NULL;
}
/***********************************************************************
* virtual_unwind