static int pe_assign_addresses(struct pe_info *pe) { int i, k, o, c; DWORD addr; int *section_order; struct section_info *si; struct section_info *merged_text; struct section_info *merged_data; Section *s; // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC); section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int)); for (o = k = 0 ; k < sec_last; ++k) { for (i = 1; i < pe->s1->nb_sections; ++i) { s = pe->s1->sections[i]; if (k == pe_section_class(s)) { s->sh_addr = pe->imagebase; section_order[o++] = i; } } } pe->sec_info = tcc_mallocz(o * sizeof (struct section_info)); addr = pe->imagebase + 1; merged_text = NULL; merged_data = NULL; for (i = 0; i < o; ++i) { k = section_order[i]; s = pe->s1->sections[k]; c = pe_section_class(s); si = &pe->sec_info[pe->sec_count]; #ifdef PE_MERGE_DATA if (c == sec_data && merged_data == NULL) { merged_data = si; } if (c == sec_bss && merged_data != NULL) { // Append .bss to .data s->sh_addr = addr = ((addr - 1) | 15) + 1; addr += s->data_offset; merged_data->sh_size = addr - merged_data->sh_addr; merged_data->last->next = s; merged_data->last = s; continue; } #endif if (c == sec_text) { if (s->unused) continue; if (merged_text) { merged_text->sh_size = align(merged_text->sh_size, s->sh_addralign); s->sh_addr = merged_text->sh_addr + merged_text->sh_size; merged_text->sh_size += s->data_offset; addr = merged_text->sh_addr + merged_text->sh_size; merged_text->last->next = s; merged_text->last = s; continue; } else { merged_text = si; } } strcpy(si->name, c == sec_text ? ".text" : s->name); si->cls = c; si->ord = k; si->sh_addr = s->sh_addr = addr = pe_virtual_align(addr); si->sh_flags = s->sh_flags; si->first = si->last = s; if (c == sec_data && pe->thunk == NULL) { pe->thunk = s; } if (s == pe->thunk) { pe_build_imports(pe); pe_build_exports(pe); } if (c == sec_reloc) { pe_build_reloc(pe); } if (s->data_offset) { si->sh_size = s->data_offset; addr += s->data_offset; pe->sec_count++; } } tcc_free(section_order); return 0; }
ST_FN int pe_assign_addresses (struct pe_info *pe) { int i, k, o, c; DWORD addr; int *section_order; struct section_info *si; Section *s; // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC); section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int)); for (o = k = 0 ; k < sec_last; ++k) { for (i = 1; i < pe->s1->nb_sections; ++i) { s = pe->s1->sections[i]; if (k == pe_section_class(s)) { // printf("%s %d\n", s->name, k); s->sh_addr = pe->imagebase; section_order[o++] = i; } } } pe->sec_info = tcc_mallocz(o * sizeof (struct section_info)); addr = pe->imagebase + 1; for (i = 0; i < o; ++i) { k = section_order[i]; s = pe->s1->sections[k]; c = pe_section_class(s); si = &pe->sec_info[pe->sec_count]; #ifdef PE_MERGE_DATA if (c == sec_bss && pe->sec_count && si[-1].cls == sec_data) { /* append .bss to .data */ s->sh_addr = addr = ((addr-1) | 15) + 1; addr += s->data_offset; si[-1].sh_size = addr - si[-1].sh_addr; continue; } #endif strcpy(si->name, s->name); si->cls = c; si->ord = k; si->sh_addr = s->sh_addr = addr = pe_virtual_align(addr); si->sh_flags = s->sh_flags; if (c == sec_data && NULL == pe->thunk) pe->thunk = s; if (s == pe->thunk) { pe_build_imports(pe); pe_build_exports(pe); } if (c == sec_reloc) pe_build_reloc (pe); if (s->data_offset) { if (s->sh_type != SHT_NOBITS) { si->data = s->data; si->data_size = s->data_offset; } addr += s->data_offset; si->sh_size = s->data_offset; ++pe->sec_count; } // printf("%08x %05x %s\n", si->sh_addr, si->sh_size, si->name); } #if 0 for (i = 1; i < pe->s1->nb_sections; ++i) { Section *s = pe->s1->sections[i]; int type = s->sh_type; int flags = s->sh_flags; printf("section %-16s %-10s %5x %s,%s,%s\n", s->name, type == SHT_PROGBITS ? "progbits" : type == SHT_NOBITS ? "nobits" : type == SHT_SYMTAB ? "symtab" : type == SHT_STRTAB ? "strtab" : type == SHT_REL ? "rel" : "???", s->data_offset, flags & SHF_ALLOC ? "alloc" : "", flags & SHF_WRITE ? "write" : "", flags & SHF_EXECINSTR ? "exec" : "" ); } pe->s1->verbose = 2; #endif tcc_free(section_order); return 0; }