mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-04 06:30:10 +08:00
OpenBSD: runtime fixes
After this commit we can compile and run code with some limitations. - The dlsym function is broken so this makes -run and bound checking not work all the time. Make -k test does work for most code. - You have to do: ln -s /usr/lib/libN.so.x.y /usr/lib/libN.so for all .so files in /usr/lib. OpenBSD uses opendir/readdir to find the correct so file. This is not the way other platforms do this. Also the .a versions do not have all symbols that are present in the .so files. tcc.h: - Use different dynamic loader elf.h: - Add SHT_X86_64_UNWIND tccelf.c: - Do not use -dl - Add required NOTE section - Add extra dynamic tags - Allow SHT_X86_64_UNWIND/SHT_NOTE in tcc_load_object_file tccrun.c: - Uses MAP_FIXED because without the offset between exec and data section becomes too big for x86_64 lib/bcheck.c: - Do not use __libc_freeres tests/tcctest.c: - aligned_function also disabled for __GNUC__ == 4
This commit is contained in:
parent
19d287aae3
commit
baacb0f52a
2
elf.h
2
elf.h
@ -2908,6 +2908,8 @@ typedef Elf32_Addr Elf32_Conflict;
|
|||||||
|
|
||||||
#define R_X86_64_NUM 43
|
#define R_X86_64_NUM 43
|
||||||
|
|
||||||
|
/* x86-64 sh_type values. */
|
||||||
|
#define SHT_X86_64_UNWIND 0x70000001 /* Unwind information. */
|
||||||
|
|
||||||
/* AM33 relocations. */
|
/* AM33 relocations. */
|
||||||
#define R_MN10300_NONE 0 /* No reloc. */
|
#define R_MN10300_NONE 0 /* No reloc. */
|
||||||
|
@ -1147,7 +1147,7 @@ void __attribute__((destructor)) __bound_exit(void)
|
|||||||
dprintf(stderr, "%s, %s():\n", __FILE__, __FUNCTION__);
|
dprintf(stderr, "%s, %s():\n", __FILE__, __FUNCTION__);
|
||||||
|
|
||||||
if (inited) {
|
if (inited) {
|
||||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__)
|
||||||
if (print_heap) {
|
if (print_heap) {
|
||||||
extern void __libc_freeres (void);
|
extern void __libc_freeres (void);
|
||||||
__libc_freeres ();
|
__libc_freeres ();
|
||||||
|
6
tcc.h
6
tcc.h
@ -285,7 +285,11 @@ extern char **environ;
|
|||||||
# if defined(TCC_MUSL)
|
# if defined(TCC_MUSL)
|
||||||
# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"
|
# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"
|
||||||
# else
|
# else
|
||||||
# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
|
# if defined(__OpenBSD__)
|
||||||
|
# define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.so"
|
||||||
|
# else
|
||||||
|
# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# elif defined(TCC_TARGET_RISCV64)
|
# elif defined(TCC_TARGET_RISCV64)
|
||||||
# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-riscv64-lp64d.so.1"
|
# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-riscv64-lp64d.so.1"
|
||||||
|
60
tccelf.c
60
tccelf.c
@ -1413,7 +1413,9 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
|
|||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
|
if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
|
||||||
tcc_add_library_err(s1, "pthread");
|
tcc_add_library_err(s1, "pthread");
|
||||||
|
#if !defined(__OpenBSD__)
|
||||||
tcc_add_library_err(s1, "dl");
|
tcc_add_library_err(s1, "dl");
|
||||||
|
#endif
|
||||||
tcc_add_support(s1, "bcheck.o");
|
tcc_add_support(s1, "bcheck.o");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1992,7 +1994,7 @@ static void put_dt(Section *dynamic, int dt, addr_t val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
|
static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
|
||||||
Section *dynamic)
|
Section *dynamic, Section *note)
|
||||||
{
|
{
|
||||||
ElfW(Phdr) *ph;
|
ElfW(Phdr) *ph;
|
||||||
|
|
||||||
@ -2019,6 +2021,19 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
|
|||||||
ph->p_align = interp->sh_addralign;
|
ph->p_align = interp->sh_addralign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (note) {
|
||||||
|
ph = &phdr[phnum - 2];
|
||||||
|
|
||||||
|
ph->p_type = PT_NOTE;
|
||||||
|
ph->p_offset = note->sh_offset;
|
||||||
|
ph->p_vaddr = note->sh_addr;
|
||||||
|
ph->p_paddr = ph->p_vaddr;
|
||||||
|
ph->p_filesz = note->sh_size;
|
||||||
|
ph->p_memsz = note->sh_size;
|
||||||
|
ph->p_flags = PF_R;
|
||||||
|
ph->p_align = note->sh_addralign;
|
||||||
|
}
|
||||||
|
|
||||||
/* if dynamic section, then add corresponding program header */
|
/* if dynamic section, then add corresponding program header */
|
||||||
if (dynamic) {
|
if (dynamic) {
|
||||||
ph = &phdr[phnum - 1];
|
ph = &phdr[phnum - 1];
|
||||||
@ -2051,6 +2066,13 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
|
|||||||
put_dt(dynamic, DT_RELA, dyninf->rel_addr);
|
put_dt(dynamic, DT_RELA, dyninf->rel_addr);
|
||||||
put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
|
put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
|
||||||
put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
|
put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
|
||||||
|
put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
|
||||||
|
put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
|
||||||
|
put_dt(dynamic, DT_PLTREL, DT_RELA);
|
||||||
|
put_dt(dynamic, DT_BIND_NOW, 1); /* Dirty hack */
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
|
put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
|
||||||
@ -2372,6 +2394,25 @@ static void create_arm_attribute_section(TCCState *s1)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
static Section *create_openbsd_note_section(TCCState *s1)
|
||||||
|
{
|
||||||
|
Section *s = find_section (s1, ".note.openbsd.ident");
|
||||||
|
|
||||||
|
if (s->data_offset == 0) {
|
||||||
|
unsigned char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
|
||||||
|
ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
|
||||||
|
|
||||||
|
s->sh_type = SHT_NOTE;
|
||||||
|
note->n_namesz = 8;
|
||||||
|
note->n_descsz = 4;
|
||||||
|
note->n_type = ELF_NOTE_OS_GNU;
|
||||||
|
strcpy (ptr + sizeof(ElfW(Nhdr)), "OpenBSD");
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Output an elf, coff or binary file */
|
/* Output an elf, coff or binary file */
|
||||||
/* XXX: suppress unneeded sections */
|
/* XXX: suppress unneeded sections */
|
||||||
static int elf_output_file(TCCState *s1, const char *filename)
|
static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
@ -2379,13 +2420,18 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
|||||||
int ret, phnum, shnum, file_type, file_offset, *sec_order;
|
int ret, phnum, shnum, file_type, file_offset, *sec_order;
|
||||||
struct dyn_inf dyninf = {0};
|
struct dyn_inf dyninf = {0};
|
||||||
ElfW(Phdr) *phdr;
|
ElfW(Phdr) *phdr;
|
||||||
Section *strsec, *interp, *dynamic, *dynstr;
|
Section *strsec, *interp, *dynamic, *dynstr, *note = NULL;
|
||||||
|
|
||||||
|
file_type = s1->output_type;
|
||||||
|
|
||||||
#ifdef TCC_TARGET_ARM
|
#ifdef TCC_TARGET_ARM
|
||||||
create_arm_attribute_section (s1);
|
create_arm_attribute_section (s1);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
if (file_type != TCC_OUTPUT_OBJ)
|
||||||
|
note = create_openbsd_note_section (s1);
|
||||||
|
#endif
|
||||||
|
|
||||||
file_type = s1->output_type;
|
|
||||||
s1->nb_errors = 0;
|
s1->nb_errors = 0;
|
||||||
ret = -1;
|
ret = -1;
|
||||||
phdr = NULL;
|
phdr = NULL;
|
||||||
@ -2497,6 +2543,8 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
|||||||
phnum = i < s1->nb_sections ? 6 : 5;
|
phnum = i < s1->nb_sections ? 6 : 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
phnum += note != NULL;
|
||||||
|
|
||||||
/* allocate program segment headers */
|
/* allocate program segment headers */
|
||||||
phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
|
phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
|
||||||
|
|
||||||
@ -2515,7 +2563,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
|||||||
/* Fill remaining program header and finalize relocation related to dynamic
|
/* Fill remaining program header and finalize relocation related to dynamic
|
||||||
linking. */
|
linking. */
|
||||||
if (file_type != TCC_OUTPUT_OBJ) {
|
if (file_type != TCC_OUTPUT_OBJ) {
|
||||||
fill_unloadable_phdr(phdr, phnum, interp, dynamic);
|
fill_unloadable_phdr(phdr, phnum, interp, dynamic, note);
|
||||||
if (dynamic) {
|
if (dynamic) {
|
||||||
ElfW(Sym) *sym;
|
ElfW(Sym) *sym;
|
||||||
dynamic->data_offset = dyninf.data_offset;
|
dynamic->data_offset = dyninf.data_offset;
|
||||||
@ -2703,6 +2751,10 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
|
|||||||
if (sh->sh_type != SHT_PROGBITS &&
|
if (sh->sh_type != SHT_PROGBITS &&
|
||||||
#ifdef TCC_ARM_EABI
|
#ifdef TCC_ARM_EABI
|
||||||
sh->sh_type != SHT_ARM_EXIDX &&
|
sh->sh_type != SHT_ARM_EXIDX &&
|
||||||
|
#endif
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
sh->sh_type != SHT_X86_64_UNWIND &&
|
||||||
|
sh->sh_type != SHT_NOTE &&
|
||||||
#endif
|
#endif
|
||||||
sh->sh_type != SHT_NOBITS &&
|
sh->sh_type != SHT_NOBITS &&
|
||||||
sh->sh_type != SHT_PREINIT_ARRAY &&
|
sh->sh_type != SHT_PREINIT_ARRAY &&
|
||||||
|
15
tccrun.c
15
tccrun.c
@ -88,8 +88,23 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
|
|||||||
unlink(tmpfname);
|
unlink(tmpfname);
|
||||||
ftruncate(fd, size);
|
ftruncate(fd, size);
|
||||||
|
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
{ /* OpenBSD uses random 64 addresses that are far apart. This does not
|
||||||
|
work for the x86_64 target.
|
||||||
|
This might be a problem in the future for other targets. */
|
||||||
|
static char *prw = (char *) 0x100000000;
|
||||||
|
char *pex = prw + 0x40000000;
|
||||||
|
|
||||||
|
ptr = mmap (prw, size, PROT_READ|PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
|
||||||
|
prx = mmap (pex, size, PROT_READ|PROT_EXEC, MAP_SHARED | MAP_FIXED, fd, 0);
|
||||||
|
tcc_enter_state (s1);
|
||||||
|
prw += 0x100000000;
|
||||||
|
tcc_exit_state();
|
||||||
|
}
|
||||||
|
#else
|
||||||
ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
|
prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
|
||||||
|
#endif
|
||||||
if (ptr == MAP_FAILED || prx == MAP_FAILED)
|
if (ptr == MAP_FAILED || prx == MAP_FAILED)
|
||||||
tcc_error("tccrun: could not map memory");
|
tcc_error("tccrun: could not map memory");
|
||||||
dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
|
dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
|
||||||
|
@ -2313,7 +2313,7 @@ int fib(int n)
|
|||||||
return fib(n-1) + fib(n-2);
|
return fib(n-1) + fib(n-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __GNUC__ == 3
|
#if __GNUC__ == 3 || __GNUC__ == 4
|
||||||
# define aligned_function 0
|
# define aligned_function 0
|
||||||
#else
|
#else
|
||||||
void __attribute__((aligned(16))) aligned_function(int i) {}
|
void __attribute__((aligned(16))) aligned_function(int i) {}
|
||||||
|
Loading…
Reference in New Issue
Block a user