History

64bit: Fix addends > 32 bits

If a symbolic reference is offsetted by a constant > 32bit the backends can't deal with that, so don't construct such values.

Michael Matz committed 10 years ago

Commit 235711f1 parent a2a596e3 files · +27 −2Browse files

Unified · Split

3 files
  1. tccgen.c +6 −1
  2. tests/tcctest.c +16 −0
  3. x86_64-gen.c +5 −1
tccgen.c+6−1
@@ -1775,8 +1775,13 @@ static void gen_opic(int op) · 1774 unmodified lines
17751775 /* symbol + constant case */
17761776 if (op == '-')
17771777 l2 = -l2;
1778+ l2 += vtop[-1].c.i;
1779+ /* The backends can't always deal with addends to symbols
1780+ larger than +-1<<31. Don't construct such. */
1781+ if ((int)l2 != l2)
1782+ goto general_case;
17781783 vtop--;
1779− vtop->c.i += l2;
1784+ vtop->c.i = l2;
17801785 } else {
17811786 general_case:
17821787 if (!nocode_wanted) {
tests/tcctest.c+16−0
@@ -2429,6 +2429,19 @@ void getmyaddress(void) · 2428 unmodified lines
24292429 {
24302430 printf("in getmyaddress\n");
24312431 }
2432+
2433+#ifdef __LP64__
2434+long __pa_symbol(void)
2435+{
2436+ /* This 64bit constant was handled incorrectly, it was used as addend
2437+ (which can hold 64bit just fine) in connection with a symbol,
2438+ and TCC generates wrong code for that (displacements are 32bit only).
2439+ This effectively is "+ 0x80000000", and if addresses of globals
2440+ are below 2GB the result should be a number without high 32 bits set. */
2441+ return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL));
2442+}
2443+#endif
2444+
24322445 unsigned long theaddress = (unsigned long)getmyaddress;
24332446 void relocation_test(void)
24342447 {
@@ -2436,6 +2449,9 @@ void relocation_test(void) · 1 unmodified line
24362449 printf("*rel1=%d\n", *rel1);
24372450 printf("*rel2=%d\n", *rel2);
24382451 fptr();
2452+#ifdef __LP64__
2453+ printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
2454+#endif
24392455 }
24402456
24412457 void old_style_f(a,b,c)
x86_64-gen.c+5−1
@@ -349,6 +349,8 @@ void load(int r, SValue *sv) · 348 unmodified lines
349349 fr = sv->r;
350350 ft = sv->type.t & ~VT_DEFSIGN;
351351 fc = sv->c.i;
352+ if (fc != sv->c.i && (fr & VT_SYM))
353+ tcc_error("64 bit addend in load");
352354
353355 ft &= ~(VT_VOLATILE | VT_CONSTANT);
354356
@@ -528,9 +530,11 @@ void store(int r, SValue *v) · 173 unmodified lines
528530 v = pe_getimport(v, &v2);
529531 #endif
530532
533+ fr = v->r & VT_VALMASK;
531534 ft = v->type.t;
532535 fc = v->c.i;
533− fr = v->r & VT_VALMASK;
536+ if (fc != v->c.i && (fr & VT_SYM))
537+ tcc_error("64 bit addend in store");
534538 ft &= ~(VT_VOLATILE | VT_CONSTANT);
535539 bt = ft & VT_BTYPE;
536540

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t