History

riscv: fix relocs for global syms

loads and stores to global symbols need to go via the GOT (at least for weaks), otherwise -run doesn't work. Ideally we'd generate GOT relocs (and loads) always and replace them with PCREL relocs and adds during linking.

Michael Matz committed 7 years ago

Commit 06184ae1 parent 69c77d11 file · +40 −14Browse files

Unified · Split

riscv64-gen.c+40−14
@@ -145,7 +145,7 @@ ST_FUNC void load(int r, SValue *sv) · 144 unmodified lines
145 int bt = sv->type.t & VT_BTYPE;145 int bt = sv->type.t & VT_BTYPE;
146 int align, size = type_size(&sv->type, &align);146 int align, size = type_size(&sv->type, &align);
147 if (fr & VT_LVAL) {147 if (fr & VT_LVAL) {
148 int func3, opcode = 0x03;148 int func3, opcode = 0x03, doload = 0;
149 if (is_freg(r)) {149 if (is_freg(r)) {
150 assert(bt == VT_DOUBLE || bt == VT_FLOAT);150 assert(bt == VT_DOUBLE || bt == VT_FLOAT);
151 opcode = 0x07;151 opcode = 0x07;
@@ -176,12 +176,19 @@ ST_FUNC void load(int r, SValue *sv) · 24 unmodified lines
176 EI(opcode, func3, rr, ireg(v), fc); // l[bhwd][u] RR, 0(V)176 EI(opcode, func3, rr, ireg(v), fc); // l[bhwd][u] RR, 0(V)
177 } else if (v == VT_CONST && (fr & VT_SYM)) {177 } else if (v == VT_CONST && (fr & VT_SYM)) {
178 static Sym label;178 static Sym label;
179 int addend = 0, tempr;179 int tempr;
180 if (1 || ((unsigned)fc + (1 << 11)) >> 12)180 if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax
181 addend = fc, fc = 0;181 greloca(cur_text_section, sv->sym, ind,
182 182 R_RISCV_PCREL_HI20, sv->c.i);
183 greloca(cur_text_section, sv->sym, ind,183 fc = 0;
184 R_RISCV_PCREL_HI20, addend);184 sv->c.i = 0;
185 } else {
186 if (((unsigned)fc + (1 << 11)) >> 12)
187 tcc_error("unimp: large addend for global address");
188 greloca(cur_text_section, sv->sym, ind,
189 R_RISCV_GOT_HI20, 0);
190 doload = 1;
191 }
185 if (!label.v) {192 if (!label.v) {
186 label.v = tok_alloc(".L0 ", 4)->tok;193 label.v = tok_alloc(".L0 ", 4)->tok;
187 label.type.t = VT_VOID | VT_STATIC;194 label.type.t = VT_VOID | VT_STATIC;
@@ -192,6 +199,12 @@ ST_FUNC void load(int r, SValue *sv) · 4 unmodified lines
192 o(0x17 | (tempr << 7)); // auipc TR, 0 %pcrel_hi(sym)+addend199 o(0x17 | (tempr << 7)); // auipc TR, 0 %pcrel_hi(sym)+addend
193 greloca(cur_text_section, &label, ind,200 greloca(cur_text_section, &label, ind,
194 R_RISCV_PCREL_LO12_I, 0);201 R_RISCV_PCREL_LO12_I, 0);
202 if (doload) {
203 EI(0x03, 3, tempr, tempr, 0); // ld TR, 0(TR)
204 if (fc)
205 EI(0x13, 0, tempr, tempr, fc << 20 >> 20); // addi TR, TR, FC
206 fc = 0;
207 }
195 EI(opcode, func3, rr, tempr, fc); // l[bhwd][u] RR, fc(TR)208 EI(opcode, func3, rr, tempr, fc); // l[bhwd][u] RR, fc(TR)
196 } else if (v == VT_LLOCAL) {209 } else if (v == VT_LLOCAL) {
197 int br = 8, tempr = is_ireg(r) ? rr : 5;210 int br = 8, tempr = is_ireg(r) ? rr : 5;
@@ -361,13 +374,20 @@ ST_FUNC void store(int r, SValue *sv) · 163 unmodified lines
361 ptrreg, rr, fc); // s[bhwd] RR, fc(PTRREG)374 ptrreg, rr, fc); // s[bhwd] RR, fc(PTRREG)
362 } else if ((sv->r & ~VT_LVAL_TYPE) == (VT_CONST | VT_SYM | VT_LVAL)) {375 } else if ((sv->r & ~VT_LVAL_TYPE) == (VT_CONST | VT_SYM | VT_LVAL)) {
363 static Sym label;376 static Sym label;
364 int tempr, addend = 0;377 int tempr, doload = 0;
365 if (1 || ((unsigned)fc + (1 << 11)) >> 12)
366 addend = fc, fc = 0;
367
368 tempr = 5; // t0378 tempr = 5; // t0
369 greloca(cur_text_section, sv->sym, ind,379 if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax
370 R_RISCV_PCREL_HI20, addend);380 greloca(cur_text_section, sv->sym, ind,
381 R_RISCV_PCREL_HI20, sv->c.i);
382 fc = 0;
383 sv->c.i = 0;
384 } else {
385 if (((unsigned)fc + (1 << 11)) >> 12)
386 tcc_error("unimp: large addend for global address");
387 greloca(cur_text_section, sv->sym, ind,
388 R_RISCV_GOT_HI20, 0);
389 doload = 1;
390 }
371 if (!label.v) {391 if (!label.v) {
372 label.v = tok_alloc(".L0 ", 4)->tok;392 label.v = tok_alloc(".L0 ", 4)->tok;
373 label.type.t = VT_VOID | VT_STATIC;393 label.type.t = VT_VOID | VT_STATIC;
@@ -376,7 +396,13 @@ ST_FUNC void store(int r, SValue *sv) · 2 unmodified lines
376 put_extern_sym(&label, cur_text_section, ind, 0);396 put_extern_sym(&label, cur_text_section, ind, 0);
377 o(0x17 | (tempr << 7)); // auipc TEMPR, 0 %pcrel_hi(sym)+addend397 o(0x17 | (tempr << 7)); // auipc TEMPR, 0 %pcrel_hi(sym)+addend
378 greloca(cur_text_section, &label, ind,398 greloca(cur_text_section, &label, ind,
379 R_RISCV_PCREL_LO12_S, 0);399 doload ? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0);
400 if (doload) {
401 EI(0x03, 3, tempr, tempr, 0); // ld TR, 0(TR)
402 if (fc)
403 EI(0x13, 0, tempr, tempr, fc << 20 >> 20); // addi TR, TR, FC
404 fc = 0;
405 }
380 if (is_freg(r))406 if (is_freg(r))
381 ES(0x27, size == 4 ? 2 : 3, tempr, rr, fc); // fs[wd] RR, fc(TEMPR)407 ES(0x27, size == 4 ? 2 : 3, tempr, rr, fc); // fs[wd] RR, fc(TEMPR)
382 else408 else

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