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
29082908
29092909 #define R_X86_64_NUM 43
29102910
2911+/* x86-64 sh_type values. */
2912+#define SHT_X86_64_UNWIND 0x70000001 /* Unwind information. */
29112913
29122914 /* AM33 relocations. */
29132915 #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
11471147 dprintf(stderr, "%s, %s():\n", __FILE__, __FUNCTION__);
11481148
11491149 if (inited) {
1150−#if !defined(_WIN32) && !defined(__APPLE__)
1150+#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__)
11511151 if (print_heap) {
11521152 extern void __libc_freeres (void);
11531153 __libc_freeres ();
tcc.h+5−1
@@ -285,7 +285,11 @@ extern char **environ; · 284 unmodified lines
285285 # if defined(TCC_MUSL)
286286 # define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"
287287 # 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
289293 # endif
290294 # elif defined(TCC_TARGET_RISCV64)
291295 # 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
14131413 #ifdef CONFIG_TCC_BCHECK
14141414 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
14151415 tcc_add_library_err(s1, "pthread");
1416+#if !defined(__OpenBSD__)
14161417 tcc_add_library_err(s1, "dl");
1418+#endif
14171419 tcc_add_support(s1, "bcheck.o");
14181420 }
14191421 #endif
@@ -1992,7 +1994,7 @@ static void put_dt(Section *dynamic, int dt, addr_t val) · 572 unmodified lines
19921994 }
19931995
19941996 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1995− Section *dynamic)
1997+ Section *dynamic, Section *note)
19961998 {
19971999 ElfW(Phdr) *ph;
19982000
@@ -2019,6 +2021,19 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp, · 20 unmodified lines
20192021 ph->p_align = interp->sh_addralign;
20202022 }
20212023
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+
20222037 /* if dynamic section, then add corresponding program header */
20232038 if (dynamic) {
20242039 ph = &phdr[phnum - 1];
@@ -2051,6 +2066,13 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) · 26 unmodified lines
20512066 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
20522067 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
20532068 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
20542076 #else
20552077 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
20562078 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
@@ -2372,6 +2394,25 @@ static void create_arm_attribute_section(TCCState *s1) · 315 unmodified lines
23722394 }
23732395 #endif
23742396
2397+#ifdef __OpenBSD__
2398+static 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+
23752416 /* Output an elf, coff or binary file */
23762417 /* XXX: suppress unneeded sections */
23772418 static 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
23792420 int ret, phnum, shnum, file_type, file_offset, *sec_order;
23802421 struct dyn_inf dyninf = {0};
23812422 ElfW(Phdr) *phdr;
2382− Section *strsec, *interp, *dynamic, *dynstr;
2423+ Section *strsec, *interp, *dynamic, *dynstr, *note = NULL;
2424+
2425+ file_type = s1->output_type;
23832426
23842427 #ifdef TCC_TARGET_ARM
23852428 create_arm_attribute_section (s1);
23862429 #endif
2430+#ifdef __OpenBSD__
2431+ if (file_type != TCC_OUTPUT_OBJ)
2432+ note = create_openbsd_note_section (s1);
2433+#endif
23872434
2388− file_type = s1->output_type;
23892435 s1->nb_errors = 0;
23902436 ret = -1;
23912437 phdr = NULL;
@@ -2497,6 +2543,8 @@ static int elf_output_file(TCCState *s1, const char *filename) · 105 unmodified lines
24972543 phnum = i < s1->nb_sections ? 6 : 5;
24982544 }
24992545
2546+ phnum += note != NULL;
2547+
25002548 /* allocate program segment headers */
25012549 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
25022550
@@ -2515,7 +2563,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 12 unmodified lines
25152563 /* Fill remaining program header and finalize relocation related to dynamic
25162564 linking. */
25172565 if (file_type != TCC_OUTPUT_OBJ) {
2518− fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2566+ fill_unloadable_phdr(phdr, phnum, interp, dynamic, note);
25192567 if (dynamic) {
25202568 ElfW(Sym) *sym;
25212569 dynamic->data_offset = dyninf.data_offset;
@@ -2703,6 +2751,10 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 181 unmodified lines
27032751 if (sh->sh_type != SHT_PROGBITS &&
27042752 #ifdef TCC_ARM_EABI
27052753 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 &&
27062758 #endif
27072759 sh->sh_type != SHT_NOBITS &&
27082760 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
8888 unlink(tmpfname);
8989 ftruncate(fd, size);
9090
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
91105 ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
92106 prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
107+#endif
93108 if (ptr == MAP_FAILED || prx == MAP_FAILED)
94109 tcc_error("tccrun: could not map memory");
95110 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
23132313 return fib(n-1) + fib(n-2);
23142314 }
23152315
2316−#if __GNUC__ == 3
2316+#if __GNUC__ == 3 || __GNUC__ == 4
23172317 # define aligned_function 0
23182318 #else
23192319 void __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