mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-28 04:00:06 +08:00
function pointer compare
tccelf.c: - Check if symbol is in data section and UNDEF. Then generate new relocation and let dynamic linker solve it. tests/tests2/42_function_pointer.c: - Add new test code
This commit is contained in:
parent
ffac4e7688
commit
8f9bf3f223
23
tccelf.c
23
tccelf.c
@ -996,12 +996,25 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
|||||||
tgt += rel->r_addend;
|
tgt += rel->r_addend;
|
||||||
#endif
|
#endif
|
||||||
addr = s->sh_addr + rel->r_offset;
|
addr = s->sh_addr + rel->r_offset;
|
||||||
relocate(s1, rel, type, ptr, addr, tgt);
|
{
|
||||||
|
#if !(defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
|
||||||
|
defined(TCC_TARGET_MACHO))
|
||||||
|
int dynindex;
|
||||||
|
if (s == data_section && sym->st_shndx == SHN_UNDEF &&
|
||||||
|
s1->dynsym &&
|
||||||
|
(dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index)) {
|
||||||
|
rel->r_info = ELFW(R_INFO)(dynindex, type);
|
||||||
|
*qrel++ = *rel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
relocate(s1, rel, type, ptr, addr, tgt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* if the relocation is allocated, we change its symbol table */
|
/* if the relocation is allocated, we change its symbol table */
|
||||||
if (sr->sh_flags & SHF_ALLOC) {
|
if (sr->sh_flags & SHF_ALLOC) {
|
||||||
sr->link = s1->dynsym;
|
sr->link = s1->dynsym;
|
||||||
if (s1->output_type == TCC_OUTPUT_DLL) {
|
if (qrel != (ElfW_Rel *)sr->data) {
|
||||||
size_t r = (uint8_t*)qrel - sr->data;
|
size_t r = (uint8_t*)qrel - sr->data;
|
||||||
if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
|
if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
|
||||||
&& 0 == strcmp(s->name, ".stab"))
|
&& 0 == strcmp(s->name, ".stab"))
|
||||||
@ -1242,6 +1255,12 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
|||||||
/* dynsym isn't set for -run :-/ */
|
/* dynsym isn't set for -run :-/ */
|
||||||
dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
|
dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
|
||||||
esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
|
esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
|
||||||
|
#if !(defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
|
||||||
|
defined(TCC_TARGET_MACHO))
|
||||||
|
if (dynindex && s == data_section->reloc)
|
||||||
|
s->sh_flags |= SHF_ALLOC;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if (dynindex
|
if (dynindex
|
||||||
&& (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
|
&& (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
|
||||||
|| (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
|
|| (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
|
||||||
|
@ -12,10 +12,18 @@ int (*f)(int) = &fred;
|
|||||||
(fprint here) must not be called directly anywhere in the test. */
|
(fprint here) must not be called directly anywhere in the test. */
|
||||||
int (*fprintfptr)(FILE *, const char *, ...) = &fprintf;
|
int (*fprintfptr)(FILE *, const char *, ...) = &fprintf;
|
||||||
|
|
||||||
|
typedef int (*func) (int);
|
||||||
|
static int dummy1(int i) { return 0; }
|
||||||
|
int dummy2(int i) { return 0; }
|
||||||
|
static func allfunc[] = { putchar, dummy1, dummy2 };
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
fprintfptr(stdout, "%d\n", (*f)(24));
|
fprintfptr(stdout, "%d\n", (*f)(24));
|
||||||
|
|
||||||
|
printf ("%d\n", allfunc[0] == putchar);
|
||||||
|
printf ("%d\n", allfunc[1] == dummy1);
|
||||||
|
printf ("%d\n", allfunc[2] == dummy2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,2 +1,5 @@
|
|||||||
yo 24
|
yo 24
|
||||||
42
|
42
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
Loading…
Reference in New Issue
Block a user