Subversion Repositories Kolibri OS

Rev

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