diff options
| author | Mike Pall <mike> | 2016-05-07 12:32:15 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2016-05-07 12:32:15 +0200 |
| commit | 35b09e692ead67181755795352f1df12547fd4fa (patch) | |
| tree | d120dd561f649f955ddbbe844fe00a97f7b9e625 /src/host | |
| parent | 6a9973203c55daa4c1fcd611718bc5df09e4e5b5 (diff) | |
| download | luajit-35b09e692ead67181755795352f1df12547fd4fa.tar.gz luajit-35b09e692ead67181755795352f1df12547fd4fa.tar.bz2 luajit-35b09e692ead67181755795352f1df12547fd4fa.zip | |
Windows/x86: Add full exception interoperability.
Contributed by Peter Cawley.
Diffstat (limited to 'src/host')
| -rw-r--r-- | src/host/buildvm.c | 2 | ||||
| -rw-r--r-- | src/host/buildvm_peobj.c | 28 |
2 files changed, 27 insertions, 3 deletions
diff --git a/src/host/buildvm.c b/src/host/buildvm.c index 6d9e09e1..57b4dc97 100644 --- a/src/host/buildvm.c +++ b/src/host/buildvm.c | |||
| @@ -110,7 +110,7 @@ static const char *sym_decorate(BuildCtx *ctx, | |||
| 110 | if (p) { | 110 | if (p) { |
| 111 | #if LJ_TARGET_X86ORX64 | 111 | #if LJ_TARGET_X86ORX64 |
| 112 | if (!LJ_64 && (ctx->mode == BUILD_coffasm || ctx->mode == BUILD_peobj)) | 112 | if (!LJ_64 && (ctx->mode == BUILD_coffasm || ctx->mode == BUILD_peobj)) |
| 113 | name[0] = '@'; | 113 | name[0] = name[1] == 'R' ? '_' : '@'; /* Just for _RtlUnwind@16. */ |
| 114 | else | 114 | else |
| 115 | *p = '\0'; | 115 | *p = '\0'; |
| 116 | #elif LJ_TARGET_PPC && !LJ_TARGET_CONSOLE | 116 | #elif LJ_TARGET_PPC && !LJ_TARGET_CONSOLE |
diff --git a/src/host/buildvm_peobj.c b/src/host/buildvm_peobj.c index e8c927d8..42f6ac84 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, |
