Refactor buildvm symbol generation.
Fixes Windows and OSX builds with LUAJIT_DISABLE_JIT.
This commit is contained in:
@@ -101,6 +101,33 @@ static void emit_raw(BuildCtx *ctx)
|
||||
|
||||
/* -- Build machine code -------------------------------------------------- */
|
||||
|
||||
static const char *sym_decorate(BuildCtx *ctx,
|
||||
const char *prefix, const char *suffix)
|
||||
{
|
||||
char name[256];
|
||||
char *p;
|
||||
#if LJ_64
|
||||
const char *symprefix = ctx->mode == BUILD_machasm ? "_" : "";
|
||||
#else
|
||||
const char *symprefix = ctx->mode != BUILD_elfasm ? "_" : "";
|
||||
#endif
|
||||
sprintf(name, "%s%s%s", symprefix, prefix, suffix);
|
||||
p = strchr(name, '@');
|
||||
if (p) {
|
||||
if (!LJ_64 && (ctx->mode == BUILD_coffasm || ctx->mode == BUILD_peobj))
|
||||
name[0] = '@';
|
||||
else
|
||||
*p = '\0';
|
||||
}
|
||||
p = (char *)malloc(strlen(name)+1); /* MSVC doesn't like strdup. */
|
||||
strcpy(p, name);
|
||||
return p;
|
||||
}
|
||||
|
||||
#define NRELOCSYM (sizeof(extnames)/sizeof(extnames[0])-1)
|
||||
|
||||
static int relocmap[NRELOCSYM];
|
||||
|
||||
/* Collect external relocations. */
|
||||
static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type)
|
||||
{
|
||||
@@ -108,32 +135,38 @@ static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type)
|
||||
fprintf(stderr, "Error: too many relocations, increase BUILD_MAX_RELOC.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (relocmap[idx] < 0) {
|
||||
relocmap[idx] = ctx->nrelocsym;
|
||||
ctx->relocsym[ctx->nrelocsym] = sym_decorate(ctx, "", extnames[idx]);
|
||||
ctx->nrelocsym++;
|
||||
}
|
||||
ctx->reloc[ctx->nreloc].ofs = (int32_t)(addr - ctx->code);
|
||||
ctx->reloc[ctx->nreloc].sym = idx;
|
||||
ctx->reloc[ctx->nreloc].sym = relocmap[idx];
|
||||
ctx->reloc[ctx->nreloc].type = type;
|
||||
ctx->nreloc++;
|
||||
return 0; /* Encode symbol offset of 0. */
|
||||
}
|
||||
|
||||
/* Naive insertion sort. Performance doesn't matter here. */
|
||||
static void perm_insert(int *perm, int32_t *ofs, int i)
|
||||
static void sym_insert(BuildCtx *ctx, int32_t ofs,
|
||||
const char *prefix, const char *suffix)
|
||||
{
|
||||
perm[i] = i;
|
||||
ptrdiff_t i = ctx->nsym++;
|
||||
while (i > 0) {
|
||||
int a = perm[i-1];
|
||||
int b = perm[i];
|
||||
if (ofs[a] <= ofs[b]) break;
|
||||
perm[i] = a;
|
||||
perm[i-1] = b;
|
||||
if (ctx->sym[i-1].ofs <= ofs)
|
||||
break;
|
||||
ctx->sym[i] = ctx->sym[i-1];
|
||||
i--;
|
||||
}
|
||||
ctx->sym[i].ofs = ofs;
|
||||
ctx->sym[i].name = sym_decorate(ctx, prefix, suffix);
|
||||
}
|
||||
|
||||
/* Build the machine code. */
|
||||
static int build_code(BuildCtx *ctx)
|
||||
{
|
||||
int status;
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
/* Initialize DynASM structures. */
|
||||
ctx->nglob = GLOB__MAX;
|
||||
@@ -141,8 +174,10 @@ static int build_code(BuildCtx *ctx)
|
||||
memset(ctx->glob, 0, ctx->nglob*sizeof(void *));
|
||||
ctx->nreloc = 0;
|
||||
|
||||
ctx->extnames = extnames;
|
||||
ctx->globnames = globnames;
|
||||
ctx->relocsym = (const char **)malloc(NRELOCSYM*sizeof(const char *));
|
||||
ctx->nrelocsym = 0;
|
||||
for (i = 0; i < (int)NRELOCSYM; i++) relocmap[i] = -1;
|
||||
|
||||
ctx->dasm_ident = DASM_IDENT;
|
||||
ctx->dasm_arch = DASM_ARCH;
|
||||
@@ -160,37 +195,41 @@ static int build_code(BuildCtx *ctx)
|
||||
ctx->code = (uint8_t *)malloc(ctx->codesz);
|
||||
if ((status = dasm_encode(Dst, (void *)ctx->code))) return status;
|
||||
|
||||
/* Allocate the symbol offset and permutation tables. */
|
||||
ctx->nsym = ctx->npc + ctx->nglob;
|
||||
ctx->perm = (int *)malloc((ctx->nsym+1)*sizeof(int *));
|
||||
ctx->sym_ofs = (int32_t *)malloc((ctx->nsym+1)*sizeof(int32_t));
|
||||
/* Allocate symbol table and bytecode offsets. */
|
||||
ctx->beginsym = sym_decorate(ctx, "", LABEL_PREFIX "vm_asm_begin");
|
||||
ctx->sym = (BuildSym *)malloc((ctx->npc+ctx->nglob+1)*sizeof(BuildSym));
|
||||
ctx->nsym = 0;
|
||||
ctx->bc_ofs = (int32_t *)malloc(ctx->npc*sizeof(int32_t));
|
||||
|
||||
/* Collect the opcodes (PC labels). */
|
||||
for (i = 0; i < ctx->npc; i++) {
|
||||
int32_t n = dasm_getpclabel(Dst, i);
|
||||
if (n < 0) return 0x22000000|i;
|
||||
ctx->sym_ofs[i] = n;
|
||||
perm_insert(ctx->perm, ctx->sym_ofs, i);
|
||||
int32_t ofs = dasm_getpclabel(Dst, i);
|
||||
if (ofs < 0) return 0x22000000|i;
|
||||
ctx->bc_ofs[i] = ofs;
|
||||
#if !LJ_HASJIT
|
||||
if (!(i == BC_JFORI || i == BC_JFORL || i == BC_JITERL || i == BC_JLOOP ||
|
||||
i == BC_IFORL || i == BC_IITERL || i == BC_ILOOP))
|
||||
#endif
|
||||
sym_insert(ctx, ofs, LABEL_PREFIX_BC, bc_names[i]);
|
||||
}
|
||||
|
||||
/* Collect the globals (named labels). */
|
||||
for (j = 0; j < ctx->nglob; j++, i++) {
|
||||
const char *gl = globnames[j];
|
||||
for (i = 0; i < ctx->nglob; i++) {
|
||||
const char *gl = globnames[i];
|
||||
int len = (int)strlen(gl);
|
||||
if (!ctx->glob[j]) {
|
||||
if (!ctx->glob[i]) {
|
||||
fprintf(stderr, "Error: undefined global %s\n", gl);
|
||||
exit(2);
|
||||
}
|
||||
if (len >= 2 && gl[len-2] == '_' && gl[len-1] == 'Z')
|
||||
ctx->sym_ofs[i] = -1; /* Skip the _Z symbols. */
|
||||
else
|
||||
ctx->sym_ofs[i] = (int32_t)((uint8_t *)(ctx->glob[j]) - ctx->code);
|
||||
perm_insert(ctx->perm, ctx->sym_ofs, i);
|
||||
/* Skip the _Z symbols. */
|
||||
if (!(len >= 2 && gl[len-2] == '_' && gl[len-1] == 'Z'))
|
||||
sym_insert(ctx, (int32_t)((uint8_t *)(ctx->glob[i]) - ctx->code),
|
||||
LABEL_PREFIX, globnames[i]);
|
||||
}
|
||||
|
||||
/* Close the address range. */
|
||||
ctx->sym_ofs[i] = (int32_t)ctx->codesz;
|
||||
perm_insert(ctx->perm, ctx->sym_ofs, i);
|
||||
sym_insert(ctx, (int32_t)ctx->codesz, "", "");
|
||||
ctx->nsym--;
|
||||
|
||||
dasm_free(Dst);
|
||||
|
||||
@@ -260,7 +299,7 @@ static void emit_bcdef(BuildCtx *ctx)
|
||||
for (i = 0; i < ctx->npc; i++) {
|
||||
if (i != 0)
|
||||
fprintf(ctx->fp, ",\n");
|
||||
fprintf(ctx->fp, "%d", ctx->sym_ofs[i]);
|
||||
fprintf(ctx->fp, "%d", ctx->bc_ofs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user