History

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

herman ten brugge committed 5 years ago

Commit baacb0f1 parent 19d287a6 files · +80 −7Browse files

Unified · Split

6 files
  1. elf.h +2 −0
  2. lib/bcheck.c +1 −1
  3. tcc.h +5 −1
  4. tccelf.c +56 −4
  5. tccrun.c +15 −0
  6. tests/tcctest.c +1 −1
elf.h+2−0
@@ -2908,6 +2908,8 @@ typedef Elf32_Addr Elf32_Conflict; · 2907 unmodified lines
2908 2908
2909#define R_X86_64_NUM 432909#define R_X86_64_NUM 43
2910 2910
2911/* x86-64 sh_type values. */
2912#define SHT_X86_64_UNWIND 0x70000001 /* Unwind information. */
2911 2913
2912/* AM33 relocations. */2914/* AM33 relocations. */
2913#define R_MN10300_NONE 0 /* No reloc. */2915#define R_MN10300_NONE 0 /* No reloc. */
lib/bcheck.c+1−1
@@ -1147,7 +1147,7 @@ void __attribute__((destructor)) __bound_exit(void) · 1146 unmodified lines
1147 dprintf(stderr, "%s, %s():\n", __FILE__, __FUNCTION__);1147 dprintf(stderr, "%s, %s():\n", __FILE__, __FUNCTION__);
1148 1148
1149 if (inited) {1149 if (inited) {
1150#if !defined(_WIN32) && !defined(__APPLE__)1150#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__)
1151 if (print_heap) {1151 if (print_heap) {
1152 extern void __libc_freeres (void);1152 extern void __libc_freeres (void);
1153 __libc_freeres ();1153 __libc_freeres ();
tcc.h+5−1
@@ -285,7 +285,11 @@ extern char **environ; · 284 unmodified lines
285# if defined(TCC_MUSL)285# if defined(TCC_MUSL)
286# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"286# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"
287# else287# else
288# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"288# if defined(__OpenBSD__)
289# define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.so"
290# else
291# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
292# endif
289# endif293# endif
290# elif defined(TCC_TARGET_RISCV64)294# elif defined(TCC_TARGET_RISCV64)
291# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-riscv64-lp64d.so.1"295# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-riscv64-lp64d.so.1"
tccelf.c+56−4
@@ -1413,7 +1413,9 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 1412 unmodified lines
1413#ifdef CONFIG_TCC_BCHECK1413#ifdef CONFIG_TCC_BCHECK
1414 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {1414 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1415 tcc_add_library_err(s1, "pthread");1415 tcc_add_library_err(s1, "pthread");
1416#if !defined(__OpenBSD__)
1416 tcc_add_library_err(s1, "dl");1417 tcc_add_library_err(s1, "dl");
1418#endif
1417 tcc_add_support(s1, "bcheck.o");1419 tcc_add_support(s1, "bcheck.o");
1418 }1420 }
1419#endif1421#endif
@@ -1992,7 +1994,7 @@ static void put_dt(Section *dynamic, int dt, addr_t val) · 572 unmodified lines
1992}1994}
1993 1995
1994static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,1996static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1995 Section *dynamic)1997 Section *dynamic, Section *note)
1996{1998{
1997 ElfW(Phdr) *ph;1999 ElfW(Phdr) *ph;
1998 2000
@@ -2019,6 +2021,19 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp, · 20 unmodified lines
2019 ph->p_align = interp->sh_addralign;2021 ph->p_align = interp->sh_addralign;
2020 }2022 }
2021 2023
2024 if (note) {
2025 ph = &phdr[phnum - 2];
2026
2027 ph->p_type = PT_NOTE;
2028 ph->p_offset = note->sh_offset;
2029 ph->p_vaddr = note->sh_addr;
2030 ph->p_paddr = ph->p_vaddr;
2031 ph->p_filesz = note->sh_size;
2032 ph->p_memsz = note->sh_size;
2033 ph->p_flags = PF_R;
2034 ph->p_align = note->sh_addralign;
2035 }
2036
2022 /* if dynamic section, then add corresponding program header */2037 /* if dynamic section, then add corresponding program header */
2023 if (dynamic) {2038 if (dynamic) {
2024 ph = &phdr[phnum - 1];2039 ph = &phdr[phnum - 1];
@@ -2051,6 +2066,13 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) · 26 unmodified lines
2051 put_dt(dynamic, DT_RELA, dyninf->rel_addr);2066 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2052 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);2067 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2053 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));2068 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2069#ifdef __OpenBSD__
2070 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2071 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2072 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2073 put_dt(dynamic, DT_PLTREL, DT_RELA);
2074 put_dt(dynamic, DT_BIND_NOW, 1); /* Dirty hack */
2075#endif
2054#else2076#else
2055#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)2077#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2056 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);2078 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
@@ -2372,6 +2394,25 @@ static void create_arm_attribute_section(TCCState *s1) · 315 unmodified lines
2372}2394}
2373#endif2395#endif
2374 2396
2397#ifdef __OpenBSD__
2398static Section *create_openbsd_note_section(TCCState *s1)
2399{
2400 Section *s = find_section (s1, ".note.openbsd.ident");
2401
2402 if (s->data_offset == 0) {
2403 unsigned char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2404 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2405
2406 s->sh_type = SHT_NOTE;
2407 note->n_namesz = 8;
2408 note->n_descsz = 4;
2409 note->n_type = ELF_NOTE_OS_GNU;
2410 strcpy (ptr + sizeof(ElfW(Nhdr)), "OpenBSD");
2411 }
2412 return s;
2413}
2414#endif
2415
2375/* Output an elf, coff or binary file */2416/* Output an elf, coff or binary file */
2376/* XXX: suppress unneeded sections */2417/* XXX: suppress unneeded sections */
2377static int elf_output_file(TCCState *s1, const char *filename)2418static int elf_output_file(TCCState *s1, const char *filename)
@@ -2379,13 +2420,18 @@ static int elf_output_file(TCCState *s1, const char *filename) · 1 unmodified line
2379 int ret, phnum, shnum, file_type, file_offset, *sec_order;2420 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2380 struct dyn_inf dyninf = {0};2421 struct dyn_inf dyninf = {0};
2381 ElfW(Phdr) *phdr;2422 ElfW(Phdr) *phdr;
2382 Section *strsec, *interp, *dynamic, *dynstr;2423 Section *strsec, *interp, *dynamic, *dynstr, *note = NULL;
2424
2425 file_type = s1->output_type;
2383 2426
2384#ifdef TCC_TARGET_ARM2427#ifdef TCC_TARGET_ARM
2385 create_arm_attribute_section (s1);2428 create_arm_attribute_section (s1);
2386#endif2429#endif
2430#ifdef __OpenBSD__
2431 if (file_type != TCC_OUTPUT_OBJ)
2432 note = create_openbsd_note_section (s1);
2433#endif
2387 2434
2388 file_type = s1->output_type;
2389 s1->nb_errors = 0;2435 s1->nb_errors = 0;
2390 ret = -1;2436 ret = -1;
2391 phdr = NULL;2437 phdr = NULL;
@@ -2497,6 +2543,8 @@ static int elf_output_file(TCCState *s1, const char *filename) · 105 unmodified lines
2497 phnum = i < s1->nb_sections ? 6 : 5;2543 phnum = i < s1->nb_sections ? 6 : 5;
2498 }2544 }
2499 2545
2546 phnum += note != NULL;
2547
2500 /* allocate program segment headers */2548 /* allocate program segment headers */
2501 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));2549 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2502 2550
@@ -2515,7 +2563,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 12 unmodified lines
2515 /* Fill remaining program header and finalize relocation related to dynamic2563 /* Fill remaining program header and finalize relocation related to dynamic
2516 linking. */2564 linking. */
2517 if (file_type != TCC_OUTPUT_OBJ) {2565 if (file_type != TCC_OUTPUT_OBJ) {
2518 fill_unloadable_phdr(phdr, phnum, interp, dynamic);2566 fill_unloadable_phdr(phdr, phnum, interp, dynamic, note);
2519 if (dynamic) {2567 if (dynamic) {
2520 ElfW(Sym) *sym;2568 ElfW(Sym) *sym;
2521 dynamic->data_offset = dyninf.data_offset;2569 dynamic->data_offset = dyninf.data_offset;
@@ -2703,6 +2751,10 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 181 unmodified lines
2703 if (sh->sh_type != SHT_PROGBITS &&2751 if (sh->sh_type != SHT_PROGBITS &&
2704#ifdef TCC_ARM_EABI2752#ifdef TCC_ARM_EABI
2705 sh->sh_type != SHT_ARM_EXIDX &&2753 sh->sh_type != SHT_ARM_EXIDX &&
2754#endif
2755#ifdef __OpenBSD__
2756 sh->sh_type != SHT_X86_64_UNWIND &&
2757 sh->sh_type != SHT_NOTE &&
2706#endif2758#endif
2707 sh->sh_type != SHT_NOBITS &&2759 sh->sh_type != SHT_NOBITS &&
2708 sh->sh_type != SHT_PREINIT_ARRAY &&2760 sh->sh_type != SHT_PREINIT_ARRAY &&
tccrun.c+15−0
@@ -88,8 +88,23 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) · 87 unmodified lines
88 unlink(tmpfname);88 unlink(tmpfname);
89 ftruncate(fd, size);89 ftruncate(fd, size);
90 90
91#ifdef __OpenBSD__
92 { /* OpenBSD uses random 64 addresses that are far apart. This does not
93 work for the x86_64 target.
94 This might be a problem in the future for other targets. */
95 static char *prw = (char *) 0x100000000;
96 char *pex = prw + 0x40000000;
97
98 ptr = mmap (prw, size, PROT_READ|PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
99 prx = mmap (pex, size, PROT_READ|PROT_EXEC, MAP_SHARED | MAP_FIXED, fd, 0);
100 tcc_enter_state (s1);
101 prw += 0x100000000;
102 tcc_exit_state();
103 }
104#else
91 ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);105 ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
92 prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);106 prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
107#endif
93 if (ptr == MAP_FAILED || prx == MAP_FAILED)108 if (ptr == MAP_FAILED || prx == MAP_FAILED)
94 tcc_error("tccrun: could not map memory");109 tcc_error("tccrun: could not map memory");
95 dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);110 dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
tests/tcctest.c+1−1
@@ -2313,7 +2313,7 @@ int fib(int n) · 2312 unmodified lines
2313 return fib(n-1) + fib(n-2);2313 return fib(n-1) + fib(n-2);
2314}2314}
2315 2315
2316#if __GNUC__ == 32316#if __GNUC__ == 3 || __GNUC__ == 4
2317# define aligned_function 02317# define aligned_function 0
2318#else2318#else
2319void __attribute__((aligned(16))) aligned_function(int i) {}2319void __attribute__((aligned(16))) aligned_function(int i) {}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t