diff options
Diffstat (limited to 'src/buildvm_peobj.c')
-rw-r--r-- | src/buildvm_peobj.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/src/buildvm_peobj.c b/src/buildvm_peobj.c index b97a5b03..eb1d345f 100644 --- a/src/buildvm_peobj.c +++ b/src/buildvm_peobj.c | |||
@@ -191,15 +191,15 @@ void emit_peobj(BuildCtx *ctx) | |||
191 | #if LJ_TARGET_X64 | 191 | #if LJ_TARGET_X64 |
192 | memcpy(pesect[PEOBJ_SECT_PDATA].name, ".pdata", sizeof(".pdata")-1); | 192 | memcpy(pesect[PEOBJ_SECT_PDATA].name, ".pdata", sizeof(".pdata")-1); |
193 | pesect[PEOBJ_SECT_PDATA].ofs = sofs; | 193 | pesect[PEOBJ_SECT_PDATA].ofs = sofs; |
194 | sofs += (pesect[PEOBJ_SECT_PDATA].size = 3*4); | 194 | sofs += (pesect[PEOBJ_SECT_PDATA].size = 6*4); |
195 | pesect[PEOBJ_SECT_PDATA].relocofs = sofs; | 195 | pesect[PEOBJ_SECT_PDATA].relocofs = sofs; |
196 | sofs += (pesect[PEOBJ_SECT_PDATA].nreloc = 3) * PEOBJ_RELOC_SIZE; | 196 | sofs += (pesect[PEOBJ_SECT_PDATA].nreloc = 6) * PEOBJ_RELOC_SIZE; |
197 | /* Flags: 40 = read, 30 = align4, 40 = initialized data. */ | 197 | /* Flags: 40 = read, 30 = align4, 40 = initialized data. */ |
198 | pesect[PEOBJ_SECT_PDATA].flags = 0x40300040; | 198 | pesect[PEOBJ_SECT_PDATA].flags = 0x40300040; |
199 | 199 | ||
200 | memcpy(pesect[PEOBJ_SECT_XDATA].name, ".xdata", sizeof(".xdata")-1); | 200 | memcpy(pesect[PEOBJ_SECT_XDATA].name, ".xdata", sizeof(".xdata")-1); |
201 | pesect[PEOBJ_SECT_XDATA].ofs = sofs; | 201 | pesect[PEOBJ_SECT_XDATA].ofs = sofs; |
202 | sofs += (pesect[PEOBJ_SECT_XDATA].size = 8*2+4); /* See below. */ | 202 | sofs += (pesect[PEOBJ_SECT_XDATA].size = 8*2+4+6*2); /* See below. */ |
203 | pesect[PEOBJ_SECT_XDATA].relocofs = sofs; | 203 | pesect[PEOBJ_SECT_XDATA].relocofs = sofs; |
204 | sofs += (pesect[PEOBJ_SECT_XDATA].nreloc = 1) * PEOBJ_RELOC_SIZE; | 204 | sofs += (pesect[PEOBJ_SECT_XDATA].nreloc = 1) * PEOBJ_RELOC_SIZE; |
205 | /* Flags: 40 = read, 30 = align4, 40 = initialized data. */ | 205 | /* Flags: 40 = read, 30 = align4, 40 = initialized data. */ |
@@ -247,9 +247,12 @@ void emit_peobj(BuildCtx *ctx) | |||
247 | 247 | ||
248 | #if LJ_TARGET_X64 | 248 | #if LJ_TARGET_X64 |
249 | { /* Write .pdata section. */ | 249 | { /* Write .pdata section. */ |
250 | uint32_t fcofs = (uint32_t)ctx->sym[ctx->nsym-1].ofs; | ||
250 | uint32_t pdata[3]; /* Start of .text, end of .text and .xdata. */ | 251 | uint32_t pdata[3]; /* Start of .text, end of .text and .xdata. */ |
251 | PEreloc reloc; | 252 | PEreloc reloc; |
252 | pdata[0] = 0; pdata[1] = (uint32_t)ctx->codesz; pdata[2] = 0; | 253 | pdata[0] = 0; pdata[1] = fcofs; pdata[2] = 0; |
254 | owrite(ctx, &pdata, sizeof(pdata)); | ||
255 | pdata[0] = fcofs; pdata[1] = (uint32_t)ctx->codesz; pdata[2] = 20; | ||
253 | owrite(ctx, &pdata, sizeof(pdata)); | 256 | owrite(ctx, &pdata, sizeof(pdata)); |
254 | reloc.vaddr = 0; reloc.symidx = 1+2+nrsym+2+2+1; | 257 | reloc.vaddr = 0; reloc.symidx = 1+2+nrsym+2+2+1; |
255 | reloc.type = PEOBJ_RELOC_ADDR32NB; | 258 | reloc.type = PEOBJ_RELOC_ADDR32NB; |
@@ -260,12 +263,21 @@ void emit_peobj(BuildCtx *ctx) | |||
260 | reloc.vaddr = 8; reloc.symidx = 1+2+nrsym+2; | 263 | reloc.vaddr = 8; reloc.symidx = 1+2+nrsym+2; |
261 | reloc.type = PEOBJ_RELOC_ADDR32NB; | 264 | reloc.type = PEOBJ_RELOC_ADDR32NB; |
262 | owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); | 265 | owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); |
266 | reloc.vaddr = 12; reloc.symidx = 1+2+nrsym+2+2+1; | ||
267 | reloc.type = PEOBJ_RELOC_ADDR32NB; | ||
268 | owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); | ||
269 | reloc.vaddr = 16; reloc.symidx = 1+2+nrsym+2+2+1; | ||
270 | reloc.type = PEOBJ_RELOC_ADDR32NB; | ||
271 | owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); | ||
272 | reloc.vaddr = 20; reloc.symidx = 1+2+nrsym+2; | ||
273 | reloc.type = PEOBJ_RELOC_ADDR32NB; | ||
274 | owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); | ||
263 | } | 275 | } |
264 | { /* Write .xdata section. */ | 276 | { /* Write .xdata section. */ |
265 | uint16_t xdata[8+2]; | 277 | uint16_t xdata[8+2+6]; |
266 | PEreloc reloc; | 278 | PEreloc reloc; |
267 | xdata[0] = 0x01|0x08|0x10; /* Ver. 1, uhander/ehandler, prolog size 0. */ | 279 | xdata[0] = 0x01|0x08|0x10; /* Ver. 1, uhandler/ehandler, prolog size 0. */ |
268 | xdata[1] = 5; /* Number of unwind codes, no frame pointer. */ | 280 | xdata[1] = 0x0005; /* Number of unwind codes, no frame pointer. */ |
269 | xdata[2] = 0x4200; /* Stack offset 4*8+8 = aword*5. */ | 281 | xdata[2] = 0x4200; /* Stack offset 4*8+8 = aword*5. */ |
270 | xdata[3] = 0x3000; /* Push rbx. */ | 282 | xdata[3] = 0x3000; /* Push rbx. */ |
271 | xdata[4] = 0x6000; /* Push rsi. */ | 283 | xdata[4] = 0x6000; /* Push rsi. */ |
@@ -273,8 +285,14 @@ void emit_peobj(BuildCtx *ctx) | |||
273 | xdata[6] = 0x5000; /* Push rbp. */ | 285 | xdata[6] = 0x5000; /* Push rbp. */ |
274 | xdata[7] = 0; /* Alignment. */ | 286 | xdata[7] = 0; /* Alignment. */ |
275 | xdata[8] = xdata[9] = 0; /* Relocated address of exception handler. */ | 287 | xdata[8] = xdata[9] = 0; /* Relocated address of exception handler. */ |
288 | xdata[10] = 0x01; /* Ver. 1, no handler, prolog size 0. */ | ||
289 | xdata[11] = 0x1504; /* Number of unwind codes, fp = rbp, fpofs = 16. */ | ||
290 | xdata[12] = 0x0300; /* set_fpreg. */ | ||
291 | xdata[13] = 0x0200; /* stack offset 0*8+8 = aword*1. */ | ||
292 | xdata[14] = 0x3000; /* Push rbx. */ | ||
293 | xdata[15] = 0x5000; /* Push rbp. */ | ||
276 | owrite(ctx, &xdata, sizeof(xdata)); | 294 | owrite(ctx, &xdata, sizeof(xdata)); |
277 | reloc.vaddr = sizeof(xdata)-4; reloc.symidx = 1+2+nrsym+2+2; | 295 | reloc.vaddr = 2*8; reloc.symidx = 1+2+nrsym+2+2; |
278 | reloc.type = PEOBJ_RELOC_ADDR32NB; | 296 | reloc.type = PEOBJ_RELOC_ADDR32NB; |
279 | owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); | 297 | owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); |
280 | } | 298 | } |