mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-08 06:40:11 +08: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. */
|
/* These come from compound literals, memcpy stuff over. */
|
||||||
Section *ssec;
|
Section *ssec;
|
||||||
ElfW(Sym) *esym;
|
ElfW(Sym) *esym;
|
||||||
|
ElfW_Rel *rel;
|
||||||
esym = &((ElfW(Sym) *)symtab_section->data)[vtop->sym->c];
|
esym = &((ElfW(Sym) *)symtab_section->data)[vtop->sym->c];
|
||||||
ssec = tcc_state->sections[esym->st_shndx];
|
ssec = tcc_state->sections[esym->st_shndx];
|
||||||
memmove (ptr, ssec->data + esym->st_value, size);
|
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 {
|
} else {
|
||||||
if ((vtop->r & VT_SYM) &&
|
if ((vtop->r & VT_SYM) &&
|
||||||
(bt == VT_BYTE ||
|
(bt == VT_BYTE ||
|
||||||
|
@ -109,6 +109,21 @@ struct pkthdr {
|
|||||||
struct in6_addr daddr, saddr;
|
struct in6_addr daddr, saddr;
|
||||||
};
|
};
|
||||||
struct pkthdr phdr = { { { 6,5,4,3 } }, { { 9,8,7,6 } } };
|
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>
|
#include <stdio.h>
|
||||||
void print_ (const char *name, const u8 *p, long size)
|
void print_ (const char *name, const u8 *p, long size)
|
||||||
{
|
{
|
||||||
@ -171,6 +186,19 @@ void foo (struct W *w, struct pkthdr *phdr_)
|
|||||||
}
|
}
|
||||||
#endif
|
#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()
|
int main()
|
||||||
{
|
{
|
||||||
print(ce);
|
print(ce);
|
||||||
@ -195,5 +223,6 @@ int main()
|
|||||||
print(phdr);
|
print(phdr);
|
||||||
foo(&gw, &phdr);
|
foo(&gw, &phdr);
|
||||||
//printf("q: %s\n", q);
|
//printf("q: %s\n", q);
|
||||||
|
test_compound_with_relocs();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user