Skip to content

Commit ca061f3

Browse files
author
grischka
committed
i386-asm: fix pc-relative label ariths
See test. We need to use 'ind' from later when the address field of the instruction is put. Also: fix crash when the substracted symbol is undefined Also: assume asm-symbols to be lvalues (except func/array)
1 parent 9675c1e commit ca061f3

File tree

4 files changed

+17
-2
lines changed

4 files changed

+17
-2
lines changed

i386-asm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ ST_FUNC void gen_expr32(ExprValue *pe)
487487
if (pe->pcrel)
488488
/* If PC-relative, always set VT_SYM, even without symbol,
489489
so as to force a relocation to be emitted. */
490-
gen_addrpc32(VT_SYM, pe->sym, pe->v);
490+
gen_addrpc32(VT_SYM, pe->sym, pe->v + (ind + 4));
491491
else
492492
gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
493493
}

tccasm.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
323323
ElfSym *esym1, *esym2;
324324
esym1 = elfsym(pe->sym);
325325
esym2 = elfsym(e2.sym);
326+
if (!esym2)
327+
goto cannot_relocate;
326328
if (esym1 && esym1->st_shndx == esym2->st_shndx
327329
&& esym1->st_shndx != SHN_UNDEF) {
328330
/* we also accept defined symbols in the same section */
@@ -331,7 +333,7 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
331333
} else if (esym2->st_shndx == cur_text_section->sh_num) {
332334
/* When subtracting a defined symbol in current section
333335
this actually makes the value PC-relative. */
334-
pe->v -= esym2->st_value - ind - 4;
336+
pe->v += 0 - esym2->st_value;
335337
pe->pcrel = 1;
336338
e2.sym = NULL;
337339
} else {

tccgen.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,8 @@ static void patch_type(Sym *sym, CType *type)
12041204
/* stay static if both are static */
12051205
sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
12061206
sym->type.ref = type->ref;
1207+
if ((type->t & VT_BTYPE) != VT_FUNC && !(type->t & VT_ARRAY))
1208+
sym->r |= VT_LVAL;
12071209
}
12081210

12091211
if (!is_compatible_types(&sym->type, type)) {

tests/tcctest.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3758,6 +3758,16 @@ void asm_dot_test(void)
37583758
#endif
37593759
}
37603760

3761+
void asm_pcrel_test(void)
3762+
{
3763+
unsigned o1, o2;
3764+
/* subtract text-section label from forward or other-section label */
3765+
asm("1: mov $2f-1b,%%eax; mov %%eax,%0" : "=m"(o1));
3766+
/* verify ... */
3767+
asm("2: mov $2b,%%eax; sub $1b,%%eax; mov %%eax,%0" : "=m"(o2));
3768+
printf("%s : %x\n", __FUNCTION__, o1 - o2); /* should be zero */
3769+
}
3770+
37613771
void asm_test(void)
37623772
{
37633773
char buf[128];
@@ -3849,6 +3859,7 @@ void asm_test(void)
38493859
test_asm_dead_code();
38503860
test_asm_call();
38513861
asm_dot_test();
3862+
asm_pcrel_test();
38523863
return;
38533864
label1:
38543865
goto label2;

0 commit comments

Comments
 (0)