mirror of
https://github.com/frida/tinycc
synced 2024-11-28 02:29:38 +03:00
struct-init: Copy relocs for compound literals
When copying the content of compound literals we must include relocations as well.
This commit is contained in:
parent
0bca6cab06
commit
7ab35c6265
26
tccgen.c
26
tccgen.c
@ -5995,9 +5995,35 @@ static void init_putv(CType *type, Section *sec, unsigned long c)
|
||||
/* These come from compound literals, memcpy stuff over. */
|
||||
Section *ssec;
|
||||
ElfW(Sym) *esym;
|
||||
ElfW_Rel *rel;
|
||||
esym = &((ElfW(Sym) *)symtab_section->data)[vtop->sym->c];
|
||||
ssec = tcc_state->sections[esym->st_shndx];
|
||||
memmove (ptr, ssec->data + esym->st_value, size);
|
||||
if (ssec->reloc) {
|
||||
/* We need to copy over all memory contents, and that
|
||||
includes relocations. Use the fact that relocs are
|
||||
created it order, so look from the end of relocs
|
||||
until we hit one before the copied region. */
|
||||
int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
|
||||
rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
|
||||
while (num_relocs--) {
|
||||
rel--;
|
||||
if (rel->r_offset >= esym->st_value + size)
|
||||
continue;
|
||||
if (rel->r_offset < esym->st_value)
|
||||
break;
|
||||
put_elf_reloca(symtab_section, sec,
|
||||
c + rel->r_offset - esym->st_value,
|
||||
ELFW(R_TYPE)(rel->r_info),
|
||||
ELFW(R_SYM)(rel->r_info),
|
||||
#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
|
||||
rel->r_addend
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((vtop->r & VT_SYM) &&
|
||||
(bt == VT_BYTE ||
|
||||
|
@ -109,6 +109,21 @@ struct pkthdr {
|
||||
struct in6_addr daddr, saddr;
|
||||
};
|
||||
struct pkthdr phdr = { { { 6,5,4,3 } }, { { 9,8,7,6 } } };
|
||||
|
||||
struct Wrap {
|
||||
void *func;
|
||||
};
|
||||
int global;
|
||||
void inc_global (void)
|
||||
{
|
||||
global++;
|
||||
}
|
||||
|
||||
struct Wrap global_wrap[] = {
|
||||
((struct Wrap) {inc_global}),
|
||||
inc_global,
|
||||
};
|
||||
|
||||
#include <stdio.h>
|
||||
void print_ (const char *name, const u8 *p, long size)
|
||||
{
|
||||
@ -171,6 +186,19 @@ void foo (struct W *w, struct pkthdr *phdr_)
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_compound_with_relocs (void)
|
||||
{
|
||||
struct Wrap local_wrap[] = {
|
||||
((struct Wrap) {inc_global}),
|
||||
inc_global,
|
||||
};
|
||||
void (*p)(void);
|
||||
p = global_wrap[0].func; p();
|
||||
p = global_wrap[1].func; p();
|
||||
p = local_wrap[0].func; p();
|
||||
p = local_wrap[1].func; p();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
print(ce);
|
||||
@ -195,5 +223,6 @@ int main()
|
||||
print(phdr);
|
||||
foo(&gw, &phdr);
|
||||
//printf("q: %s\n", q);
|
||||
test_compound_with_relocs();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user