Refactor buildvm symbol generation.

Fixes Windows and OSX builds with LUAJIT_DISABLE_JIT.
This commit is contained in:
Mike Pall
2010-04-14 17:13:13 +02:00
parent fbe092c22d
commit ff82df797a
8 changed files with 203 additions and 324 deletions

View File

@@ -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]);
}
}