diff --git a/arm64-gen.c b/arm64-gen.c index d43b50d..8276451 100644 --- a/arm64-gen.c +++ b/arm64-gen.c @@ -110,7 +110,7 @@ ST_FUNC void o(unsigned int c) int ind1 = ind + 4; if (ind1 > cur_text_section->data_allocated) section_realloc(cur_text_section, ind1); - *(uint32_t *)(cur_text_section->data + ind) = c; + write32le(cur_text_section->data + ind, c); ind = ind1; } @@ -237,12 +237,12 @@ ST_FUNC void gsym_addr(int t_, int a_) uint32_t t = t_; uint32_t a = a_; while (t) { - uint32_t *ptr = (uint32_t *)(cur_text_section->data + t); - uint32_t next = *ptr; + unsigned char *ptr = cur_text_section->data + t; + uint32_t next = read32le(ptr); if (a - t + 0x8000000 >= 0x10000000) tcc_error("branch out of range"); - *ptr = (a - t == 4 ? 0xd503201f : // nop - 0x14000000 | ((a - t) >> 2 & 0x3ffffff)); // b + write32le(ptr, (a - t == 4 ? 0xd503201f : // nop + 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b t = next; } } @@ -1177,8 +1177,7 @@ ST_FUNC void gen_va_arg(CType *t) o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack b2 = ind; o(0x14000000); // b lab2 // lab1: - *(uint32_t *)(cur_text_section->data + b1) = - (0x5400000d | (ind - b1) << 3); + write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3); o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs o(0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top if (hfa == 1 || fsize == 16) @@ -1198,8 +1197,7 @@ ST_FUNC void gen_va_arg(CType *t) (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)] } // lab2: - *(uint32_t *)(cur_text_section->data + b2) = - (0x14000000 | (ind - b2) >> 2); + write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2); } } @@ -1259,14 +1257,13 @@ ST_FUNC void gfunc_epilog(void) { if (loc) { // Insert instructions to subtract size of stack frame from SP. - uint32_t *ptr = - (uint32_t *)(cur_text_section->data + arm64_func_sub_sp_offset); + unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset; uint64_t diff = (-loc + 15) & ~15; if (!(diff >> 24)) { if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff) - ptr[0] = 0xd10003ff | (diff & 0xfff) << 10; + write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10); if (diff >> 12) // sub sp,sp,#(diff >> 12),lsl #12 - ptr[1] = 0xd14003ff | (diff >> 12) << 10; + write32le(ptr + 4, 0xd14003ff | (diff >> 12) << 10); } else { // In this case we may subtract more than necessary, @@ -1281,9 +1278,9 @@ ST_FUNC void gfunc_epilog(void) diff = (diff + 1) >> 1; ++j; } - ptr[0] = 0xd2800010 | diff << 5 | i << 21; + write32le(ptr, 0xd2800010 | diff << 5 | i << 21); // mov x16,#(diff),lsl #(16 * i) - ptr[1] = 0xcb3063ff | j << 10; + write32le(ptr + 4, 0xcb3063ff | j << 10); // sub sp,sp,x16,lsl #(j) } } @@ -1805,8 +1802,7 @@ ST_FUNC void gen_clear_cache(void) lab1 = ind; o(0xd50b7b20 | p); // dc cvau,x(p) o(0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz) - *(uint32_t *)(cur_text_section->data + b1) = - (0x14000000 | (ind - b1) >> 2); + write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2); o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end) o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1 o(0xd5033b9f); // dsb ish @@ -1816,8 +1812,7 @@ ST_FUNC void gen_clear_cache(void) lab1 = ind; o(0xd50b7520 | p); // ic ivau,x(p) o(0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz) - *(uint32_t *)(cur_text_section->data + b1) = - (0x14000000 | (ind - b1) >> 2); + write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2); o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end) o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1 o(0xd5033b9f); // dsb ish diff --git a/i386-gen.c b/i386-gen.c index 993293e..d202925 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -138,11 +138,10 @@ ST_FUNC void gen_le32(int c) /* output a symbol and patch all calls to it */ ST_FUNC void gsym_addr(int t, int a) { - int n, *ptr; while (t) { - ptr = (int *)(cur_text_section->data + t); - n = *ptr; /* next value */ - *ptr = a - t - 4; + unsigned char *ptr = cur_text_section->data + t; + uint32_t n = read32le(ptr); /* next value */ + write32le(ptr, a - t - 4); t = n; } } @@ -165,7 +164,7 @@ ST_FUNC int oad(int c, int s) ind1 = ind + 4; if (ind1 > cur_text_section->data_allocated) section_realloc(cur_text_section, ind1); - *(int *)(cur_text_section->data + ind) = s; + write32le(cur_text_section->data + ind, s); s = ind; ind = ind1; return s; @@ -671,9 +670,7 @@ ST_FUNC void gjmp_addr(int a) /* generate a test. set 'inv' to invert test. Stack entry is popped */ ST_FUNC int gtst(int inv, int t) { - int v, t1, *p; - - v = vtop->r & VT_VALMASK; + int v = vtop->r & VT_VALMASK; if (v == VT_CMP) { /* fast case : can jump directly since flags are set */ g(0x0f); @@ -681,14 +678,12 @@ ST_FUNC int gtst(int inv, int t) } else if (v == VT_JMP || v == VT_JMPI) { /* && or || optimization */ if ((v & 1) == inv) { + uint32_t n1, n = vtop->c.i; /* insert vtop->c jump list in t */ - t1 = vtop->c.i; - p = &t1; - while (*p != 0) - p = (int *)(cur_text_section->data + *p); - *p = t; - vtop->c.i = t1; - t = t1; + while ((n1 = read32le(cur_text_section->data + n))) + n = n1; + write32le(cur_text_section->data + n, t); + t = vtop->c.i; } else { t = gjmp(t); gsym(vtop->c.i); diff --git a/tcc.h b/tcc.h index ff846fd..1be6be7 100644 --- a/tcc.h +++ b/tcc.h @@ -131,6 +131,51 @@ #include "stab.h" #include "libtcc.h" +static inline uint16_t read16le(unsigned char *p) +{ + return p[0] | (uint16_t)p[1] << 8; +} + +static inline void write16le(unsigned char *p, uint16_t x) +{ + p[0] = x & 255; + p[1] = x >> 8 & 255; +} + +static inline uint32_t read32le(unsigned char *p) +{ + return (p[0] | (uint32_t)p[1] << 8 | + (uint32_t)p[2] << 16 | (uint32_t)p[3] << 24); +} + +static inline void write32le(unsigned char *p, uint32_t x) +{ + p[0] = x & 255; + p[1] = x >> 8 & 255; + p[2] = x >> 16 & 255; + p[3] = x >> 24 & 255; +} + +static inline uint64_t read64le(unsigned char *p) +{ + return (p[0] | (uint64_t)p[1] << 8 | + (uint64_t)p[2] << 16 | (uint64_t)p[3] << 24 | + (uint64_t)p[4] << 32 | (uint64_t)p[5] << 40 | + (uint64_t)p[6] << 48 | (uint64_t)p[7] << 56); +} + +static inline void write64le(unsigned char *p, uint64_t x) +{ + p[0] = x & 255; + p[1] = x >> 8 & 255; + p[2] = x >> 16 & 255; + p[3] = x >> 24 & 255; + p[4] = x >> 32 & 255; + p[5] = x >> 40 & 255; + p[6] = x >> 48 & 255; + p[7] = x >> 56 & 255; +} + /* parser debug */ /* #define PARSE_DEBUG */ /* preprocessor debug */ diff --git a/tccelf.c b/tccelf.c index 60320be..7b29bd6 100644 --- a/tccelf.c +++ b/tccelf.c @@ -528,7 +528,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) qrel++; } } - *(int *)ptr += val; + write32le(ptr, read32le(ptr) + val); break; case R_386_PC32: if (s1->output_type == TCC_OUTPUT_DLL) { @@ -541,36 +541,36 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) break; } } - *(int *)ptr += val - addr; + write32le(ptr, read32le(ptr) + val - addr); break; case R_386_PLT32: - *(int *)ptr += val - addr; + write32le(ptr, read32le(ptr) + val - addr); break; case R_386_GLOB_DAT: case R_386_JMP_SLOT: - *(int *)ptr = val; + write32le(ptr, val); break; case R_386_GOTPC: - *(int *)ptr += s1->got->sh_addr - addr; + write32le(ptr, read32le(ptr) + s1->got->sh_addr - addr); break; case R_386_GOTOFF: - *(int *)ptr += val - s1->got->sh_addr; + write32le(ptr, read32le(ptr) + val - s1->got->sh_addr); break; case R_386_GOT32: /* we load the got offset */ - *(int *)ptr += s1->sym_attrs[sym_index].got_offset; + write32le(ptr, read32le(ptr) + s1->sym_attrs[sym_index].got_offset); break; case R_386_16: if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { output_file: tcc_error("can only produce 16-bit binary files"); } - *(short *)ptr += val; + write16le(ptr, read16le(ptr) + val); break; case R_386_PC16: if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) goto output_file; - *(short *)ptr += val - addr; + write16le(ptr, read16le(ptr) + val - addr); break; #elif defined(TCC_TARGET_ARM) case R_ARM_PC24: @@ -762,38 +762,38 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) break; #elif defined(TCC_TARGET_ARM64) case R_AARCH64_ABS64: - *(uint64_t *)ptr = val; + write64le(ptr, val); break; case R_AARCH64_ABS32: - *(uint32_t *)ptr = val; + write32le(ptr, val); break; case R_AARCH64_MOVW_UABS_G0_NC: - *(uint32_t *)ptr = (*(uint32_t *)ptr & 0xffe0001f) | - (val & 0xffff) << 5; + write32le(ptr, ((read32le(ptr) & 0xffe0001f) | + (val & 0xffff) << 5)); break; case R_AARCH64_MOVW_UABS_G1_NC: - *(uint32_t *)ptr = (*(uint32_t *)ptr & 0xffe0001f) | - (val >> 16 & 0xffff) << 5; + write32le(ptr, ((read32le(ptr) & 0xffe0001f) | + (val >> 16 & 0xffff) << 5)); break; case R_AARCH64_MOVW_UABS_G2_NC: - *(uint32_t *)ptr = (*(uint32_t *)ptr & 0xffe0001f) | - (val >> 32 & 0xffff) << 5; + write32le(ptr, ((read32le(ptr) & 0xffe0001f) | + (val >> 32 & 0xffff) << 5)); break; case R_AARCH64_MOVW_UABS_G3: - *(uint32_t *)ptr = (*(uint32_t *)ptr & 0xffe0001f) | - (val >> 48 & 0xffff) << 5; + write32le(ptr, ((read32le(ptr) & 0xffe0001f) | + (val >> 48 & 0xffff) << 5)); break; case R_AARCH64_ADR_PREL_PG_HI21: { uint64_t off = (val >> 12) - (addr >> 12); if ((off + ((uint64_t)1 << 20)) >> 21) tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed"); - *(uint32_t *)ptr = (*(uint32_t *)ptr & 0x9f00001f) | - (off & 0x1ffffc) << 3 | (off & 3) << 29; + write32le(ptr, ((read32le(ptr) & 0x9f00001f) | + (off & 0x1ffffc) << 3 | (off & 3) << 29)); break; } case R_AARCH64_ADD_ABS_LO12_NC: - *(uint32_t *)ptr = (*(uint32_t *)ptr & 0xffc003ff) | - (val & 0xfff) << 10; + write32le(ptr, ((read32le(ptr) & 0xffc003ff) | + (val & 0xfff) << 10)); break; case R_AARCH64_JUMP26: case R_AARCH64_CALL26: @@ -812,9 +812,9 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) { tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val); } - *(uint32_t *)ptr = 0x14000000 | - (uint32_t)(type == R_AARCH64_CALL26) << 31 | - ((val - addr) >> 2 & 0x3ffffff); + write32le(ptr, (0x14000000 | + (uint32_t)(type == R_AARCH64_CALL26) << 31 | + ((val - addr) >> 2 & 0x3ffffff))); break; case R_AARCH64_ADR_GOT_PAGE: { uint64_t off = @@ -822,14 +822,15 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) s1->sym_attrs[sym_index].got_offset) >> 12) - (addr >> 12)); if ((off + ((uint64_t)1 << 20)) >> 21) tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed"); - *(uint32_t *)ptr = (*(uint32_t *)ptr & 0x9f00001f) | - (off & 0x1ffffc) << 3 | (off & 3) << 29; + write32le(ptr, ((read32le(ptr) & 0x9f00001f) | + (off & 0x1ffffc) << 3 | (off & 3) << 29)); break; } case R_AARCH64_LD64_GOT_LO12_NC: - *(uint32_t *)ptr = (*(uint32_t *)ptr & 0xfff803ff) | - ((s1->got->sh_addr + s1->sym_attrs[sym_index].got_offset) - & 0xff8) << 7; + write32le(ptr, + ((read32le(ptr) & 0xfff803ff) | + ((s1->got->sh_addr + + s1->sym_attrs[sym_index].got_offset) & 0xff8) << 7)); break; case R_AARCH64_COPY: break; @@ -841,7 +842,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) val - rel->r_addend, (char *) symtab_section->link->data + sym->st_name); #endif - *(addr_t *)ptr = val - rel->r_addend; + write64le(ptr, val - rel->r_addend); break; default: fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n", @@ -885,11 +886,11 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) break; } else { qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); - qrel->r_addend = *(long long *)ptr + val; + qrel->r_addend = read64le(ptr) + val; qrel++; } } - *(long long *)ptr += val; + write64le(ptr, read64le(ptr) + val); break; case R_X86_64_32: case R_X86_64_32S: @@ -897,10 +898,10 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) /* XXX: this logic may depend on TCC's codegen now TCC uses R_X86_64_32 even for a 64bit pointer */ qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); - qrel->r_addend = *(int *)ptr + val; + qrel->r_addend = read32le(ptr) + val; qrel++; } - *(int *)ptr += val; + write32le(ptr, read32le(ptr) + val); break; case R_X86_64_PC32: @@ -910,7 +911,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) if (esym_index) { qrel->r_offset = rel->r_offset; qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32); - qrel->r_addend = *(int *)ptr; + qrel->r_addend = read32le(ptr); qrel++; break; } @@ -931,24 +932,25 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) if (diff < -2147483648LL || diff > 2147483647LL) { tcc_error("internal error: relocation failed"); } - *(int *)ptr += diff; + write32le(ptr, read32le(ptr) + diff); } break; case R_X86_64_GLOB_DAT: case R_X86_64_JUMP_SLOT: /* They don't need addend */ - *(addr_t *)ptr = val - rel->r_addend; + write64le(ptr, val - rel->r_addend); break; case R_X86_64_GOTPCREL: - *(int *)ptr += (s1->got->sh_addr - addr + - s1->sym_attrs[sym_index].got_offset - 4); + write32le(ptr, read32le(ptr) + + (s1->got->sh_addr - addr + + s1->sym_attrs[sym_index].got_offset - 4)); break; case R_X86_64_GOTTPOFF: - *(int *)ptr += val - s1->got->sh_addr; + write32le(ptr, read32le(ptr) + val - s1->got->sh_addr); break; case R_X86_64_GOT32: /* we load the got offset */ - *(int *)ptr += s1->sym_attrs[sym_index].got_offset; + write32le(ptr, read32le(ptr) + s1->sym_attrs[sym_index].got_offset); break; #else #error unsupported processor @@ -1032,23 +1034,6 @@ static struct sym_attr *alloc_sym_attr(TCCState *s1, int index) return &s1->sym_attrs[index]; } -/* XXX: suppress that */ -static void put32(unsigned char *p, uint32_t val) -{ - p[0] = val; - p[1] = val >> 8; - p[2] = val >> 16; - p[3] = val >> 24; -} - -#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \ - defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) -static uint32_t get32(unsigned char *p) -{ - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); -} -#endif - static void build_got(TCCState *s1) { unsigned char *ptr; @@ -1061,19 +1046,19 @@ static void build_got(TCCState *s1) ptr = section_ptr_add(s1->got, 3 * PTR_SIZE); #if PTR_SIZE == 4 /* keep space for _DYNAMIC pointer, if present */ - put32(ptr, 0); + write32le(ptr, 0); /* two dummy got entries */ - put32(ptr + 4, 0); - put32(ptr + 8, 0); + write32le(ptr + 4, 0); + write32le(ptr + 8, 0); #else /* keep space for _DYNAMIC pointer, if present */ - put32(ptr, 0); - put32(ptr + 4, 0); + write32le(ptr, 0); + write32le(ptr + 4, 0); /* two dummy got entries */ - put32(ptr + 8, 0); - put32(ptr + 12, 0); - put32(ptr + 16, 0); - put32(ptr + 20, 0); + write32le(ptr + 8, 0); + write32le(ptr + 12, 0); + write32le(ptr + 16, 0); + write32le(ptr + 20, 0); #endif } @@ -1155,10 +1140,10 @@ static unsigned long put_got_entry(TCCState *s1, p = section_ptr_add(plt, 16); p[0] = 0xff; /* pushl got + PTR_SIZE */ p[1] = modrm + 0x10; - put32(p + 2, PTR_SIZE); + write32le(p + 2, PTR_SIZE); p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */ p[7] = modrm; - put32(p + 8, PTR_SIZE * 2); + write32le(p + 8, PTR_SIZE * 2); } /* The PLT slot refers to the relocation entry it needs @@ -1169,16 +1154,16 @@ static unsigned long put_got_entry(TCCState *s1, p = section_ptr_add(plt, 16); p[0] = 0xff; /* jmp *(got + x) */ p[1] = modrm; - put32(p + 2, s1->got->data_offset); + write32le(p + 2, s1->got->data_offset); p[6] = 0x68; /* push $xxx */ #ifdef TCC_TARGET_X86_64 /* On x86-64, the relocation is referred to by _index_. */ - put32(p + 7, relofs / sizeof (ElfW_Rel)); + write32le(p + 7, relofs / sizeof (ElfW_Rel)); #else - put32(p + 7, relofs); + write32le(p + 7, relofs); #endif p[11] = 0xe9; /* jmp plt_start */ - put32(p + 12, -(plt->data_offset)); + write32le(p + 12, -(plt->data_offset)); /* If this was an UNDEF symbol set the offset in the dynsymtab to the PLT slot, so that PC32 relocs to it @@ -1200,24 +1185,24 @@ static unsigned long put_got_entry(TCCState *s1, if (plt->data_offset == 0) { /* first plt entry */ p = section_ptr_add(plt, 16); - put32(p, 0xe52de004); /* push {lr} */ - put32(p+4, 0xe59fe010); /* ldr lr, [pc, #16] */ - put32(p+8, 0xe08fe00e); /* add lr, pc, lr */ - put32(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */ + write32le(p, 0xe52de004); /* push {lr} */ + write32le(p+4, 0xe59fe010); /* ldr lr, [pc, #16] */ + write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */ + write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */ } symattr->plt_offset = plt->data_offset; if (symattr->plt_thumb_stub) { p = section_ptr_add(plt, 20); - put32(p, 0x4778); /* bx pc */ - put32(p+2, 0x46c0); /* nop */ + write32le(p, 0x4778); /* bx pc */ + write32le(p+2, 0x46c0); /* nop */ p += 4; } else p = section_ptr_add(plt, 16); - put32(p, 0xe59fc004); /* ldr ip, [pc, #4] ; GOT entry offset */ - put32(p+4, 0xe08fc00c); /* add ip, pc, ip ; addr of GOT entry */ - put32(p+8, 0xe59cf000); /* ldr pc, [ip] ; jump to GOT entry */ - put32(p+12, s1->got->data_offset); /* GOT entry off once patched */ + write32le(p, 0xe59fc004); /* ldr ip, [pc, #4] ; GOT entry offset */ + write32le(p+4, 0xe08fc00c); /* add ip, pc, ip ; addr of GOT entry */ + write32le(p+8, 0xe59cf000); /* ldr pc, [ip] ; jump to GOT entry */ + write32le(p+12, s1->got->data_offset); /* GOT entry off once patched */ /* the symbol is modified so that it will be relocated to the PLT */ @@ -1237,8 +1222,8 @@ static unsigned long put_got_entry(TCCState *s1, section_ptr_add(plt, 32); symattr->plt_offset = plt->data_offset; p = section_ptr_add(plt, 16); - put32(p, s1->got->data_offset); - put32(p + 4, (uint64_t)s1->got->data_offset >> 32); + write32le(p, s1->got->data_offset); + write32le(p + 4, (uint64_t)s1->got->data_offset >> 32); if (sym->st_shndx == SHN_UNDEF) offset = plt->data_offset - 16; @@ -1381,9 +1366,9 @@ ST_FUNC void build_got_entries(TCCState *s1) text_section->data_offset + 4, R_ARM_JUMP24, sym_index); p = section_ptr_add(text_section, 8); - put32(p, 0x4778); /* bx pc */ - put32(p+2, 0x46c0); /* nop */ - put32(p+4, 0xeafffffe); /* b $sym */ + write32le(p, 0x4778); /* bx pc */ + write32le(p+2, 0x46c0); /* nop */ + write32le(p+4, 0xeafffffe); /* b $sym */ } #elif defined(TCC_TARGET_ARM64) //xx Other cases may be required here: @@ -1595,7 +1580,7 @@ ST_FUNC void tcc_add_bcheck(TCCState *s1) Section *init_section = find_section(s1, ".init"); unsigned char *pinit = section_ptr_add(init_section, 5); pinit[0] = 0xe8; - put32(pinit + 1, -4); + write32le(pinit + 1, -4); put_elf_reloc(symtab_section, init_section, init_section->data_offset - 4, R_386_PC32, sym_index); } @@ -1761,9 +1746,9 @@ ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) section_reserve(s1->got, offset + PTR_SIZE); #ifdef TCC_TARGET_X86_64 /* only works for x86-64 */ - put32(s1->got->data + offset + 4, sym->st_value >> 32); + write32le(s1->got->data + offset + 4, sym->st_value >> 32); #endif - put32(s1->got->data + offset, sym->st_value & 0xffffffff); + write32le(s1->got->data + offset, sym->st_value & 0xffffffff); } /* Perform relocation to GOT or PLT entries */ @@ -1930,20 +1915,20 @@ ST_FUNC void relocate_plt(TCCState *s1) p_end = p + s1->plt->data_offset; if (p < p_end) { #if defined(TCC_TARGET_I386) - put32(p + 2, get32(p + 2) + s1->got->sh_addr); - put32(p + 8, get32(p + 8) + s1->got->sh_addr); + write32le(p + 2, read32le(p + 2) + s1->got->sh_addr); + write32le(p + 8, read32le(p + 8) + s1->got->sh_addr); p += 16; while (p < p_end) { - put32(p + 2, get32(p + 2) + s1->got->sh_addr); + write32le(p + 2, read32le(p + 2) + s1->got->sh_addr); p += 16; } #elif defined(TCC_TARGET_X86_64) int x = s1->got->sh_addr - s1->plt->sh_addr - 6; - put32(p + 2, get32(p + 2) + x); - put32(p + 8, get32(p + 8) + x - 6); + write32le(p + 2, read32le(p + 2) + x); + write32le(p + 8, read32le(p + 8) + x - 6); p += 16; while (p < p_end) { - put32(p + 2, get32(p + 2) + x + s1->plt->data - p); + write32le(p + 2, read32le(p + 2) + x + s1->plt->data - p); p += 16; } #elif defined(TCC_TARGET_ARM) @@ -1951,9 +1936,9 @@ ST_FUNC void relocate_plt(TCCState *s1) x=s1->got->sh_addr - s1->plt->sh_addr - 12; p += 16; while (p < p_end) { - if (get32(p) == 0x46c04778) /* PLT Thumb stub present */ + if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */ p += 4; - put32(p + 12, x + get32(p + 12) + s1->plt->data - p); + write32le(p + 12, x + read32le(p + 12) + s1->plt->data - p); p += 16; } #elif defined(TCC_TARGET_ARM64) @@ -1962,32 +1947,32 @@ ST_FUNC void relocate_plt(TCCState *s1) uint64_t off = (got >> 12) - (plt >> 12); if ((off + ((uint32_t)1 << 20)) >> 21) tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt); - put32(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]! - put32(p + 4, (0x90000010 | // adrp x16,... - (off & 0x1ffffc) << 3 | (off & 3) << 29)); - put32(p + 8, (0xf9400211 | // ldr x17,[x16,#...] - (got & 0xff8) << 7)); - put32(p + 12, (0x91000210 | // add x16,x16,#... - (got & 0xfff) << 10)); - put32(p + 16, 0xd61f0220); // br x17 - put32(p + 20, 0xd503201f); // nop - put32(p + 24, 0xd503201f); // nop - put32(p + 28, 0xd503201f); // nop + write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]! + write32le(p + 4, (0x90000010 | // adrp x16,... + (off & 0x1ffffc) << 3 | (off & 3) << 29)); + write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...] + (got & 0xff8) << 7)); + write32le(p + 12, (0x91000210 | // add x16,x16,#... + (got & 0xfff) << 10)); + write32le(p + 16, 0xd61f0220); // br x17 + write32le(p + 20, 0xd503201f); // nop + write32le(p + 24, 0xd503201f); // nop + write32le(p + 28, 0xd503201f); // nop p += 32; while (p < p_end) { uint64_t pc = plt + (p - s1->plt->data); uint64_t addr = got + - (get32(p) | (uint64_t)get32(p + 4) << 32); + (read32le(p) | (uint64_t)read32le(p + 4) << 32); uint32_t off = (addr >> 12) - (pc >> 12); if ((off + ((uint32_t)1 << 20)) >> 21) tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc); - put32(p, (0x90000010 | // adrp x16,... - (off & 0x1ffffc) << 3 | (off & 3) << 29)); - put32(p + 4, (0xf9400211 | // ldr x17,[x16,#...] - (addr & 0xff8) << 7)); - put32(p + 8, (0x91000210 | // add x16,x16,#... - (addr & 0xfff) << 10)); - put32(p + 12, 0xd61f0220); // br x17 + write32le(p, (0x90000010 | // adrp x16,... + (off & 0x1ffffc) << 3 | (off & 3) << 29)); + write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...] + (addr & 0xff8) << 7)); + write32le(p + 8, (0x91000210 | // add x16,x16,#... + (addr & 0xfff) << 10)); + write32le(p + 12, 0xd61f0220); // br x17 p += 16; } #elif defined(TCC_TARGET_C67) @@ -2654,7 +2639,7 @@ static int elf_output_file(TCCState *s1, const char *filename) fill_dynamic(s1, &dyninf); /* put in GOT the dynamic section address and relocate PLT */ - put32(s1->got->data, dynamic->sh_addr); + write32le(s1->got->data, dynamic->sh_addr); if (file_type == TCC_OUTPUT_EXE #if defined(TCC_OUTPUT_DLL_WITH_PLT) || file_type == TCC_OUTPUT_DLL diff --git a/x86_64-gen.c b/x86_64-gen.c index 5394bf5..d8dfaab 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -214,11 +214,10 @@ void orex(int ll, int r, int r2, int b) /* output a symbol and patch all calls to it */ void gsym_addr(int t, int a) { - int n, *ptr; while (t) { - ptr = (int *)(cur_text_section->data + t); - n = *ptr; /* next value */ - *ptr = a - t - 4; + unsigned char *ptr = cur_text_section->data + t; + uint32_t n = read32le(ptr); /* next value */ + write32le(ptr, a - t - 4); t = n; } } @@ -248,7 +247,7 @@ ST_FUNC int oad(int c, int s) ind1 = ind + 4; if (ind1 > cur_text_section->data_allocated) section_realloc(cur_text_section, ind1); - *(int *)(cur_text_section->data + ind) = s; + write32le(cur_text_section->data + ind, s); s = ind; ind = ind1; return s; @@ -1691,9 +1690,7 @@ void gjmp_addr(int a) /* generate a test. set 'inv' to invert test. Stack entry is popped */ int gtst(int inv, int t) { - int v, t1, *p; - - v = vtop->r & VT_VALMASK; + int v = vtop->r & VT_VALMASK; if (v == VT_CMP) { /* fast case : can jump directly since flags are set */ if (vtop->c.i & 0x100) @@ -1719,14 +1716,12 @@ int gtst(int inv, int t) } else if (v == VT_JMP || v == VT_JMPI) { /* && or || optimization */ if ((v & 1) == inv) { + uint32_t n1, n = vtop->c.i; /* insert vtop->c jump list in t */ - t1 = vtop->c.i; - p = &t1; - while (*p != 0) - p = (int *)(cur_text_section->data + *p); - *p = t; - vtop->c.i = t1; - t = t1; + while ((n1 = read32le(cur_text_section->data + n))) + n = n1; + write32le(cur_text_section->data + n, t); + t = vtop->c.i; } else { t = gjmp(t); gsym(vtop->c.i);