Rev 9284 | Rev 9513 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
9284 | Coldy | 1 | /* |
2 | * TCCKX.C - KolibriOS/KX file output for the TinyC Compiler |
||
3 | * |
||
4 | * Copyright (c) 2021 Coldy |
||
5 | * |
||
6 | * This library is free software; you can redistribute it and/or |
||
7 | * modify it under the terms of the GNU Lesser General Public |
||
8 | * License as published by the Free Software Foundation; either |
||
9 | * version 2 of the License, or (at your option) any later version. |
||
10 | * |
||
11 | * This library is distributed in the hope that it will be useful, |
||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
14 | * Lesser General Public License for more details. |
||
15 | * |
||
16 | * You should have received a copy of the GNU Lesser General Public |
||
17 | * License along with this library; if not, write to the Free Software |
||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
19 | */ |
||
20 | |||
21 | typedef struct { |
||
22 | char magic[4]; |
||
23 | long flags; |
||
24 | long i_ptr; |
||
25 | } kx_header; |
||
26 | |||
27 | static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; |
||
28 | |||
9305 | Coldy | 29 | typedef struct { |
9284 | Coldy | 30 | uint32_t ImportEntry; |
31 | uint32_t LibraryName; |
||
9305 | Coldy | 32 | } LibraryEntry; |
9284 | Coldy | 33 | |
34 | /*union ImportEntry { |
||
35 | uint32_t ImportStr; |
||
36 | uint32_t ImportPrt; |
||
37 | };*/ |
||
38 | |||
39 | //static char __kx_import_table_sym[] = "__i_ptr__"; |
||
40 | |||
41 | void kx_build_imports(me_info* me) { |
||
42 | |||
43 | ElfW(Sym) *sym; |
||
44 | int sym_index, sym_end; |
||
45 | sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); |
||
9305 | Coldy | 46 | CString *str_arr, *len_arr, *sym_arr; |
47 | char dll_len; |
||
9284 | Coldy | 48 | int nlib = 0; |
49 | int i; |
||
50 | |||
51 | if (me->header.version != 2) |
||
52 | return; |
||
53 | |||
54 | str_arr = tcc_malloc(sizeof(CString) * me->s1->nb_loaded_dlls); |
||
55 | |||
56 | len_arr = tcc_malloc(sizeof(CString)* me->s1->nb_loaded_dlls); |
||
9305 | Coldy | 57 | |
58 | sym_arr = tcc_malloc(sizeof(CString)* me->s1->nb_loaded_dlls); |
||
9284 | Coldy | 59 | |
60 | for (sym_index = 1; sym_index < sym_end; ++sym_index) { |
||
61 | sym = (ElfW(Sym) *)symtab_section->data + sym_index; |
||
62 | if (sym->st_shndx == SHN_UNDEF) { |
||
63 | const char *name = symtab_section->link->data + sym->st_name; |
||
64 | int dynsym_index = find_elf_sym(me->s1->dynsymtab_section, name); |
||
65 | |||
66 | if (dynsym_index == 0) { |
||
67 | //if (strcmp(name, __kx_import_table_sym) != 0) { |
||
68 | tcc_error/*_noabort*/("undefined symbol '%s'", name); |
||
69 | //continue; // FIXME: stop compile! |
||
70 | //} |
||
71 | |||
72 | //continue; |
||
73 | } |
||
74 | |||
75 | // KOS support 32 bit only |
||
76 | Elf32_Sym* dyn_sym = &((ElfW(Sym) *)me->s1->dynsymtab_section->data)[dynsym_index]; |
||
77 | DLLReference **dllref = me->s1->loaded_dlls; |
||
9305 | Coldy | 78 | char* dll_name; |
9284 | Coldy | 79 | i = dyn_sym->st_size - 1; |
80 | // TCC store dll index in dyn_sym->st_size field |
||
81 | if (dllref[i]->level != -1) { |
||
9305 | Coldy | 82 | dll_name = dllref[i]->name; |
83 | dll_len = strlen(dll_name) + 1; |
||
9284 | Coldy | 84 | |
85 | nlib++; |
||
86 | |||
87 | cstr_new(&str_arr[i]); |
||
88 | cstr_new(&len_arr[i]); |
||
9305 | Coldy | 89 | cstr_new(&sym_arr[i]); |
9284 | Coldy | 90 | |
91 | cstr_ccat(&len_arr[i], dll_len); |
||
92 | cstr_cat(&str_arr[i], dll_name, dll_len); |
||
93 | //Mark dll as already used |
||
94 | dllref[i]->level = -1; |
||
95 | } |
||
9305 | Coldy | 96 | |
97 | cstr_wccat(&sym_arr[i], (int)name); |
||
9284 | Coldy | 98 | |
9305 | Coldy | 99 | // Export defined with prefix? |
100 | if (dyn_sym->st_value == -1){ |
||
101 | name += (dll_len - 4); // skip prefix_ |
||
102 | } |
||
103 | |||
9284 | Coldy | 104 | char name_len = strlen(name) + 1; |
105 | cstr_ccat(&len_arr[i], name_len); |
||
106 | cstr_cat(&str_arr[i], name, name_len); |
||
107 | |||
108 | } |
||
109 | } |
||
110 | |||
111 | /*if (len_arr[0].size == 0) |
||
112 | { |
||
113 | |||
114 | //tcc_error(""); |
||
115 | return; |
||
116 | }*/ |
||
117 | |||
118 | // Zero terminate of ptr (was BUG#3) |
||
119 | i = 0; |
||
120 | do { |
||
121 | |||
122 | cstr_ccat(&len_arr[i], 0); |
||
123 | |||
124 | i++; |
||
125 | |||
126 | } while (i < nlib); |
||
127 | |||
128 | kx_import_table* imp_sect; |
||
129 | |||
130 | imp_sect = tcc_mallocz(sizeof(kx_import_table)); |
||
131 | imp_sect->data = tcc_mallocz(1024); // FIXME!!! |
||
132 | imp_sect->data_size = 0; |
||
133 | //imp_sect->sh_addr = me->header.image_size;// +1; |
||
134 | |||
9305 | Coldy | 135 | long imp_data = (long)imp_sect->data; //FIXED changed to long for gcc compatible |
9284 | Coldy | 136 | |
137 | // Strings |
||
138 | i = 0; |
||
139 | do { |
||
9305 | Coldy | 140 | memcpy((void*)imp_data, str_arr[i].data, str_arr[i].size); |
9284 | Coldy | 141 | imp_data += str_arr[i].size; |
142 | imp_sect->data_size += str_arr[i].size; |
||
143 | |||
144 | i++; |
||
145 | |||
146 | } while (i < nlib); |
||
147 | |||
148 | // Align pad (check algorithm!) |
||
149 | int align = 4 - (me->header.image_size + imp_sect->data_size) % 4; |
||
150 | imp_data += align; |
||
151 | imp_sect->data_size += align; |
||
152 | |||
153 | /*add_elf_sym( |
||
154 | me->s1->dynsymtab_section, |
||
155 | me->header.image_size + imp_sect->data_size, |
||
156 | 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), |
||
157 | 0, SHN_ABS, __kx_import_table_sym);*/ |
||
158 | __kx_header.i_ptr = me->header.image_size + imp_sect->data_size; |
||
159 | |||
9305 | Coldy | 160 | LibraryEntry lib; |
9284 | Coldy | 161 | lib.ImportEntry = me->header.image_size + imp_sect->data_size + (nlib * 8) + 4; |
162 | lib.LibraryName = me->header.image_size + 0; |
||
163 | |||
164 | // LibraryEntry |
||
9305 | Coldy | 165 | memcpy((void*)imp_data, &lib, sizeof(LibraryEntry)); |
9284 | Coldy | 166 | |
167 | if (nlib > 1) { |
||
9305 | Coldy | 168 | int prev_sum = 0; |
9284 | Coldy | 169 | int prev = 0; |
170 | i = 1; |
||
171 | do { |
||
172 | lib.ImportEntry += (len_arr[prev].size - 2) * 4 + 4; //TODO: check that +4 is correct |
||
9305 | Coldy | 173 | prev_sum += str_arr[prev].size; |
174 | lib.LibraryName = me->header.image_size + prev_sum; // FIXED (was BUG#10) |
||
175 | imp_data += sizeof(LibraryEntry); |
||
176 | imp_sect->data_size += sizeof(LibraryEntry); |
||
177 | memcpy((void*)imp_data, &lib, sizeof(LibraryEntry)); |
||
9284 | Coldy | 178 | |
179 | prev++; |
||
180 | i++; |
||
181 | |||
182 | } while (i < nlib); |
||
183 | } |
||
184 | |||
185 | // End of LibraryEntry |
||
9305 | Coldy | 186 | imp_data += sizeof(LibraryEntry) + 4; |
187 | imp_sect->data_size += sizeof(LibraryEntry) + 4; |
||
9284 | Coldy | 188 | |
9305 | Coldy | 189 | const char *sym_name; |
190 | char name_len; |
||
191 | long len_sum; |
||
9284 | Coldy | 192 | |
9305 | Coldy | 193 | len_sum = me->header.image_size; |
9284 | Coldy | 194 | i = 0; |
195 | do { |
||
196 | char* len_data = len_arr[i].data; |
||
9305 | Coldy | 197 | long* sym_data = sym_arr[i].data; |
9284 | Coldy | 198 | |
199 | name_len = *len_data++; // Skip library name |
||
200 | |||
201 | do { |
||
9305 | Coldy | 202 | |
203 | memcpy(&sym_name, sym_data++, 4); |
||
9284 | Coldy | 204 | |
205 | add_elf_sym( |
||
206 | me->s1->dynsymtab_section, |
||
207 | me->header.image_size + imp_sect->data_size, |
||
208 | 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), |
||
9305 | Coldy | 209 | 0, SHN_ABS, sym_name); |
9284 | Coldy | 210 | |
9305 | Coldy | 211 | len_sum += name_len; |
212 | memcpy((void*)imp_data, &len_sum, 4); |
||
9284 | Coldy | 213 | |
214 | imp_data += 4; |
||
215 | imp_sect->data_size += 4; |
||
216 | name_len = */*++*/len_data/*++*/; //(was BUG#3) |
||
217 | |||
218 | } while (/*name_len*/*(++len_data) > 0); |
||
219 | |||
220 | imp_data += 4; |
||
221 | imp_sect->data_size += 4; |
||
222 | |||
9305 | Coldy | 223 | len_sum += name_len; |
9284 | Coldy | 224 | i++; |
225 | |||
226 | } while (i < nlib); |
||
227 | |||
228 | me->header.image_size += imp_sect->data_size; |
||
229 | me->imp_table = imp_sect; |
||
230 | |||
231 | tcc_free(str_arr); |
||
232 | tcc_free(len_arr); |
||
9305 | Coldy | 233 | tcc_free(sym_arr); |
9284 | Coldy | 234 | |
235 | } |
||
236 | |||
237 | |||
238 | |||
239 | void kx_init(me_info* me) { |
||
240 | ElfW(Sym) *sym; |
||
241 | int sym_index = 1, sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); |
||
242 | // Check that we have at last one import... |
||
243 | for (; sym_index < sym_end; ++sym_index) { |
||
244 | sym = (ElfW(Sym) *)symtab_section->data + sym_index; |
||
245 | if (sym->st_shndx == SHN_UNDEF) |
||
246 | break; |
||
247 | } |
||
248 | if ((sym_index < sym_end) && |
||
249 | // ... and user attached at last one *.def |
||
250 | (me->s1->nb_loaded_dlls)) |
||
251 | me->header.version = 2; |
||
252 | |||
253 | //tcc_add_crt(me->s1, "start1.o"); |
||
254 | } |
||
255 | |||
256 | long kx_get_header_length(me_info* me) { |
||
9305 | Coldy | 257 | if (me->header.version == 2) |
9284 | Coldy | 258 | return sizeof(kx_header); |
259 | |||
260 | return 0; |
||
261 | } |
||
262 | |||
263 | void kx_write_header(me_info* me, FILE* f) { |
||
9305 | Coldy | 264 | if (me->header.version == 2) |
9284 | Coldy | 265 | fwrite(&__kx_header, 1, sizeof(kx_header), f); |
266 | } |
||
267 | |||
268 | void kx_write_imports(me_info* me, FILE* f) { |
||
269 | if (me->imp_table) |
||
270 | fwrite(me->imp_table->data, 1, me->imp_table->data_size, f); |
||
271 | |||
272 | } |
||
273 | |||
274 | void kx_free(me_info* me) { |
||
275 | kx_import_table* imp = me->imp_table; |
||
276 | if (imp){ |
||
277 | tcc_free(imp->data); |
||
278 | tcc_free(imp); |
||
279 | } |
||
280 | }>>>>>>> |