Unified · Split
| @@ -632,9 +632,24 @@ void load(int r, SValue *sv) · 631 unmodified lines | ||
| 632 | 632 | if (fr & VT_SYM || !op) { |
| 633 | 633 | o(0xE59F0000|(intr(r)<<12)); |
| 634 | 634 | o(0xEA000000); |
| 635 | − if(fr & VT_SYM) | |
| 636 | − greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32); | |
| 637 | − o(sv->c.i); | |
| 635 | + if(fr & VT_SYM) { | |
| 636 | + if (sv->sym->type.t & VT_STATIC) { | |
| 637 | + greloc(cur_text_section, sv->sym, ind, R_ARM_REL32); | |
| 638 | + o(sv->c.i - 12); | |
| 639 | + o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | |
| 640 | + } | |
| 641 | + else { | |
| 642 | + greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL); | |
| 643 | + o(-12); | |
| 644 | + o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | |
| 645 | + o(0xe5900000 | (intr(r)<<12) | (intr(r)<<16)); // ldr rx,[rx] | |
| 646 | + if (sv->c.i) | |
| 647 | + stuff_const_harder(0xe2800000 | (intr(r)<<12) | (intr(r)<<16), | |
| 648 | + sv->c.i); | |
| 649 | + } | |
| 650 | + } | |
| 651 | + else | |
| 652 | + o(sv->c.i); | |
| 638 | 653 | } else |
| 639 | 654 | o(op); |
| 640 | 655 | return; |
| @@ -643,9 +658,24 @@ void load(int r, SValue *sv) · 2 unmodified lines | ||
| 643 | 658 | if (fr & VT_SYM || !op) { |
| 644 | 659 | o(0xE59F0000|(intr(r)<<12)); |
| 645 | 660 | o(0xEA000000); |
| 646 | − if(fr & VT_SYM) // needed ? | |
| 647 | − greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32); | |
| 648 | − o(sv->c.i); | |
| 661 | + if(fr & VT_SYM) { | |
| 662 | + if (sv->sym->type.t & VT_STATIC) { | |
| 663 | + greloc(cur_text_section, sv->sym, ind, R_ARM_REL32); | |
| 664 | + o(sv->c.i - 12); | |
| 665 | + o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | |
| 666 | + } | |
| 667 | + else { | |
| 668 | + greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL); | |
| 669 | + o(-12); | |
| 670 | + o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | |
| 671 | + o(0xe5900000 | (intr(r)<<12) | (intr(r)<<16)); // ldr rx,[rx] | |
| 672 | + if (sv->c.i) | |
| 673 | + stuff_const_harder(0xe2800000 | (intr(r)<<12) | (intr(r)<<16), | |
| 674 | + sv->c.i); | |
| 675 | + } | |
| 676 | + } | |
| 677 | + else | |
| 678 | + o(sv->c.i); | |
| 649 | 679 | o(0xE08B0000|(intr(r)<<12)|intr(r)); |
| 650 | 680 | } else |
| 651 | 681 | o(op); |
| @@ -771,25 +801,41 @@ static void gcall_or_jmp(int is_jmp) · 119 unmodified lines | ||
| 771 | 801 | uint32_t x; |
| 772 | 802 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { |
| 773 | 803 | /* constant case */ |
| 774 | − if(vtop->r & VT_SYM){ | |
| 775 | − x=encbranch(ind,ind+vtop->c.i,0); | |
| 776 | − if(x) { | |
| 777 | − /* relocation case */ | |
| 778 | − greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24); | |
| 779 | − o(x|(is_jmp?0xE0000000:0xE1000000)); | |
| 780 | − } else { | |
| 781 | − if(!is_jmp) | |
| 782 | − o(0xE28FE004); // add lr,pc,#4 | |
| 783 | − o(0xE51FF004); // ldr pc,[pc,#-4] | |
| 784 | − greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32); | |
| 785 | − o(vtop->c.i); | |
| 786 | − } | |
| 787 | − }else{ | |
| 788 | − if(!is_jmp) | |
| 789 | − o(0xE28FE004); // add lr,pc,#4 | |
| 790 | − o(0xE51FF004); // ldr pc,[pc,#-4] | |
| 791 | − o(vtop->c.i); | |
| 804 | + if(vtop->r & VT_SYM){ | |
| 805 | + x=encbranch(ind,ind+vtop->c.i,0); | |
| 806 | + if(x) { | |
| 807 | + /* relocation case */ | |
| 808 | + greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24); | |
| 809 | + o(x|(is_jmp?0xE0000000:0xE1000000)); | |
| 810 | + } else { | |
| 811 | + r = TREG_LR; | |
| 812 | + o(0xE59F0000|(intr(r)<<12)); // ldr r,[pc] | |
| 813 | + o(0xEA000000); // b $+4 | |
| 814 | + if (vtop->sym->type.t & VT_STATIC) { | |
| 815 | + greloc(cur_text_section, vtop->sym, ind, R_ARM_REL32); | |
| 816 | + o(vtop->c.i - 12); | |
| 817 | + o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | |
| 818 | + } | |
| 819 | + else { | |
| 820 | + greloc(cur_text_section, vtop->sym, ind, R_ARM_GOT_PREL); | |
| 821 | + o(-12); | |
| 822 | + o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add r,r,pc | |
| 823 | + o(0xe5900000 | (intr(r)<<12) | (intr(r)<<16)); // ldr r,[r] | |
| 824 | + if (vtop->c.i) | |
| 825 | + stuff_const_harder(0xe2800000 | (intr(r)<<12) | (intr(r)<<16), | |
| 826 | + vtop->c.i); | |
| 827 | + } | |
| 828 | + if(is_jmp) | |
| 829 | + o(0xE1A0F000 | intr(r)); // mov pc, r | |
| 830 | + else | |
| 831 | + o(0xe12fff30 | intr(r)); // blx r | |
| 792 | 832 | } |
| 833 | + }else{ | |
| 834 | + if(!is_jmp) | |
| 835 | + o(0xE28FE004); // add lr,pc,#4 | |
| 836 | + o(0xE51FF004); // ldr pc,[pc,#-4] | |
| 837 | + o(vtop->c.i); | |
| 838 | + } | |
| 793 | 839 | } else { |
| 794 | 840 | /* otherwise, indirect call */ |
| 795 | 841 | #ifdef CONFIG_TCC_BCHECK |
| @@ -821,6 +867,7 @@ static void gen_bounds_prolog(void) · 25 unmodified lines | ||
| 821 | 867 | o(0xe1a00000); /* ld r0,lbounds_section->data_offset */ |
| 822 | 868 | o(0xe1a00000); |
| 823 | 869 | o(0xe1a00000); |
| 870 | + o(0xe1a00000); | |
| 824 | 871 | o(0xe1a00000); /* call __bound_local_new */ |
| 825 | 872 | } |
| 826 | 873 | |
| @@ -847,8 +894,9 @@ static void gen_bounds_epilog(void) · 20 unmodified lines | ||
| 847 | 894 | ind = func_bound_ind; |
| 848 | 895 | o(0xe59f0000); /* ldr r0, [pc] */ |
| 849 | 896 | o(0xea000000); /* b $+4 */ |
| 850 | − greloc(cur_text_section, sym_data, ind, R_ARM_ABS32); | |
| 851 | − o(0x00000000); /* lbounds_section->data_offset */ | |
| 897 | + greloc(cur_text_section, sym_data, ind, R_ARM_REL32); | |
| 898 | + o(-12); /* lbounds_section->data_offset */ | |
| 899 | + o(0xe080000f); /* add r0,r0,pc */ | |
| 852 | 900 | gen_bounds_call(TOK___bound_local_new); |
| 853 | 901 | ind = saved_ind; |
| 854 | 902 | } |
| @@ -858,8 +906,9 @@ static void gen_bounds_epilog(void) · 3 unmodified lines | ||
| 858 | 906 | o(0xed2d0b02); /* vpush {d0} */ |
| 859 | 907 | o(0xe59f0000); /* ldr r0, [pc] */ |
| 860 | 908 | o(0xea000000); /* b $+4 */ |
| 861 | − greloc(cur_text_section, sym_data, ind, R_ARM_ABS32); | |
| 862 | − o(0x00000000); /* lbounds_section->data_offset */ | |
| 909 | + greloc(cur_text_section, sym_data, ind, R_ARM_REL32); | |
| 910 | + o(-12); /* lbounds_section->data_offset */ | |
| 911 | + o(0xe080000f); /* add r0,r0,pc */ | |
| 863 | 912 | gen_bounds_call(TOK___bound_local_delete); |
| 864 | 913 | o(0xecbd0b02); /* vpop {d0} */ |
| 865 | 914 | o(0xe8bd0003); /* pop {r0,r1} */ |