Subversion Repositories Kolibri OS

Rev

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
 }