Subversion Repositories Kolibri OS

Rev

Rev 647 | Rev 6441 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
145 halyavin 1
/*
2
 *  TCCMEOS.C - KolibriOS/MenuetOS file output for the TinyC Compiler
3
 *
4
 *  Copyright (c) 2006 Andrey Khalyavin
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
609 andrew_pro 19
 */
20
 
21
typedef struct {
22
	char magic[8];
23
	int version;
24
	int entry_point;
25
	int image_size;
26
	int memory_size;
27
	int stack;
28
	int params;
29
	int argv;
30
} IMAGE_MEOS_FILE_HEADER,*PIMAGE_MEOS_FILE_HEADER;
31
typedef struct _meos_section_info{
32
	int sh_addr;
33
	void* data;
34
	int data_size;
35
	int sec_num;
36
	struct _meos_section_info* next;
37
} meos_section_info;
38
typedef struct {
39
	TCCState* s1;
40
	IMAGE_MEOS_FILE_HEADER header;
41
	meos_section_info* code_sections;
42
	meos_section_info* data_sections;
43
	meos_section_info* bss_sections;
44
} me_info;
45
 
46
meos_section_info* findsection(me_info* me,int num)
47
{
48
	meos_section_info* si;
49
	for(si=me->code_sections;si;si=si->next)
50
	{
51
		if (si->sec_num==num)
52
			return si;
53
	}
54
	for (si=me->data_sections;si;si=si->next)
55
	{
56
		if (si->sec_num==num)
57
			return si;
58
	}
59
	for (si=me->bss_sections;si;si=si->next)
60
	{
61
		if (si->sec_num==num)
62
			return si;
63
	}
64
	return (meos_section_info*)0;
65
}
66
 
67
void build_reloc(me_info* me)
68
{
69
	int flag;
70
	Elf32_Rel *rel, *rel_, *rel_end;
71
	Section *sr;
72
	meos_section_info* s;
73
	meos_section_info* ss;
74
	s=me->code_sections;
75
	rel=0;
76
	rel_end=0;
77
	flag=0;
78
	for(;;)
79
	{
80
		sr=me->s1->sections[s->sec_num]->reloc;
81
		if (sr)
82
		{
145 halyavin 83
			rel = (Elf32_Rel *) sr->data;
609 andrew_pro 84
			rel_end = (Elf32_Rel *) (sr->data + sr->data_offset);
85
		}
86
		rel_=rel;
87
		while (rel_
88
			rel=rel_;
89
			int type = ELF32_R_TYPE(rel->r_info);
90
			rel_=rel+1;
145 halyavin 91
			if (type != R_386_PC32 && type != R_386_32)
609 andrew_pro 92
				continue;
93
			int sym = ELF32_R_SYM(rel->r_info);
94
			if (sym>symtab_section->data_offset/sizeof(Elf32_Sym))
95
				continue;
96
			Elf32_Sym* esym = ((Elf32_Sym *)symtab_section->data)+sym;
97
			int sect=esym->st_shndx;
98
			ss=findsection(me,sect);
6429 siemargl 99
			if (ss==0)
100
			{
101
            	const char *sym_name = strtab_section->data + esym->st_name;
102
    			tcc_error_noabort("undefined symbol '%s'", sym_name);
103
				continue;
104
			}
609 andrew_pro 105
			if (rel->r_offset>s->data_size)
106
				continue;
107
			if (type==R_386_PC32)
108
				*(int*)(rel->r_offset+s->data)+=ss->sh_addr+esym->st_value-rel->r_offset-s->sh_addr;
109
			else if (type==R_386_32)
110
				*(int*)(rel->r_offset+s->data)+=ss->sh_addr+esym->st_value;
111
		}
112
        rel=rel_;
113
		s=s->next;
114
		if (s==0)
115
		{
116
			if (flag) break;
117
			s=me->data_sections;
118
			if (s==0) break;
119
			flag=1;
120
			continue;
121
		}
122
	}
123
}
124
 
