From 3d62a7f25377c3b31efedc3a3211146d1d156a5e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 15 Mar 2020 02:48:13 +0900 Subject: [PATCH] [gamecode] Use fuzzy bsearch to find defs by address The idea is to find th def that contains the address. Had to write my own bsearch (well... lifted from wikipedia) because libc's is exact. The defs are assumed to be sorted (which qfcc now ensures when it writes progs and sym files). --- include/QF/progs.h | 2 ++ libs/gamecode/pr_resolve.c | 42 ++++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/include/QF/progs.h b/include/QF/progs.h index 2659ce303..7dc7e4af2 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -321,6 +321,8 @@ void ED_EntityParseFunction (progs_t *pr); */ ///@{ +pr_def_t *PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pointer_t offset) + __attribute__((pure)); pr_def_t *PR_FieldAtOfs (progs_t *pr, pointer_t ofs) __attribute__((pure)); pr_def_t *PR_GlobalAtOfs (progs_t *pr, pointer_t ofs) __attribute__((pure)); diff --git a/libs/gamecode/pr_resolve.c b/libs/gamecode/pr_resolve.c index 5297f101a..03e6949a2 100644 --- a/libs/gamecode/pr_resolve.c +++ b/libs/gamecode/pr_resolve.c @@ -43,32 +43,38 @@ static const char param_str[] = ".param_0"; +pr_def_t * +PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pointer_t offset) +{ + // fuzzy bsearh + unsigned left = 0; + unsigned right = num_defs - 1; + unsigned mid; + + while (left != right) { + mid = (left + right + 1) / 2; + if (defs[mid].ofs > offset) { + right = mid - 1; + } else { + left = mid; + } + } + if (defs[left].ofs <= offset) { + return defs + left; + } + return 0; +} + pr_def_t * PR_GlobalAtOfs (progs_t * pr, pointer_t ofs) { - pr_def_t *def; - pr_uint_t i; - - for (i = 0; i < pr->progs->numglobaldefs; i++) { - def = &pr->pr_globaldefs[i]; - if (def->ofs == ofs) - return def; - } - return NULL; + return PR_SearchDefs (pr->pr_globaldefs, pr->progs->numglobaldefs, ofs); } VISIBLE pr_def_t * PR_FieldAtOfs (progs_t * pr, pointer_t ofs) { - pr_def_t *def; - pr_uint_t i; - - for (i = 0; i < pr->progs->numfielddefs; i++) { - def = &pr->pr_fielddefs[i]; - if (def->ofs == ofs) - return def; - } - return NULL; + return PR_SearchDefs (pr->pr_fielddefs, pr->progs->numfielddefs, ofs); } VISIBLE pr_def_t *