mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-28 04:00:06 +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 (pe->pcrel)
|
||||||
/* If PC-relative, always set VT_SYM, even without symbol,
|
/* If PC-relative, always set VT_SYM, even without symbol,
|
||||||
so as to force a relocation to be emitted. */
|
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
|
else
|
||||||
gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
|
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;
|
ElfSym *esym1, *esym2;
|
||||||
esym1 = elfsym(pe->sym);
|
esym1 = elfsym(pe->sym);
|
||||||
esym2 = elfsym(e2.sym);
|
esym2 = elfsym(e2.sym);
|
||||||
|
if (!esym2)
|
||||||
|
goto cannot_relocate;
|
||||||
if (esym1 && esym1->st_shndx == esym2->st_shndx
|
if (esym1 && esym1->st_shndx == esym2->st_shndx
|
||||||
&& esym1->st_shndx != SHN_UNDEF) {
|
&& esym1->st_shndx != SHN_UNDEF) {
|
||||||
/* we also accept defined symbols in the same section */
|
/* 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) {
|
} else if (esym2->st_shndx == cur_text_section->sh_num) {
|
||||||
/* When subtracting a defined symbol in current section
|
/* When subtracting a defined symbol in current section
|
||||||
this actually makes the value PC-relative. */
|
this actually makes the value PC-relative. */
|
||||||
pe->v -= esym2->st_value - ind - 4;
|
pe->v += 0 - esym2->st_value;
|
||||||
pe->pcrel = 1;
|
pe->pcrel = 1;
|
||||||
e2.sym = NULL;
|
e2.sym = NULL;
|
||||||
} else {
|
} 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 */
|
/* stay static if both are static */
|
||||||
sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
|
sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
|
||||||
sym->type.ref = type->ref;
|
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)) {
|
if (!is_compatible_types(&sym->type, type)) {
|
||||||
|
@ -3758,6 +3758,16 @@ void asm_dot_test(void)
|
|||||||
#endif
|
#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)
|
void asm_test(void)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
@ -3849,6 +3859,7 @@ void asm_test(void)
|
|||||||
test_asm_dead_code();
|
test_asm_dead_code();
|
||||||
test_asm_call();
|
test_asm_call();
|
||||||
asm_dot_test();
|
asm_dot_test();
|
||||||
|
asm_pcrel_test();
|
||||||
return;
|
return;
|
||||||
label1:
|
label1:
|
||||||
goto label2;
|
goto label2;
|
||||||
|
Loading…
Reference in New Issue
Block a user