mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-26 03:50:07 +08:00
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)
This commit is contained in:
parent
9675c1e245
commit
ca061f3a96
@ -487,7 +487,7 @@ ST_FUNC void gen_expr32(ExprValue *pe)
|
||||
if (pe->pcrel)
|
||||
/* If PC-relative, always set VT_SYM, even without symbol,
|
||||
so as to force a relocation to be emitted. */
|
||||
gen_addrpc32(VT_SYM, pe->sym, pe->v);
|
||||
gen_addrpc32(VT_SYM, pe->sym, pe->v + (ind + 4));
|
||||
else
|
||||
gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
|
||||
}
|
||||
|
4
tccasm.c
4
tccasm.c
@ -323,6 +323,8 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
|
||||
ElfSym *esym1, *esym2;
|
||||
esym1 = elfsym(pe->sym);
|
||||
esym2 = elfsym(e2.sym);
|
||||
if (!esym2)
|
||||
goto cannot_relocate;
|
||||
if (esym1 && esym1->st_shndx == esym2->st_shndx
|
||||
&& esym1->st_shndx != SHN_UNDEF) {
|
||||
/* we also accept defined symbols in the same section */
|
||||
@ -331,7 +333,7 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
|
||||
} else if (esym2->st_shndx == cur_text_section->sh_num) {
|
||||
/* When subtracting a defined symbol in current section
|
||||
this actually makes the value PC-relative. */
|
||||
pe->v -= esym2->st_value - ind - 4;
|
||||
pe->v += 0 - esym2->st_value;
|
||||
pe->pcrel = 1;
|
||||
e2.sym = NULL;
|
||||
} else {
|
||||
|
2
tccgen.c
2
tccgen.c
@ -1204,6 +1204,8 @@ static void patch_type(Sym *sym, CType *type)
|
||||
/* stay static if both are static */
|
||||
sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
|
||||
sym->type.ref = type->ref;
|
||||
if ((type->t & VT_BTYPE) != VT_FUNC && !(type->t & VT_ARRAY))
|
||||
sym->r |= VT_LVAL;
|
||||
}
|
||||
|
||||
if (!is_compatible_types(&sym->type, type)) {
|
||||
|
@ -3758,6 +3758,16 @@ void asm_dot_test(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void asm_pcrel_test(void)
|
||||
{
|
||||
unsigned o1, o2;
|
||||
/* subtract text-section label from forward or other-section label */
|
||||
asm("1: mov $2f-1b,%%eax; mov %%eax,%0" : "=m"(o1));
|
||||
/* verify ... */
|
||||
asm("2: mov $2b,%%eax; sub $1b,%%eax; mov %%eax,%0" : "=m"(o2));
|
||||
printf("%s : %x\n", __FUNCTION__, o1 - o2); /* should be zero */
|
||||
}
|
||||
|
||||
void asm_test(void)
|
||||
{
|
||||
char buf[128];
|
||||
@ -3849,6 +3859,7 @@ void asm_test(void)
|
||||
test_asm_dead_code();
|
||||
test_asm_call();
|
||||
asm_dot_test();
|
||||
asm_pcrel_test();
|
||||
return;
|
||||
label1:
|
||||
goto label2;
|
||||
|
Loading…
Reference in New Issue
Block a user