summaryrefslogtreecommitdiff
path: root/src/buildvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildvm.c')
-rw-r--r--src/buildvm.c97
1 files changed, 68 insertions, 29 deletions
diff --git a/src/buildvm.c b/src/buildvm.c
index dd0cbcc6..1b4d6928 100644
--- a/src/buildvm.c
+++ b/src/buildvm.c
@@ -101,6 +101,33 @@ static void emit_raw(BuildCtx *ctx)
101 101
102/* -- Build machine code -------------------------------------------------- */ 102/* -- Build machine code -------------------------------------------------- */
103 103
104static const char *sym_decorate(BuildCtx *ctx,
105 const char *prefix, const char *suffix)
106{
107 char name[256];
108 char *p;
109#if LJ_64
110 const char *symprefix = ctx->mode == BUILD_machasm ? "_" : "";
111#else
112 const char *symprefix = ctx->mode != BUILD_elfasm ? "_" : "";
113#endif
114 sprintf(name, "%s%s%s", symprefix, prefix, suffix);
115 p = strchr(name, '@');
116 if (p) {
117 if (!LJ_64 && (ctx->mode == BUILD_coffasm || ctx->mode == BUILD_peobj))
118 name[0] = '@';
119 else
120 *p = '\0';
121 }
122 p = (char *)malloc(strlen(name)+1); /* MSVC doesn't like strdup. */
123 strcpy(p, name);
124 return p;
125}
126
127#define NRELOCSYM (sizeof(extnames)/sizeof(extnames[0])-1)
128
129static int relocmap[NRELOCSYM];
130
104/* Collect external relocations. */ 131/* Collect external relocations. */
105static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type) 132static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type)
106{ 133{
@@ -108,32 +135,38 @@ static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type)
108 fprintf(stderr, "Error: too many relocations, increase BUILD_MAX_RELOC.\n"); 135 fprintf(stderr, "Error: too many relocations, increase BUILD_MAX_RELOC.\n");
109 exit(1); 136 exit(1);
110 } 137 }
138 if (relocmap[idx] < 0) {
139 relocmap[idx] = ctx->nrelocsym;
140 ctx->relocsym[ctx->nrelocsym] = sym_decorate(ctx, "", extnames[idx]);
141 ctx->nrelocsym++;
142 }
111 ctx->reloc[ctx->nreloc].ofs = (int32_t)(addr - ctx->code); 143 ctx->reloc[ctx->nreloc].ofs = (int32_t)(addr - ctx->code);
112 ctx->reloc[ctx->nreloc].sym = idx; 144 ctx->reloc[ctx->nreloc].sym = relocmap[idx];
113 ctx->reloc[ctx->nreloc].type = type; 145 ctx->reloc[ctx->nreloc].type = type;
114 ctx->nreloc++; 146 ctx->nreloc++;
115 return 0; /* Encode symbol offset of 0. */ 147 return 0; /* Encode symbol offset of 0. */
116} 148}
117 149
118/* Naive insertion sort. Performance doesn't matter here. */ 150/* Naive insertion sort. Performance doesn't matter here. */
119static void perm_insert(int *perm, int32_t *ofs, int i) 151static void sym_insert(BuildCtx *ctx, int32_t ofs,
152 const char *prefix, const char *suffix)
120{ 153{
121 perm[i] = i; 154 ptrdiff_t i = ctx->nsym++;
122 while (i > 0) { 155 while (i > 0) {
123 int a = perm[i-1]; 156 if (ctx->sym[i-1].ofs <= ofs)
124 int b = perm[i]; 157 break;
125 if (ofs[a] <= ofs[b]) break; 158 ctx->sym[i] = ctx->sym[i-1];
126 perm[i] = a;
127 perm[i-1] = b;
128 i--; 159 i--;
129 } 160 }
161 ctx->sym[i].ofs = ofs;
162 ctx->sym[i].name = sym_decorate(ctx, prefix, suffix);
130} 163}
131 164
132/* Build the machine code. */ 165/* Build the machine code. */
133static int build_code(BuildCtx *ctx) 166static int build_code(BuildCtx *ctx)
134{ 167{
135 int status; 168 int status;
136 int i, j; 169 int i;
137 170
138 /* Initialize DynASM structures. */ 171 /* Initialize DynASM structures. */
139 ctx->nglob = GLOB__MAX; 172 ctx->nglob = GLOB__MAX;
@@ -141,8 +174,10 @@ static int build_code(BuildCtx *ctx)
141 memset(ctx->glob, 0, ctx->nglob*sizeof(void *)); 174 memset(ctx->glob, 0, ctx->nglob*sizeof(void *));
142 ctx->nreloc = 0; 175 ctx->nreloc = 0;
143 176
144 ctx->extnames = extnames;
145 ctx->globnames = globnames; 177 ctx->globnames = globnames;
178 ctx->relocsym = (const char **)malloc(NRELOCSYM*sizeof(const char *));
179 ctx->nrelocsym = 0;
180 for (i = 0; i < (int)NRELOCSYM; i++) relocmap[i] = -1;
146 181
147 ctx->dasm_ident = DASM_IDENT; 182 ctx->dasm_ident = DASM_IDENT;
148 ctx->dasm_arch = DASM_ARCH; 183 ctx->dasm_arch = DASM_ARCH;
@@ -160,37 +195,41 @@ static int build_code(BuildCtx *ctx)
160 ctx->code = (uint8_t *)malloc(ctx->codesz); 195 ctx->code = (uint8_t *)malloc(ctx->codesz);
161 if ((status = dasm_encode(Dst, (void *)ctx->code))) return status; 196 if ((status = dasm_encode(Dst, (void *)ctx->code))) return status;
162 197
163 /* Allocate the symbol offset and permutation tables. */ 198 /* Allocate symbol table and bytecode offsets. */
164 ctx->nsym = ctx->npc + ctx->nglob; 199 ctx->beginsym = sym_decorate(ctx, "", LABEL_PREFIX "vm_asm_begin");
165 ctx->perm = (int *)malloc((ctx->nsym+1)*sizeof(int *)); 200 ctx->sym = (BuildSym *)malloc((ctx->npc+ctx->nglob+1)*sizeof(BuildSym));
166 ctx->sym_ofs = (int32_t *)malloc((ctx->nsym+1)*sizeof(int32_t)); 201 ctx->nsym = 0;
202 ctx->bc_ofs = (int32_t *)malloc(ctx->npc*sizeof(int32_t));
167 203
168 /* Collect the opcodes (PC labels). */ 204 /* Collect the opcodes (PC labels). */
169 for (i = 0; i < ctx->npc; i++) { 205 for (i = 0; i < ctx->npc; i++) {
170 int32_t n = dasm_getpclabel(Dst, i); 206 int32_t ofs = dasm_getpclabel(Dst, i);
171 if (n < 0) return 0x22000000|i; 207 if (ofs < 0) return 0x22000000|i;
172 ctx->sym_ofs[i] = n; 208 ctx->bc_ofs[i] = ofs;
173 perm_insert(ctx->perm, ctx->sym_ofs, i); 209#if !LJ_HASJIT
210 if (!(i == BC_JFORI || i == BC_JFORL || i == BC_JITERL || i == BC_JLOOP ||
211 i == BC_IFORL || i == BC_IITERL || i == BC_ILOOP))
212#endif
213 sym_insert(ctx, ofs, LABEL_PREFIX_BC, bc_names[i]);
174 } 214 }
175 215
176 /* Collect the globals (named labels). */ 216 /* Collect the globals (named labels). */
177 for (j = 0; j < ctx->nglob; j++, i++) { 217 for (i = 0; i < ctx->nglob; i++) {
178 const char *gl = globnames[j]; 218 const char *gl = globnames[i];
179 int len = (int)strlen(gl); 219 int len = (int)strlen(gl);
180 if (!ctx->glob[j]) { 220 if (!ctx->glob[i]) {
181 fprintf(stderr, "Error: undefined global %s\n", gl); 221 fprintf(stderr, "Error: undefined global %s\n", gl);
182 exit(2); 222 exit(2);
183 } 223 }
184 if (len >= 2 && gl[len-2] == '_' && gl[len-1] == 'Z') 224 /* Skip the _Z symbols. */
185 ctx->sym_ofs[i] = -1; /* Skip the _Z symbols. */ 225 if (!(len >= 2 && gl[len-2] == '_' && gl[len-1] == 'Z'))
186 else 226 sym_insert(ctx, (int32_t)((uint8_t *)(ctx->glob[i]) - ctx->code),
187 ctx->sym_ofs[i] = (int32_t)((uint8_t *)(ctx->glob[j]) - ctx->code); 227 LABEL_PREFIX, globnames[i]);
188 perm_insert(ctx->perm, ctx->sym_ofs, i);
189 } 228 }
190 229
191 /* Close the address range. */ 230 /* Close the address range. */
192 ctx->sym_ofs[i] = (int32_t)ctx->codesz; 231 sym_insert(ctx, (int32_t)ctx->codesz, "", "");
193 perm_insert(ctx->perm, ctx->sym_ofs, i); 232 ctx->nsym--;
194 233
195 dasm_free(Dst); 234 dasm_free(Dst);
196 235
@@ -260,7 +299,7 @@ static void emit_bcdef(BuildCtx *ctx)
260 for (i = 0; i < ctx->npc; i++) { 299 for (i = 0; i < ctx->npc; i++) {
261 if (i != 0) 300 if (i != 0)
262 fprintf(ctx->fp, ",\n"); 301 fprintf(ctx->fp, ",\n");
263 fprintf(ctx->fp, "%d", ctx->sym_ofs[i]); 302 fprintf(ctx->fp, "%d", ctx->bc_ofs[i]);
264 } 303 }
265} 304}
266 305