43,6 → 43,9 |
meos_section_info* bss_sections; |
} me_info; |
|
int tcc_output_dbgme(const char *filename, me_info* me); |
|
|
meos_section_info* findsection(me_info* me,int num) |
{ |
meos_section_info* si; |
67,7 → 70,7 |
void build_reloc(me_info* me) |
{ |
int flag; |
Elf32_Rel *rel, *rel_, *rel_end; |
Elf32_Rel *rel = 0, *rel_ = 0, *rel_end = 0; |
Section *sr; |
meos_section_info* s; |
meos_section_info* ss; |
111,7 → 114,7 |
} |
rel=rel_; |
s=s->next; |
if (s==0) |
if (s==0) // what about multiple BSS sections ? |
{ |
if (flag) break; |
s=me->data_sections; |
152,6 → 155,7 |
if (strcmp(".bss",s->name)==0) |
{ |
si=tcc_malloc(sizeof(meos_section_info)); |
si->data=s->data; |
si->data_size=s->data_offset; |
si->next=me->bss_sections; |
si->sec_num=i; |
177,7 → 181,10 |
si->sh_addr=addr; |
addr+=si->data_size; |
} |
if (me->s1->pe_stack_size < 4096) |
addr+=4096; |
else |
addr += me->s1->pe_stack_size; |
addr=(addr+4)&(~3); |
me->header.stack=addr; |
me->header.memory_size=addr; |
245,6 → 252,10 |
me.s1=s1; |
relocate_common_syms(); |
assign_addresses(&me); |
|
if (s1->do_debug) |
tcc_output_dbgme(filename, &me); |
|
me.header.entry_point=tcc_find_symbol_me(&me,"start"); |
me.header.params= tcc_find_symbol_me(&me,"__argv"); // <-- |
me.header.argv= tcc_find_symbol_me(&me,"__path"); // <-- |
262,6 → 273,14 |
fwrite(si->data,1,si->data_size,f); |
for (si=me.data_sections;si;si=si->next) |
fwrite(si->data,1,si->data_size,f); |
for (si=me.bss_sections;si;si=si->next) |
fwrite(si->data,1,si->data_size,f); |
/* |
if (me.bss_sections) // Siemargl testin, what we lose |
{ |
tcc_error_noabort("We lose .BSS section when linking KOS32 executable"); |
} |
*/ |
fclose(f); |
return 0; |
} |
288,3 → 307,181 |
} |
|
#endif |
|
|
static FILE *src_file; |
static int next_src_line; |
|
void close_source_file() |
{ |
if (src_file) |
fclose(src_file); |
src_file = NULL; |
} |
|
void load_source_file(char *fname) |
{ |
close_source_file(); |
src_file = fopen(fname,"rt"); |
if (!src_file) return; |
next_src_line = 1; |
} |
|
int get_src_lines(char *buf, int sz, int start, int end) |
// 1 if read |
{ |
char line[255], *ch; |
strcpy(buf, ""); |
if (!src_file) return 0; |
while (next_src_line < start) // skip |
{ |
ch = fgets(line, sizeof line, src_file); |
if (!ch) return 0; |
next_src_line++; |
} |
while (next_src_line <= end) |
{ |
ch = fgets(line, sizeof line, src_file); |
if (!ch) return 0; |
next_src_line++; |
strncat(buf, line, sz - strlen(buf) - 1); |
} |
// remove newlines |
for (ch = buf; *ch; ch++) |
if (strchr("\t\n\r", *ch)) *ch = ' '; |
|
return 1; |
} |
|
int tcc_output_dbgme(const char *filename, me_info* me) |
// by Siemargl. Writes filename.dbg file for source code level debuggin with MTDBG |
// return 1 on error |
{ |
FILE *fdbg; |
char fname[400], buf[200]; |
|
strcpy(fname, filename); |
strcat(fname, ".dbg"); |
fdbg = fopen(fname,"wt"); |
if (!fdbg) return 1; |
|
meos_section_info *si, *ss; |
fputs(".text\n", fdbg); // just for mtbg |
|
// print symbol table with resolved addresses |
Elf32_Sym* esym; |
for (esym = (Elf32_Sym*)symtab_section->data; esym <= (Elf32_Sym*)(symtab_section->data + symtab_section->data_offset); esym++) |
{ |
if (esym->st_info == 0 || esym->st_info == 4) continue; |
int sect = esym->st_shndx; |
ss = findsection(me, sect); |
const char *sym_name = strtab_section->data + esym->st_name; |
if (ss == 0) |
{ |
fprintf(fdbg, "undefined symbol '%s' type(%d)\n", sym_name, esym->st_info); |
continue; |
} |
fprintf(fdbg, "0x%X %s\n", ss->sh_addr + esym->st_value, sym_name); // removed type(%d) esym->st_info |
} |
|
fputs(".text source code links\n", fdbg); // just for mtbg |
// print symbol table with resolved addresses |
Stab_Sym *stab; |
char *str = "", *cur_file = "???", cur_fun[255]; |
int cur_line = 0, cur_fun_addr = 0, fun_flag = 0; |
strcpy(cur_fun, "fn???"); |
for (stab = (Stab_Sym*)stab_section->data; stab <= (Stab_Sym*)(stab_section->data + stab_section->data_offset); stab++) |
{ |
str = ""; |
switch(stab->n_type) |
{ |
case 100: // source file, or path |
if (stab->n_strx) |
{ |
cur_file = stabstr_section->data + stab->n_strx; |
load_source_file(cur_file); |
} |
else |
cur_file = "???"; |
strcpy(cur_fun, "fn???"); |
cur_line = 0; |
cur_fun_addr = 0; |
fun_flag = 0; |
break; |
case 36: // func |
cur_fun_addr = 0; |
if (stab->n_strx) |
{ |
strcpy(cur_fun, stabstr_section->data + stab->n_strx); |
str = strchr(cur_fun, ':'); |
if (str) *str = '\0'; |
cur_fun_addr = tcc_find_symbol_me(me, cur_fun); |
cur_line = stab->n_desc; |
fun_flag = 1; |
//fprintf(fdbg, "0x%X %s() line(%d)\n", cur_fun_addr, cur_fun, cur_line); // commented as conflicted with direct address |
} |
else |
strcpy(cur_fun, "fn???"); |
break; |
case 68: // N_SLINE |
if (stab->n_value == 0 ) continue; // skip zero offset line |
if (fun_flag) // skip string {, as duplicates address |
{ |
fun_flag = 0; |
continue; |
} |
|
int line; |
if (stab->n_desc > cur_line) |
line = cur_line + 1; |
else |
line = cur_line; |
//fprintf(fdbg, "0x%X LINES %d-%d \n", cur_fun_addr + stab->n_value, line, stab->n_desc); |
if (get_src_lines(buf, sizeof buf, line, stab->n_desc)) |
fprintf(fdbg, "0x%X %s\n", cur_fun_addr + stab->n_value, buf); |
|
cur_line = stab->n_desc; |
break; |
default: |
continue; |
} |
/* |
if (stab->n_strx) |
str = stabstr_section->data + stab->n_strx; |
fprintf(fdbg, "0x%X type(%d) str(%s) desc(%d)\n", stab->n_value, stab->n_type, str, stab->n_desc); |
*/ |
} |
|
/* for(; si; si = si->next) |
{ |
Section *sr; |
Elf32_Rel *rel, *rel_end; |
for(sr = me->s1->sections[si->sec_num]->reloc; sr; ) |
{ |
for (rel = (Elf32_Rel *) sr->data, rel_end = (Elf32_Rel *) (sr->data + sr->data_offset); rel < rel_end; rel++) |
{ |
int type = ELF32_R_TYPE(rel->r_info); |
if (type != R_386_PC32 && type != R_386_32) |
continue; |
int sym = ELF32_R_SYM(rel->r_info); |
if (sym > symtab_section->data_offset / sizeof(Elf32_Sym)) |
continue; |
Elf32_Sym* esym = ((Elf32_Sym*)symtab_section->data) + sym; |
int sect = esym->st_shndx; |
ss = findsection(me, sect); |
const char *sym_name = strtab_section->data + esym->st_name; |
if (ss == 0) |
{ |
fprintf(fdbg, "undefined symbol '%s'\n", sym_name); |
continue; |
} |
if (rel->r_offset > si->data_size) continue; |
fprintf(fdbg, "\t0x%X %s\n", ss->sh_addr + esym->st_value, sym_name); |
} |
} |
} |
*/ |
close_source_file(); |
fclose(fdbg); |
return 0; |
} |