summaryrefslogtreecommitdiff
path: root/src/buildvm_peobj.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildvm_peobj.c')
-rw-r--r--src/buildvm_peobj.c86
1 files changed, 16 insertions, 70 deletions
diff --git a/src/buildvm_peobj.c b/src/buildvm_peobj.c
index 2ff274f9..4cde6e00 100644
--- a/src/buildvm_peobj.c
+++ b/src/buildvm_peobj.c
@@ -84,14 +84,11 @@ typedef struct PEsymaux {
84#define PEOBJ_ARCH_TARGET 0x014c 84#define PEOBJ_ARCH_TARGET 0x014c
85#define PEOBJ_RELOC_REL32 0x14 /* MS: REL32, GNU: DISP32. */ 85#define PEOBJ_RELOC_REL32 0x14 /* MS: REL32, GNU: DISP32. */
86#define PEOBJ_RELOC_DIR32 0x06 86#define PEOBJ_RELOC_DIR32 0x06
87#define PEOBJ_SYM_PREFIX "_"
88#define PEOBJ_SYMF_PREFIX "@"
89#elif LJ_TARGET_X64 87#elif LJ_TARGET_X64
90#define PEOBJ_ARCH_TARGET 0x8664 88#define PEOBJ_ARCH_TARGET 0x8664
91#define PEOBJ_RELOC_REL32 0x04 /* MS: REL32, GNU: DISP32. */ 89#define PEOBJ_RELOC_REL32 0x04 /* MS: REL32, GNU: DISP32. */
92#define PEOBJ_RELOC_DIR32 0x02 90#define PEOBJ_RELOC_DIR32 0x02
93#define PEOBJ_RELOC_ADDR32NB 0x03 91#define PEOBJ_RELOC_ADDR32NB 0x03
94#define PEOBJ_SYM_PREFIX ""
95#endif 92#endif
96 93
97/* Section numbers (0-based). */ 94/* Section numbers (0-based). */
@@ -164,18 +161,13 @@ static void emit_peobj_sym_sect(BuildCtx *ctx, PEsection *pesect, int sect)
164 owrite(ctx, &aux, PEOBJ_SYM_SIZE); 161 owrite(ctx, &aux, PEOBJ_SYM_SIZE);
165} 162}
166 163
167#define emit_peobj_sym_func(ctx, name, ofs) \
168 emit_peobj_sym(ctx, name, (uint32_t)(ofs), \
169 PEOBJ_SECT_TEXT, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN)
170
171/* Emit Windows PE object file. */ 164/* Emit Windows PE object file. */
172void emit_peobj(BuildCtx *ctx) 165void emit_peobj(BuildCtx *ctx)
173{ 166{
174 PEheader pehdr; 167 PEheader pehdr;
175 PEsection pesect[PEOBJ_NSECTIONS]; 168 PEsection pesect[PEOBJ_NSECTIONS];
176 int nzsym, relocsyms;
177 uint32_t sofs; 169 uint32_t sofs;
178 int i; 170 int i, nrsym;
179 union { uint8_t b; uint32_t u; } host_endian; 171 union { uint8_t b; uint32_t u; } host_endian;
180 172
181 host_endian.u = 1; 173 host_endian.u = 1;
@@ -230,16 +222,11 @@ void emit_peobj(BuildCtx *ctx)
230 222
231 /* Compute the size of the symbol table: 223 /* Compute the size of the symbol table:
232 ** @feat.00 + nsections*2 224 ** @feat.00 + nsections*2
233 ** + asm_start + (nsyms-nzsym) 225 ** + asm_start + nsym
234 ** + relocsyms 226 ** + nrsym
235 */ 227 */
236 /* Skip _Z syms. */ 228 nrsym = ctx->nrelocsym;
237 for (nzsym = 0; ctx->sym_ofs[ctx->perm[nzsym]] < 0; nzsym++) ; 229 pehdr.nsyms = 1+PEOBJ_NSECTIONS*2 + 1+ctx->nsym + nrsym;
238 for (relocsyms = 0; ctx->extnames[relocsyms]; relocsyms++) ;
239 pehdr.nsyms = 1+PEOBJ_NSECTIONS*2 + 1+(ctx->nsym-nzsym) + relocsyms;
240#if !LJ_HASJIT
241 pehdr.nsyms -= 11; /* See below, removes [IJ]* opcode symbols. */
242#endif
243#if LJ_TARGET_X64 230#if LJ_TARGET_X64
244 pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win64. */ 231 pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win64. */
245#endif 232#endif
@@ -264,13 +251,13 @@ void emit_peobj(BuildCtx *ctx)
264 PEreloc reloc; 251 PEreloc reloc;
265 pdata[0] = 0; pdata[1] = (uint32_t)ctx->codesz; pdata[2] = 0; 252 pdata[0] = 0; pdata[1] = (uint32_t)ctx->codesz; pdata[2] = 0;
266 owrite(ctx, &pdata, sizeof(pdata)); 253 owrite(ctx, &pdata, sizeof(pdata));
267 reloc.vaddr = 0; reloc.symidx = 1+2+relocsyms+2+2+1; 254 reloc.vaddr = 0; reloc.symidx = 1+2+nrsym+2+2+1;
268 reloc.type = PEOBJ_RELOC_ADDR32NB; 255 reloc.type = PEOBJ_RELOC_ADDR32NB;
269 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); 256 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
270 reloc.vaddr = 4; reloc.symidx = 1+2+relocsyms+2+2+1; 257 reloc.vaddr = 4; reloc.symidx = 1+2+nrsym+2+2+1;
271 reloc.type = PEOBJ_RELOC_ADDR32NB; 258 reloc.type = PEOBJ_RELOC_ADDR32NB;
272 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); 259 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
273 reloc.vaddr = 8; reloc.symidx = 1+2+relocsyms+2; 260 reloc.vaddr = 8; reloc.symidx = 1+2+nrsym+2;
274 reloc.type = PEOBJ_RELOC_ADDR32NB; 261 reloc.type = PEOBJ_RELOC_ADDR32NB;
275 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); 262 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
276 } 263 }
@@ -287,7 +274,7 @@ void emit_peobj(BuildCtx *ctx)
287 xdata[7] = 0; /* Alignment. */ 274 xdata[7] = 0; /* Alignment. */
288 xdata[8] = xdata[9] = 0; /* Relocated address of exception handler. */ 275 xdata[8] = xdata[9] = 0; /* Relocated address of exception handler. */
289 owrite(ctx, &xdata, sizeof(xdata)); 276 owrite(ctx, &xdata, sizeof(xdata));
290 reloc.vaddr = sizeof(xdata)-4; reloc.symidx = 1+2+relocsyms+2+2; 277 reloc.vaddr = sizeof(xdata)-4; reloc.symidx = 1+2+nrsym+2+2;
291 reloc.type = PEOBJ_RELOC_ADDR32NB; 278 reloc.type = PEOBJ_RELOC_ADDR32NB;
292 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); 279 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
293 } 280 }
@@ -299,69 +286,28 @@ void emit_peobj(BuildCtx *ctx)
299 /* Write symbol table. */ 286 /* Write symbol table. */
300 strtab = NULL; /* 1st pass: collect string sizes. */ 287 strtab = NULL; /* 1st pass: collect string sizes. */
301 for (;;) { 288 for (;;) {
302 char name[80];
303
304 strtabofs = 4; 289 strtabofs = 4;
305 /* Mark as SafeSEH compliant. */ 290 /* Mark as SafeSEH compliant. */
306 emit_peobj_sym(ctx, "@feat.00", 1, 291 emit_peobj_sym(ctx, "@feat.00", 1,
307 PEOBJ_SECT_ABS, PEOBJ_TYPE_NULL, PEOBJ_SCL_STATIC); 292 PEOBJ_SECT_ABS, PEOBJ_TYPE_NULL, PEOBJ_SCL_STATIC);
308 293
309 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_TEXT); 294 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_TEXT);
310 for (i = 0; ctx->extnames[i]; i++) { 295 for (i = 0; i < nrsym; i++)
311 const char *sym = ctx->extnames[i]; 296 emit_peobj_sym(ctx, ctx->relocsym[i], 0,
312 const char *p = strchr(sym, '@');
313 if (p) {
314#ifdef PEOBJ_SYMF_PREFIX
315 sprintf(name, PEOBJ_SYMF_PREFIX "%s", sym);
316#else
317 strncpy(name, sym, p-sym);
318 name[p-sym] = '\0';
319#endif
320 } else {
321 sprintf(name, PEOBJ_SYM_PREFIX "%s", sym);
322 }
323 emit_peobj_sym(ctx, name, 0,
324 PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN); 297 PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
325 }
326 298
327#if LJ_TARGET_X64 299#if LJ_TARGET_X64
328 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_PDATA); 300 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_PDATA);
329 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_XDATA); 301 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_XDATA);
330 emit_peobj_sym(ctx, PEOBJ_SYM_PREFIX "lj_err_unwind_win64", 0, 302 emit_peobj_sym(ctx, "lj_err_unwind_win64", 0,
331 PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN); 303 PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
332#endif 304#endif
333 305
334 emit_peobj_sym(ctx, PEOBJ_SYM_PREFIX LABEL_ASM_BEGIN, 0, 306 emit_peobj_sym(ctx, ctx->beginsym, 0,
335 PEOBJ_SECT_TEXT, PEOBJ_TYPE_NULL, PEOBJ_SCL_EXTERN); 307 PEOBJ_SECT_TEXT, PEOBJ_TYPE_NULL, PEOBJ_SCL_EXTERN);
336 for (i = nzsym; i < ctx->nsym; i++) { 308 for (i = 0; i < ctx->nsym; i++)
337 int pi = ctx->perm[i]; 309 emit_peobj_sym(ctx, ctx->sym[i].name, (uint32_t)ctx->sym[i].ofs,
338 if (pi >= ctx->npc) { 310 PEOBJ_SECT_TEXT, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
339 const char *sym = ctx->globnames[pi-ctx->npc];
340 const char *p = strchr(sym, '@');
341 if (p) {
342#ifdef PEOBJ_SYMF_PREFIX
343 sprintf(name, PEOBJ_SYMF_PREFIX LABEL_PREFIX "%s", sym);
344#else
345 sprintf(name, LABEL_PREFIX "%s", sym);
346 name[(p-sym)+sizeof(LABEL_PREFIX)-1] = '\0';
347#endif
348 } else {
349 sprintf(name, PEOBJ_SYM_PREFIX LABEL_PREFIX "%s", sym);
350 }
351 emit_peobj_sym_func(ctx, name, ctx->sym_ofs[pi]);
352#if LJ_HASJIT
353 } else {
354#else
355 } else if (!(pi == BC_JFORI || pi == BC_JFORL || pi == BC_JITERL ||
356 pi == BC_JLOOP || pi == BC_JFUNCF || pi == BC_JFUNCV ||
357 pi == BC_IFORL || pi == BC_IITERL || pi == BC_ILOOP ||
358 pi == BC_IFUNCF || pi == BC_IFUNCV)) {
359#endif
360 sprintf(name, PEOBJ_SYM_PREFIX LABEL_PREFIX_BC "%s",
361 bc_names[pi]);
362 emit_peobj_sym_func(ctx, name, ctx->sym_ofs[pi]);
363 }
364 }
365 311
366 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_RDATA_Z); 312 emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_RDATA_Z);
367 313