Subversion Repositories Kolibri OS

Rev

Rev 158 | 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
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
		{
83
			rel = (Elf32_Rel *) sr->data;
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;
91
			if (type != R_386_PC32 && type != R_386_32)
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);
159 halyavin 99
			if (ss==0)
100
				ss=me->bss_sections;
145 halyavin 101
			if (rel->r_offset>s->data_size)
102
				continue;
103
			if (type==R_386_PC32)
159 halyavin 104
				*(int*)(rel->r_offset+s->data)=ss->sh_addr+esym->st_value-rel->r_offset-s->sh_addr-4;
145 halyavin 105
			else if (type==R_386_32)
106
				*(int*)(rel->r_offset+s->data)+=ss->sh_addr+esym->st_value;
107
		}
108
        rel=rel_;
109
		s=s->next;
110
		if (s==0)
111
		{
112
			if (flag) break;
113
			s=me->data_sections;
114
			if (s==0) break;
115
			flag=1;
116
			continue;
117
		}
118
	}
119
}
120
 
121
void assign_addresses(me_info* me)
122
{
123
	int i;
124
	meos_section_info* si;
125
	for (i=1;is1->nb_sections;i++)
126
	{
127
		Section* s=me->s1->sections[i];
128
		if (strcmp(".text",s->name)==0)
129
		{
130
			si=tcc_malloc(sizeof(meos_section_info));
131
			si->data=s->data;
132
			si->data_size=s->data_offset;
133
			si->next=me->code_sections;
134
			si->sec_num=i;
135
			me->code_sections=si;
136
			continue;
137
		}
138
		if (strcmp(".data",s->name)==0)
139
		{
140
			si=tcc_malloc(sizeof(meos_section_info));
141
			si->data=s->data;
142
			si->data_size=s->data_offset;
143
			si->next=me->data_sections;
144
			si->sec_num=i;
145
			me->data_sections=si;
146
			continue;
147
		}
148
		if (strcmp(".bss",s->name)==0)
149
		{
150
			si=tcc_malloc(sizeof(meos_section_info));
151
			si->data_size=s->data_offset;
152
			si->next=me->bss_sections;
153
			si->sec_num=i;
154
			me->bss_sections=si;
155
			continue;
156
		}
157
	}
158
	int addr;
159
	addr=sizeof(IMAGE_MEOS_FILE_HEADER);
160
	for (si=me->code_sections;si;si=si->next)
161
	{
162
		si->sh_addr=addr;
163
		addr+=si->data_size;
164
	}
165
	for (si=me->data_sections;si;si=si->next)
166
	{
167
		si->sh_addr=addr;
168
		addr+=si->data_size;
169
	}
170
	me->header.image_size=addr;
171
	for (si=me->bss_sections;si;si=si->next)
172
	{
173
		si->sh_addr=addr;
174
		addr+=si->data_size;
175
	}
176
	addr+=4096;
177
	addr=(addr+4)&(~3);
178
	me->header.stack=addr;
179
	me->header.memory_size=addr;
180
	build_reloc(me);
181
}
182
int tcc_find_symbol_me(me_info* me, const char *sym_name)
183
{
184
	int i;
185
	int symtab;
186
	int strtab;
187
	symtab=0;
188
	strtab=0;
189
	for (i=1;is1->nb_sections;i++)
190
	{
191
		Section* s;
192
		s=me->s1->sections[i];
193
		if (strcmp(s->name,".symtab")==0)
194
		{
195
			symtab=i;
196
		}
197
		if (strcmp(s->name,".strtab")==0)
198
		{
199
			strtab=i;
200
		}
201
	}
202
	if (symtab==0 || strtab==0)
203
		return 0;
204
	Elf32_Sym* s,*se;
205
	char* name;
206
	s=(Elf32_Sym*)me->s1->sections[symtab]->data;
207
	se=(Elf32_Sym*)(((void*)s)+me->s1->sections[symtab]->data_offset);
208
	name=(char*)me->s1->sections[strtab]->data;
209
	while (s
210
	{
211
		if (strcmp(name+s->st_name,sym_name)==0)
212
		{
213
			return s->st_value+findsection(me,s->st_shndx)->sh_addr;
214
		}
215
		s++;
216
	}
217
	return 0;
218
}
219
const char* me_magic="MENUET01";
220
int tcc_output_me(TCCState* s1,const char *filename)
221
{
222
	me_info me;
223
    int i;
224
    FILE* f;
225
    //printf("%d\n",s1->nb_sections);
226
	memset(&me,0,sizeof(me));
227
	me.s1=s1;
228
	relocate_common_syms();
229
	assign_addresses(&me);
158 halyavin 230
	me.header.version=1;
145 halyavin 231
	me.header.entry_point=tcc_find_symbol_me(&me,"start");
232
	me.header.params= tcc_find_symbol_me(&me,"__argv"); // <--
233
	me.header.argv= tcc_find_symbol_me(&me,"__path"); // <--
234
 
235
	f=fopen(filename,"wb");
236
    for (i=0;i<8;i++)
237
        me.header.magic[i]=me_magic[i];
238
	/*me.header.magic[0]='M';me.header.magic[1]='E';
239
	me.header.magic[2]='N';me.header.magic[3]='U';
240
	me.header.magic[4]='E';me.header.magic[5]='T';
241
	me.header.magic[6]='0';me.header.magic[7]='1';*/
242
	fwrite(&me.header,1,sizeof(IMAGE_MEOS_FILE_HEADER),f);
243
	meos_section_info* si;
244
	for(si=me.code_sections;si;si=si->next)
245
		fwrite(si->data,1,si->data_size,f);
246
	for (si=me.data_sections;si;si=si->next)
247
		fwrite(si->data,1,si->data_size,f);
248
	fclose(f);
249
	return 0;
250
}