Rev 6429 | Rev 6443 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6429 | Rev 6441 | ||
---|---|---|---|
Line 41... | Line 41... | ||
41 | meos_section_info* code_sections; |
41 | meos_section_info* code_sections; |
42 | meos_section_info* data_sections; |
42 | meos_section_info* data_sections; |
43 | meos_section_info* bss_sections; |
43 | meos_section_info* bss_sections; |
44 | } me_info; |
44 | } me_info; |
Line -... | Line 45... | ||
- | 45 | ||
- | 46 | int tcc_output_dbgme(const char *filename, me_info* me); |
|
- | 47 | ||
45 | 48 | ||
46 | meos_section_info* findsection(me_info* me,int num) |
49 | meos_section_info* findsection(me_info* me,int num) |
47 | { |
50 | { |
48 | meos_section_info* si; |
51 | meos_section_info* si; |
49 | for(si=me->code_sections;si;si=si->next) |
52 | for(si=me->code_sections;si;si=si->next) |
Line 65... | Line 68... | ||
65 | } |
68 | } |
Line 66... | Line 69... | ||
66 | 69 | ||
67 | void build_reloc(me_info* me) |
70 | void build_reloc(me_info* me) |
68 | { |
71 | { |
69 | int flag; |
72 | int flag; |
70 | Elf32_Rel *rel, *rel_, *rel_end; |
73 | Elf32_Rel *rel = 0, *rel_ = 0, *rel_end = 0; |
71 | Section *sr; |
74 | Section *sr; |
72 | meos_section_info* s; |
75 | meos_section_info* s; |
73 | meos_section_info* ss; |
76 | meos_section_info* ss; |
74 | s=me->code_sections; |
77 | s=me->code_sections; |
Line 109... | Line 112... | ||
109 | else if (type==R_386_32) |
112 | else if (type==R_386_32) |
110 | *(int*)(rel->r_offset+s->data)+=ss->sh_addr+esym->st_value; |
113 | *(int*)(rel->r_offset+s->data)+=ss->sh_addr+esym->st_value; |
111 | } |
114 | } |
112 | rel=rel_; |
115 | rel=rel_; |
113 | s=s->next; |
116 | s=s->next; |
114 | if (s==0) |
117 | if (s==0) // what about multiple BSS sections ? |
115 | { |
118 | { |
116 | if (flag) break; |
119 | if (flag) break; |
117 | s=me->data_sections; |
120 | s=me->data_sections; |
118 | if (s==0) break; |
121 | if (s==0) break; |
119 | flag=1; |
122 | flag=1; |
Line 150... | Line 153... | ||
150 | continue; |
153 | continue; |
151 | } |
154 | } |
152 | if (strcmp(".bss",s->name)==0) |
155 | if (strcmp(".bss",s->name)==0) |
153 | { |
156 | { |
154 | si=tcc_malloc(sizeof(meos_section_info)); |
157 | si=tcc_malloc(sizeof(meos_section_info)); |
- | 158 | si->data=s->data; |
|
155 | si->data_size=s->data_offset; |
159 | si->data_size=s->data_offset; |
156 | si->next=me->bss_sections; |
160 | si->next=me->bss_sections; |
157 | si->sec_num=i; |
161 | si->sec_num=i; |
158 | me->bss_sections=si; |
162 | me->bss_sections=si; |
159 | continue; |
163 | continue; |
Line 175... | Line 179... | ||
175 | for (si=me->bss_sections;si;si=si->next) |
179 | for (si=me->bss_sections;si;si=si->next) |
176 | { |
180 | { |
177 | si->sh_addr=addr; |
181 | si->sh_addr=addr; |
178 | addr+=si->data_size; |
182 | addr+=si->data_size; |
179 | } |
183 | } |
- | 184 | if (me->s1->pe_stack_size < 4096) |
|
180 | addr+=4096; |
185 | addr+=4096; |
- | 186 | else |
|
- | 187 | addr += me->s1->pe_stack_size; |
|
181 | addr=(addr+4)&(~3); |
188 | addr=(addr+4)&(~3); |
182 | me->header.stack=addr; |
189 | me->header.stack=addr; |
183 | me->header.memory_size=addr; |
190 | me->header.memory_size=addr; |
184 | build_reloc(me); |
191 | build_reloc(me); |
185 | } |
192 | } |
Line 243... | Line 250... | ||
243 | //printf("%d\n",s1->nb_sections); |
250 | //printf("%d\n",s1->nb_sections); |
244 | memset(&me,0,sizeof(me)); |
251 | memset(&me,0,sizeof(me)); |
245 | me.s1=s1; |
252 | me.s1=s1; |
246 | relocate_common_syms(); |
253 | relocate_common_syms(); |
247 | assign_addresses(&me); |
254 | assign_addresses(&me); |
- | 255 | ||
- | 256 | if (s1->do_debug) |
|
- | 257 | tcc_output_dbgme(filename, &me); |
|
- | 258 | ||
248 | me.header.entry_point=tcc_find_symbol_me(&me,"start"); |
259 | me.header.entry_point=tcc_find_symbol_me(&me,"start"); |
249 | me.header.params= tcc_find_symbol_me(&me,"__argv"); // <-- |
260 | me.header.params= tcc_find_symbol_me(&me,"__argv"); // <-- |
250 | me.header.argv= tcc_find_symbol_me(&me,"__path"); // <-- |
261 | me.header.argv= tcc_find_symbol_me(&me,"__path"); // <-- |
Line 251... | Line 262... | ||
251 | 262 | ||
Line 260... | Line 271... | ||
260 | meos_section_info* si; |
271 | meos_section_info* si; |
261 | for(si=me.code_sections;si;si=si->next) |
272 | for(si=me.code_sections;si;si=si->next) |
262 | fwrite(si->data,1,si->data_size,f); |
273 | fwrite(si->data,1,si->data_size,f); |
263 | for (si=me.data_sections;si;si=si->next) |
274 | for (si=me.data_sections;si;si=si->next) |
264 | fwrite(si->data,1,si->data_size,f); |
275 | fwrite(si->data,1,si->data_size,f); |
- | 276 | for (si=me.bss_sections;si;si=si->next) |
|
- | 277 | fwrite(si->data,1,si->data_size,f); |
|
- | 278 | /* |
|
- | 279 | if (me.bss_sections) // Siemargl testin, what we lose |
|
- | 280 | { |
|
- | 281 | tcc_error_noabort("We lose .BSS section when linking KOS32 executable"); |
|
- | 282 | } |
|
- | 283 | */ |
|
265 | fclose(f); |
284 | fclose(f); |
266 | return 0; |
285 | return 0; |
267 | } |
286 | } |
Line 268... | Line 287... | ||
268 | 287 | ||
Line 286... | Line 305... | ||
286 | else |
305 | else |
287 | return buf; |
306 | return buf; |
288 | } |
307 | } |
Line 289... | Line 308... | ||
289 | 308 | ||
- | 309 | #endif |
|
- | 310 | ||
- | 311 | ||
- | 312 | static FILE *src_file; |
|
- | 313 | static int next_src_line; |
|
- | 314 | ||
- | 315 | void close_source_file() |
|
- | 316 | { |
|
- | 317 | if (src_file) |
|
- | 318 | fclose(src_file); |
|
- | 319 | src_file = NULL; |
|
- | 320 | } |
|
- | 321 | ||
- | 322 | void load_source_file(char *fname) |
|
- | 323 | { |
|
- | 324 | close_source_file(); |
|
- | 325 | src_file = fopen(fname,"rt"); |
|
- | 326 | if (!src_file) return; |
|
- | 327 | next_src_line = 1; |
|
- | 328 | } |
|
- | 329 | ||
- | 330 | int get_src_lines(char *buf, int sz, int start, int end) |
|
- | 331 | // 1 if read |
|
- | 332 | { |
|
- | 333 | char line[255], *ch; |
|
- | 334 | strcpy(buf, ""); |
|
- | 335 | if (!src_file) return 0; |
|
- | 336 | while (next_src_line < start) // skip |
|
- | 337 | { |
|
- | 338 | ch = fgets(line, sizeof line, src_file); |
|
- | 339 | if (!ch) return 0; |
|
- | 340 | next_src_line++; |
|
- | 341 | } |
|
- | 342 | while (next_src_line <= end) |
|
- | 343 | { |
|
- | 344 | ch = fgets(line, sizeof line, src_file); |
|
- | 345 | if (!ch) return 0; |
|
- | 346 | next_src_line++; |
|
- | 347 | strncat(buf, line, sz - strlen(buf) - 1); |
|
- | 348 | } |
|
- | 349 | // remove newlines |
|
- | 350 | for (ch = buf; *ch; ch++) |
|
- | 351 | if (strchr("\t\n\r", *ch)) *ch = ' '; |
|
- | 352 | ||
- | 353 | return 1; |
|
- | 354 | } |
|
- | 355 | ||
- | 356 | int tcc_output_dbgme(const char *filename, me_info* me) |
|
- | 357 | // by Siemargl. Writes filename.dbg file for source code level debuggin with MTDBG |
|
- | 358 | // return 1 on error |
|
- | 359 | { |
|
- | 360 | FILE *fdbg; |
|
- | 361 | char fname[400], buf[200]; |
|
- | 362 | ||
- | 363 | strcpy(fname, filename); |
|
- | 364 | strcat(fname, ".dbg"); |
|
- | 365 | fdbg = fopen(fname,"wt"); |
|
- | 366 | if (!fdbg) return 1; |
|
- | 367 | ||
- | 368 | meos_section_info *si, *ss; |
|
- | 369 | fputs(".text\n", fdbg); // just for mtbg |
|
- | 370 | ||
- | 371 | // print symbol table with resolved addresses |
|
- | 372 | Elf32_Sym* esym; |
|
- | 373 | for (esym = (Elf32_Sym*)symtab_section->data; esym <= (Elf32_Sym*)(symtab_section->data + symtab_section->data_offset); esym++) |
|
- | 374 | { |
|
- | 375 | if (esym->st_info == 0 || esym->st_info == 4) continue; |
|
- | 376 | int sect = esym->st_shndx; |
|
- | 377 | ss = findsection(me, sect); |
|
- | 378 | const char *sym_name = strtab_section->data + esym->st_name; |
|
- | 379 | if (ss == 0) |
|
- | 380 | { |
|
- | 381 | fprintf(fdbg, "undefined symbol '%s' type(%d)\n", sym_name, esym->st_info); |
|
- | 382 | continue; |
|
- | 383 | } |
|
- | 384 | fprintf(fdbg, "0x%X %s\n", ss->sh_addr + esym->st_value, sym_name); // removed type(%d) esym->st_info |
|
- | 385 | } |
|
- | 386 | ||
- | 387 | fputs(".text source code links\n", fdbg); // just for mtbg |
|
- | 388 | // print symbol table with resolved addresses |
|
- | 389 | Stab_Sym *stab; |
|
- | 390 | char *str = "", *cur_file = "???", cur_fun[255]; |
|
- | 391 | int cur_line = 0, cur_fun_addr = 0, fun_flag = 0; |
|
- | 392 | strcpy(cur_fun, "fn???"); |
|
- | 393 | for (stab = (Stab_Sym*)stab_section->data; stab <= (Stab_Sym*)(stab_section->data + stab_section->data_offset); stab++) |
|
- | 394 | { |
|
- | 395 | str = ""; |
|
- | 396 | switch(stab->n_type) |
|
- | 397 | { |
|
- | 398 | case 100: // source file, or path |
|
- | 399 | if (stab->n_strx) |
|
- | 400 | { |
|
- | 401 | cur_file = stabstr_section->data + stab->n_strx; |
|
- | 402 | load_source_file(cur_file); |
|
- | 403 | } |
|
- | 404 | else |
|
- | 405 | cur_file = "???"; |
|
- | 406 | strcpy(cur_fun, "fn???"); |
|
- | 407 | cur_line = 0; |
|
- | 408 | cur_fun_addr = 0; |
|
- | 409 | fun_flag = 0; |
|
- | 410 | break; |
|
- | 411 | case 36: // func |
|
- | 412 | cur_fun_addr = 0; |
|
- | 413 | if (stab->n_strx) |
|
- | 414 | { |
|
- | 415 | strcpy(cur_fun, stabstr_section->data + stab->n_strx); |
|
- | 416 | str = strchr(cur_fun, ':'); |
|
- | 417 | if (str) *str = '\0'; |
|
- | 418 | cur_fun_addr = tcc_find_symbol_me(me, cur_fun); |
|
- | 419 | cur_line = stab->n_desc; |
|
- | 420 | fun_flag = 1; |
|
- | 421 | //fprintf(fdbg, "0x%X %s() line(%d)\n", cur_fun_addr, cur_fun, cur_line); // commented as conflicted with direct address |
|
- | 422 | } |
|
- | 423 | else |
|
- | 424 | strcpy(cur_fun, "fn???"); |
|
- | 425 | break; |
|
- | 426 | case 68: // N_SLINE |
|
- | 427 | if (stab->n_value == 0 ) continue; // skip zero offset line |
|
- | 428 | if (fun_flag) // skip string {, as duplicates address |
|
- | 429 | { |
|
- | 430 | fun_flag = 0; |
|
- | 431 | continue; |
|
- | 432 | } |
|
- | 433 | ||
- | 434 | int line; |
|
- | 435 | if (stab->n_desc > cur_line) |
|
- | 436 | line = cur_line + 1; |
|
- | 437 | else |
|
- | 438 | line = cur_line; |
|
- | 439 | //fprintf(fdbg, "0x%X LINES %d-%d \n", cur_fun_addr + stab->n_value, line, stab->n_desc); |
|
- | 440 | if (get_src_lines(buf, sizeof buf, line, stab->n_desc)) |
|
- | 441 | fprintf(fdbg, "0x%X %s\n", cur_fun_addr + stab->n_value, buf); |
|
- | 442 | ||
- | 443 | cur_line = stab->n_desc; |
|
- | 444 | break; |
|
- | 445 | default: |
|
- | 446 | continue; |
|
- | 447 | } |
|
- | 448 | /* |
|
- | 449 | if (stab->n_strx) |
|
- | 450 | str = stabstr_section->data + stab->n_strx; |
|
- | 451 | fprintf(fdbg, "0x%X type(%d) str(%s) desc(%d)\n", stab->n_value, stab->n_type, str, stab->n_desc); |
|
- | 452 | */ |
|
- | 453 | } |
|
- | 454 | ||
- | 455 | /* for(; si; si = si->next) |
|
- | 456 | { |
|
- | 457 | Section *sr; |
|
- | 458 | Elf32_Rel *rel, *rel_end; |
|
- | 459 | for(sr = me->s1->sections[si->sec_num]->reloc; sr; ) |
|
- | 460 | { |
|
- | 461 | for (rel = (Elf32_Rel *) sr->data, rel_end = (Elf32_Rel *) (sr->data + sr->data_offset); rel < rel_end; rel++) |
|
- | 462 | { |
|
- | 463 | int type = ELF32_R_TYPE(rel->r_info); |
|
- | 464 | if (type != R_386_PC32 && type != R_386_32) |
|
- | 465 | continue; |
|
- | 466 | int sym = ELF32_R_SYM(rel->r_info); |
|
- | 467 | if (sym > symtab_section->data_offset / sizeof(Elf32_Sym)) |
|
- | 468 | continue; |
|
- | 469 | Elf32_Sym* esym = ((Elf32_Sym*)symtab_section->data) + sym; |
|
- | 470 | int sect = esym->st_shndx; |
|
- | 471 | ss = findsection(me, sect); |
|
- | 472 | const char *sym_name = strtab_section->data + esym->st_name; |
|
- | 473 | if (ss == 0) |
|
- | 474 | { |
|
- | 475 | fprintf(fdbg, "undefined symbol '%s'\n", sym_name); |
|
- | 476 | continue; |
|
- | 477 | } |
|
- | 478 | if (rel->r_offset > si->data_size) continue; |
|
- | 479 | fprintf(fdbg, "\t0x%X %s\n", ss->sh_addr + esym->st_value, sym_name); |
|
- | 480 | } |
|
- | 481 | } |
|
- | 482 | } |
|
- | 483 | */ |
|
- | 484 | close_source_file(); |
|
- | 485 | fclose(fdbg); |
|
- | 486 | return 0; |