125
void assign_addresses(me_info* me)
126
{
127
	int i;
128
	meos_section_info* si;
129
	for (i=1;is1->nb_sections;i++)
130
	{
131
		Section* s=me->s1->sections[i];
132
		if (strcmp(".text",s->name)==0)
133
		{
134
			si=tcc_malloc(sizeof(meos_section_info));
135
			si->data=s->data;
136
			si->data_size=s->data_offset;
137
			si->next=me->code_sections;
138
			si->sec_num=i;
139
			me->code_sections=si;
140
			continue;
141
		}
142
		if (strcmp(".data",s->name)==0)
143
		{
144
			si=tcc_malloc(sizeof(meos_section_info));
145
			si->data=s->data;
146
			si->data_size=s->data_offset;
147
			si->next=me->data_sections;
148
			si->sec_num=i;
149
			me->data_sections=si;
150
			continue;
151
		}
152
		if (strcmp(".bss",s->name)==0)
153
		{
154
			si=tcc_malloc(sizeof(meos_section_info));
155
			si->data_size=s->data_offset;
156
			si->next=me->bss_sections;
157
			si->sec_num=i;
158
			me->bss_sections=si;
159
			continue;
160
		}
161
	}
162
	int addr;
163
	addr=sizeof(IMAGE_MEOS_FILE_HEADER);
164
	for (si=me->code_sections;si;si=si->next)
165
	{
166
		si->sh_addr=addr;
167
		addr+=si->data_size;
168
	}
169
	for (si=me->data_sections;si;si=si->next)
170
	{
171
		si->sh_addr=addr;
172
		addr+=si->data_size;
173
	}
174
	me->header.image_size=addr;
175
	for (si=me->bss_sections;si;si=si->next)
176
	{
177
		si->sh_addr=addr;
178
		addr+=si->data_size;
179
	}
180
	addr+=4096;
181
	addr=(addr+4)&(~3);
182
	me->header.stack=addr;
183
	me->header.memory_size=addr;
184
	build_reloc(me);
185
}
6429 siemargl 186
 
187
 
188
const char *tcc_get_symbol_name(int st_name)
189
// return string by index from stringtable section
190
{
191
	const char *sym_name = strtab_section->data + st_name;
192
	return sym_name;
193
}
194
 
609 andrew_pro 195
int tcc_find_symbol_me(me_info* me, const char *sym_name)
196
{
197
	int i;
198
	int symtab;
199
	int strtab;
200
	symtab=0;
201
	strtab=0;
202
	for (i=1;is1->nb_sections;i++)
203
	{
204
		Section* s;
205
		s=me->s1->sections[i];
206
		if (strcmp(s->name,".symtab")==0)
207
		{
208
			symtab=i;
209
		}
210
		if (strcmp(s->name,".strtab")==0)
211
		{
212
			strtab=i;
213
		}
214
	}
215
	if (symtab==0 || strtab==0)
6429 siemargl 216
	{
217
        tcc_error_noabort("undefined sections .symtab or .strtab on linking '%s'", sym_name);
609 andrew_pro 218
		return 0;
6429 siemargl 219
	}
609 andrew_pro 220
	Elf32_Sym* s,*se;
221
	char* name;
222
	s=(Elf32_Sym*)me->s1->sections[symtab]->data;
223
	se=(Elf32_Sym*)(((void*)s)+me->s1->sections[symtab]->data_offset);
224
	name=(char*)me->s1->sections[strtab]->data;
225
	while (s
226
	{
227
		if (strcmp(name+s->st_name,sym_name)==0)
228
		{
229
			return s->st_value+findsection(me,s->st_shndx)->sh_addr;
230
		}
231
		s++;
232
	}
6429 siemargl 233
    tcc_error_noabort("undefined symbol '%s'", sym_name);
609 andrew_pro 234
	return 0;
235
}
6429 siemargl 236
 
609 andrew_pro 237
const char* me_magic="MENUET01";
238
int tcc_output_me(TCCState* s1,const char *filename)
239
{
240
	me_info me;
241
    int i;
242
    FILE* f;
243
    //printf("%d\n",s1->nb_sections);
244
	memset(&me,0,sizeof(me));
245
	me.s1=s1;
246
	relocate_common_syms();
247
	assign_addresses(&me);
248
	me.header.entry_point=tcc_find_symbol_me(&me,"start");
249
	me.header.params= tcc_find_symbol_me(&me,"__argv"); // <--
250
	me.header.argv= tcc_find_symbol_me(&me,"__path"); // <--
251
 
252
	f=fopen(filename,"wb");
253
    for (i=0;i<8;i++)
254
        me.header.magic[i]=me_magic[i];
255
	/*me.header.magic[0]='M';me.header.magic[1]='E';
256
	me.header.magic[2]='N';me.header.magic[3]='U';
257
	me.header.magic[4]='E';me.header.magic[5]='T';
258
	me.header.magic[6]='0';me.header.magic[7]='1';*/
259
	fwrite(&me.header,1,sizeof(IMAGE_MEOS_FILE_HEADER),f);
260
	meos_section_info* si;
261
	for(si=me.code_sections;si;si=si->next)
262
		fwrite(si->data,1,si->data_size,f);
263
	for (si=me.data_sections;si;si=si->next)
264
		fwrite(si->data,1,si->data_size,f);
265
	fclose(f);
266
	return 0;
267
}
6429 siemargl 268
 
269
#ifndef _WIN32
270
 
271
static inline int get_current_folder(char* buf, int bufsize){
272
    register int val;
273
    asm volatile ("int $0x40":"=a"(val):"a"(30), "b"(2), "c"(buf), "d"(bufsize));
274
    return val;
275
}
276
 
277
 
278
char *getcwd(char *buf, size_t size)
279
{
280
	int rc = get_current_folder(buf, size);
281
	if (rc > size)
282
	{
283
		errno = ERANGE;
284
		return 0;
285
	}
286
	else
287
		return buf;
288
}
289
 
290
#endif