diff options
Diffstat (limited to 'src/host/buildvm_peobj.c')
-rw-r--r-- | src/host/buildvm_peobj.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/src/host/buildvm_peobj.c b/src/host/buildvm_peobj.c index aab00d68..2eb2bb7b 100644 --- a/src/host/buildvm_peobj.c +++ b/src/host/buildvm_peobj.c | |||
@@ -109,6 +109,8 @@ enum { | |||
109 | #if LJ_TARGET_X64 | 109 | #if LJ_TARGET_X64 |
110 | PEOBJ_SECT_PDATA, | 110 | PEOBJ_SECT_PDATA, |
111 | PEOBJ_SECT_XDATA, | 111 | PEOBJ_SECT_XDATA, |
112 | #elif LJ_TARGET_X86 | ||
113 | PEOBJ_SECT_SXDATA, | ||
112 | #endif | 114 | #endif |
113 | PEOBJ_SECT_RDATA_Z, | 115 | PEOBJ_SECT_RDATA_Z, |
114 | PEOBJ_NSECTIONS | 116 | PEOBJ_NSECTIONS |
@@ -208,6 +210,13 @@ void emit_peobj(BuildCtx *ctx) | |||
208 | sofs += (pesect[PEOBJ_SECT_XDATA].nreloc = 1) * PEOBJ_RELOC_SIZE; | 210 | sofs += (pesect[PEOBJ_SECT_XDATA].nreloc = 1) * PEOBJ_RELOC_SIZE; |
209 | /* Flags: 40 = read, 30 = align4, 40 = initialized data. */ | 211 | /* Flags: 40 = read, 30 = align4, 40 = initialized data. */ |
210 | pesect[PEOBJ_SECT_XDATA].flags = 0x40300040; | 212 | pesect[PEOBJ_SECT_XDATA].flags = 0x40300040; |
213 | #elif LJ_TARGET_X86 | ||
214 | memcpy(pesect[PEOBJ_SECT_SXDATA].name, ".sxdata", sizeof(".sxdata")-1); | ||
215 | pesect[PEOBJ_SECT_SXDATA].ofs = sofs; | ||
216 | sofs += (pesect[PEOBJ_SECT_SXDATA].size = 4); | ||
217 | pesect[PEOBJ_SECT_SXDATA].relocofs = sofs; | ||
218 | /* Flags: 40 = read, 30 = align4, 02 = lnk_info, 40 = initialized data. */ | ||
219 | pesect[PEOBJ_SECT_SXDATA].flags = 0x40300240; | ||
211 | #endif | 220 | #endif |
212 | 221 | ||
213 | memcpy(pesect[PEOBJ_SECT_RDATA_Z].name, ".rdata$Z", sizeof(".rdata$Z")-1); | 222 | memcpy(pesect[PEOBJ_SECT_RDATA_Z].name, ".rdata$Z", sizeof(".rdata$Z")-1); |
@@ -232,7 +241,7 @@ void emit_peobj(BuildCtx *ctx) | |||
232 | nrsym = ctx->nrelocsym; | 241 | nrsym = ctx->nrelocsym; |
233 | pehdr.nsyms = 1+PEOBJ_NSECTIONS*2 + 1+ctx->nsym + nrsym; | 242 | pehdr.nsyms = 1+PEOBJ_NSECTIONS*2 + 1+ctx->nsym + nrsym; |
234 | #if LJ_TARGET_X64 | 243 | #if LJ_TARGET_X64 |
235 | pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win64. */ | 244 | pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win. */ |
236 | #endif | 245 | #endif |
237 | 246 | ||
238 | /* Write PE object header and all sections. */ | 247 | /* Write PE object header and all sections. */ |
@@ -312,6 +321,19 @@ void emit_peobj(BuildCtx *ctx) | |||
312 | reloc.type = PEOBJ_RELOC_ADDR32NB; | 321 | reloc.type = PEOBJ_RELOC_ADDR32NB; |
313 | owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); | 322 | owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); |
314 | } | 323 | } |
324 | #elif LJ_TARGET_X86 | ||
325 | /* Write .sxdata section. */ | ||
326 | for (i = 0; i < nrsym; i++) { | ||
327 | if (!strcmp(ctx->relocsym[i], "_lj_err_unwind_win")) { | ||
328 | uint32_t symidx = 1+2+i; | ||
329 | owrite(ctx, &symidx, 4); | ||
330 | break; | ||
331 | } | ||
332 | } | ||
333 | if (i == nrsym) { | ||
334 | fprintf(stderr, "Error: extern lj_err_unwind_win not used\n"); | ||
335 | exit(1); | ||
336 | } | ||
315 | #endif | 337 | #endif |
316 | 338 | ||
317 | /* Write .rdata$Z section. */ | 339 | /* Write .rdata$Z section. */ |
@@ -333,8 +355,10 @@ void emit_peobj(BuildCtx *ctx) | |||
333 | #if LJ_TARGET_X64 | 355 | #if LJ_TARGET_X64 |
334 | emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_PDATA); | 356 | emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_PDATA); |
335 | emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_XDATA); | 357 | emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_XDATA); |
336 | emit_peobj_sym(ctx, "lj_err_unwind_win64", 0, | 358 | emit_peobj_sym(ctx, "lj_err_unwind_win", 0, |
337 | PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN); | 359 | PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN); |
360 | #elif LJ_TARGET_X86 | ||
361 | emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_SXDATA); | ||
338 | #endif | 362 | #endif |
339 | 363 | ||
340 | emit_peobj_sym(ctx, ctx->beginsym, 0, | 364 | emit_peobj_sym(ctx, ctx->beginsym, 0, |