aboutsummaryrefslogtreecommitdiff
path: root/src/host/buildvm_peobj.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/host/buildvm_peobj.c')
-rw-r--r--src/host/buildvm_peobj.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/src/host/buildvm_peobj.c b/src/host/buildvm_peobj.c
index 17b3293a..28b771a3 100644
--- a/src/host/buildvm_peobj.c
+++ b/src/host/buildvm_peobj.c
@@ -9,7 +9,7 @@
9#include "buildvm.h" 9#include "buildvm.h"
10#include "lj_bc.h" 10#include "lj_bc.h"
11 11
12#if LJ_TARGET_X86ORX64 12#if LJ_TARGET_X86ORX64 || LJ_TARGET_PPC
13 13
14/* Context for PE object emitter. */ 14/* Context for PE object emitter. */
15static char *strtab; 15static char *strtab;
@@ -84,11 +84,21 @@ 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_RELOC_OFS 0
88#define PEOBJ_TEXT_FLAGS 0x60500020 /* 60=r+x, 50=align16, 20=code. */
87#elif LJ_TARGET_X64 89#elif LJ_TARGET_X64
88#define PEOBJ_ARCH_TARGET 0x8664 90#define PEOBJ_ARCH_TARGET 0x8664
89#define PEOBJ_RELOC_REL32 0x04 /* MS: REL32, GNU: DISP32. */ 91#define PEOBJ_RELOC_REL32 0x04 /* MS: REL32, GNU: DISP32. */
90#define PEOBJ_RELOC_DIR32 0x02 92#define PEOBJ_RELOC_DIR32 0x02
91#define PEOBJ_RELOC_ADDR32NB 0x03 93#define PEOBJ_RELOC_ADDR32NB 0x03
94#define PEOBJ_RELOC_OFS 0
95#define PEOBJ_TEXT_FLAGS 0x60500020 /* 60=r+x, 50=align16, 20=code. */
96#elif LJ_TARGET_PPC
97#define PEOBJ_ARCH_TARGET 0x01f2
98#define PEOBJ_RELOC_REL32 0x06
99#define PEOBJ_RELOC_DIR32 0x02
100#define PEOBJ_RELOC_OFS (-4)
101#define PEOBJ_TEXT_FLAGS 0x60400020 /* 60=r+x, 40=align8, 20=code. */
92#endif 102#endif
93 103
94/* Section numbers (0-based). */ 104/* Section numbers (0-based). */
@@ -170,12 +180,6 @@ void emit_peobj(BuildCtx *ctx)
170 int i, nrsym; 180 int i, nrsym;
171 union { uint8_t b; uint32_t u; } host_endian; 181 union { uint8_t b; uint32_t u; } host_endian;
172 182
173 host_endian.u = 1;
174 if (host_endian.b != LJ_ENDIAN_SELECT(1, 0)) {
175 fprintf(stderr, "Error: different byte order for host and target\n");
176 exit(1);
177 }
178
179 sofs = sizeof(PEheader) + PEOBJ_NSECTIONS*sizeof(PEsection); 183 sofs = sizeof(PEheader) + PEOBJ_NSECTIONS*sizeof(PEsection);
180 184
181 /* Fill in PE sections. */ 185 /* Fill in PE sections. */
@@ -186,7 +190,7 @@ void emit_peobj(BuildCtx *ctx)
186 pesect[PEOBJ_SECT_TEXT].relocofs = sofs; 190 pesect[PEOBJ_SECT_TEXT].relocofs = sofs;
187 sofs += (pesect[PEOBJ_SECT_TEXT].nreloc = (uint16_t)ctx->nreloc) * PEOBJ_RELOC_SIZE; 191 sofs += (pesect[PEOBJ_SECT_TEXT].nreloc = (uint16_t)ctx->nreloc) * PEOBJ_RELOC_SIZE;
188 /* Flags: 60 = read+execute, 50 = align16, 20 = code. */ 192 /* Flags: 60 = read+execute, 50 = align16, 20 = code. */
189 pesect[PEOBJ_SECT_TEXT].flags = 0x60500020; 193 pesect[PEOBJ_SECT_TEXT].flags = PEOBJ_TEXT_FLAGS;
190 194
191#if LJ_TARGET_X64 195#if LJ_TARGET_X64
192 memcpy(pesect[PEOBJ_SECT_PDATA].name, ".pdata", sizeof(".pdata")-1); 196 memcpy(pesect[PEOBJ_SECT_PDATA].name, ".pdata", sizeof(".pdata")-1);
@@ -236,10 +240,22 @@ void emit_peobj(BuildCtx *ctx)
236 owrite(ctx, &pesect, sizeof(PEsection)*PEOBJ_NSECTIONS); 240 owrite(ctx, &pesect, sizeof(PEsection)*PEOBJ_NSECTIONS);
237 241
238 /* Write .text section. */ 242 /* Write .text section. */
243 host_endian.u = 1;
244 if (host_endian.b != LJ_ENDIAN_SELECT(1, 0)) {
245#if LJ_TARGET_PPC
246 uint32_t *p = (uint32_t *)ctx->code;
247 int n = (int)(ctx->codesz >> 2);
248 for (i = 0; i < n; i++, p++)
249 *p = lj_bswap(*p); /* Byteswap .text section. */
250#else
251 fprintf(stderr, "Error: different byte order for host and target\n");
252 exit(1);
253#endif
254 }
239 owrite(ctx, ctx->code, ctx->codesz); 255 owrite(ctx, ctx->code, ctx->codesz);
240 for (i = 0; i < ctx->nreloc; i++) { 256 for (i = 0; i < ctx->nreloc; i++) {
241 PEreloc reloc; 257 PEreloc reloc;
242 reloc.vaddr = (uint32_t)ctx->reloc[i].ofs; 258 reloc.vaddr = (uint32_t)ctx->reloc[i].ofs + PEOBJ_RELOC_OFS;
243 reloc.symidx = 1+2+ctx->reloc[i].sym; /* Reloc syms are after .text sym. */ 259 reloc.symidx = 1+2+ctx->reloc[i].sym; /* Reloc syms are after .text sym. */
244 reloc.type = ctx->reloc[i].type ? PEOBJ_RELOC_REL32 : PEOBJ_RELOC_DIR32; 260 reloc.type = ctx->reloc[i].type ? PEOBJ_RELOC_REL32 : PEOBJ_RELOC_DIR32;
245 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE); 261 owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);