If a symbolic reference is offsetted by a constant > 32bit the backends can't deal with that, so don't construct such values.
Unified · Split
| @@ -1775,8 +1775,13 @@ static void gen_opic(int op) · 1774 unmodified lines | |||
| 1775 | /* symbol + constant case */ | 1775 | /* symbol + constant case */ |
| 1776 | if (op == '-') | 1776 | if (op == '-') |
| 1777 | l2 = -l2; | 1777 | 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; | ||
| 1778 | vtop--; | 1783 | vtop--; |
| 1779 | vtop->c.i += l2; | 1784 | vtop->c.i = l2; |
| 1780 | } else { | 1785 | } else { |
| 1781 | general_case: | 1786 | general_case: |
| 1782 | if (!nocode_wanted) { | 1787 | if (!nocode_wanted) { |
| @@ -2429,6 +2429,19 @@ void getmyaddress(void) · 2428 unmodified lines | |||
| 2429 | { | 2429 | { |
| 2430 | printf("in getmyaddress\n"); | 2430 | printf("in getmyaddress\n"); |
| 2431 | } | 2431 | } |
| 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 | |||
| 2432 | unsigned long theaddress = (unsigned long)getmyaddress; | 2445 | unsigned long theaddress = (unsigned long)getmyaddress; |
| 2433 | void relocation_test(void) | 2446 | void relocation_test(void) |
| 2434 | { | 2447 | { |
| @@ -2436,6 +2449,9 @@ void relocation_test(void) · 1 unmodified line | |||
| 2436 | printf("*rel1=%d\n", *rel1); | 2449 | printf("*rel1=%d\n", *rel1); |
| 2437 | printf("*rel2=%d\n", *rel2); | 2450 | printf("*rel2=%d\n", *rel2); |
| 2438 | fptr(); | 2451 | fptr(); |
| 2452 | #ifdef __LP64__ | ||
| 2453 | printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63); | ||
| 2454 | #endif | ||
| 2439 | } | 2455 | } |
| 2440 | 2456 | ||
| 2441 | void old_style_f(a,b,c) | 2457 | void old_style_f(a,b,c) |
| @@ -349,6 +349,8 @@ void load(int r, SValue *sv) · 348 unmodified lines | |||
| 349 | fr = sv->r; | 349 | fr = sv->r; |
| 350 | ft = sv->type.t & ~VT_DEFSIGN; | 350 | ft = sv->type.t & ~VT_DEFSIGN; |
| 351 | fc = sv->c.i; | 351 | fc = sv->c.i; |
| 352 | if (fc != sv->c.i && (fr & VT_SYM)) | ||
| 353 | tcc_error("64 bit addend in load"); | ||
| 352 | 354 | ||
| 353 | ft &= ~(VT_VOLATILE | VT_CONSTANT); | 355 | ft &= ~(VT_VOLATILE | VT_CONSTANT); |
| 354 | 356 | ||
| @@ -528,9 +530,11 @@ void store(int r, SValue *v) · 173 unmodified lines | |||
| 528 | v = pe_getimport(v, &v2); | 530 | v = pe_getimport(v, &v2); |
| 529 | #endif | 531 | #endif |
| 530 | 532 | ||
| 533 | fr = v->r & VT_VALMASK; | ||
| 531 | ft = v->type.t; | 534 | ft = v->type.t; |
| 532 | fc = v->c.i; | 535 | 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"); | ||
| 534 | ft &= ~(VT_VOLATILE | VT_CONSTANT); | 538 | ft &= ~(VT_VOLATILE | VT_CONSTANT); |
| 535 | bt = ft & VT_BTYPE; | 539 | bt = ft & VT_BTYPE; |
| 536 | 540 | ||