/* Looks at the RVA/Size pairs in the PE header and creates an SgAsmGenericSection object for each one. This must be done * after we build the mapping from virtual addresses to file offsets. */ void SgAsmPEFileHeader::create_table_sections() { /* First, only create the sections. */ for (size_t i=0; i<p_rvasize_pairs->get_pairs().size(); i++) { SgAsmPERVASizePair *pair = p_rvasize_pairs->get_pairs()[i]; if (0==pair->get_e_size()) continue; /* Table names come from PE file specification and are hard coded by RVA/Size pair index */ const char *tabname_short; std::string tabname = rvasize_pair_name((PairPurpose)i, &tabname_short); /* Find the starting offset in the file. * FIXME: We have a potential problem here in that ROSE sections are always contiguous in the file but a section created * from an RVA/Size pair is not necessarily contiguous in the file. Normally such sections are in fact * contiguous and we'll just ignore this for now. In any case, as long as these sections only ever read their * data via the same MemoryMap that we use here, everything should be fine. [RPM 2009-08-17] */ MemoryMap *map = get_loader_map(); ROSE_ASSERT(map!=NULL); const MemoryMap::MapElement *elmt = map->find(get_base_va() + pair->get_e_rva()); if (!elmt) { fprintf(stderr, "SgAsmPEFileHeader::create_table_sections: warning: pair-%zu, rva=0x%08"PRIx64", size=%"PRIu64 " bytes \"%s\": unable to find a mapping for the virtual address (skipping)\n", i, pair->get_e_rva().get_rva(), pair->get_e_size(), tabname.c_str()); continue; } rose_addr_t file_offset = elmt->is_anonymous() ? 0 : elmt->get_va_offset(get_base_va() + pair->get_e_rva(), 1); /* Create the new section */ SgAsmGenericSection *tabsec = NULL; switch (i) { case 0: { /* Sometimes export sections are represented by a ".edata" section, and sometimes they're represented by an * RVA/Size pair, and sometimes both point to the same part of the file. We don't want the exports duplicated * in the AST, so we only create this table as exports if we haven't already seen some other export section. */ SgAsmGenericSectionPtrList §ions = get_sections()->get_sections(); bool seen_exports = false; for (SgAsmGenericSectionPtrList::iterator si=sections.begin(); !seen_exports && si!=sections.end(); ++si) seen_exports = isSgAsmPEExportSection(*si); if (seen_exports) { tabsec = new SgAsmGenericSection(get_file(), this); } else { tabsec = new SgAsmPEExportSection(this); } break; } case 1: { /* Sometimes import sections are represented by a ".idata" section, and sometimes they're represented by an * RVA/Size pair, and sometimes both point to the same part of the file. We don't want the imports duplicated * in the AST, so we only create this table as imports if we haven't already seen some other import section. */ SgAsmGenericSectionPtrList §ions = get_sections()->get_sections(); bool seen_imports = false; for (SgAsmGenericSectionPtrList::iterator si=sections.begin(); !seen_imports && si!=sections.end(); ++si) seen_imports = isSgAsmPEImportSection(*si); if (seen_imports) { tabsec = new SgAsmGenericSection(get_file(), this); } else { tabsec = new SgAsmPEImportSection(this); } break; } default: { tabsec = new SgAsmGenericSection(get_file(), this); break; } } tabsec->set_name(new SgAsmBasicString(tabname)); tabsec->set_short_name(tabname_short); tabsec->set_synthesized(true); tabsec->set_purpose(SP_HEADER); tabsec->set_offset(file_offset); tabsec->set_size(pair->get_e_size()); tabsec->set_file_alignment(1); tabsec->set_mapped_alignment(1); tabsec->set_mapped_preferred_rva(pair->get_e_rva().get_rva()); tabsec->set_mapped_actual_va(pair->get_e_rva().get_rva()+get_base_va()); /*FIXME: not sure this is correct. [RPM 2009-09-11]*/ tabsec->set_mapped_size(pair->get_e_size()); tabsec->set_mapped_rperm(true); tabsec->set_mapped_wperm(false); tabsec->set_mapped_xperm(false); pair->set_section(tabsec); pair->set_e_rva(pair->get_e_rva().set_section(tabsec)); } /* Now parse the sections */ for (size_t i=0; i<p_rvasize_pairs->get_pairs().size(); i++) { SgAsmPERVASizePair *pair = p_rvasize_pairs->get_pairs()[i]; SgAsmGenericSection *tabsec = pair->get_section(); if (tabsec) tabsec->parse(); } }
/* Looks at the RVA/Size pairs in the PE header and creates an SgAsmGenericSection object for each one. This must be done * after we build the mapping from virtual addresses to file offsets. */ void SgAsmPEFileHeader::create_table_sections() { /* First, only create the sections. */ for (size_t i=0; i<p_rvasize_pairs->get_pairs().size(); i++) { SgAsmPERVASizePair *pair = p_rvasize_pairs->get_pairs()[i]; if (0==pair->get_e_size()) continue; /* Table names come from PE file specification and are hard coded by RVA/Size pair index */ const char *tabname_short; std::string tabname = rvasize_pair_name((PairPurpose)i, &tabname_short); /* Find the starting offset in the file. * FIXME: We have a potential problem here in that ROSE sections are always contiguous in the file but a section created * from an RVA/Size pair is not necessarily contiguous in the file. Normally such sections are in fact * contiguous and we'll just ignore this for now. In any case, as long as these sections only ever read their * data via the same MemoryMap that we use here, everything should be fine. [RPM 2009-08-17] */ rose_addr_t pair_va = get_base_va() + pair->get_e_rva(); MemoryMap::Ptr map = get_loader_map(); ROSE_ASSERT(map!=NULL); if (!map->baseSize(pair_va, pair->get_e_size()).exists(Sawyer::Container::MATCH_WHOLE)) { mlog[WARN] <<"SgAsmPEFileHeader::create_table_sections: pair-" <<i <<", rva=" <<StringUtility::addrToString(pair->get_e_rva().get_rva()) <<", size=" <<StringUtility::plural(pair->get_e_size(), "bytes") <<" \"" <<StringUtility::cEscape(tabname) <<"\":" <<" unable to find a mapping for the virtual address (skipping)\n"; continue; } const MemoryMap::Node &me = *map->at(pair_va).findNode(); rose_addr_t file_offset = me.value().offset() + pair_va - me.key().least(); /* Create the new section */ SgAsmGenericSection *tabsec = NULL; switch (i) { case 0: { /* Sometimes export sections are represented by a ".edata" section, and sometimes they're represented by an * RVA/Size pair, sometimes both point to the same part of the file, and sometimes the RVA/Size pair points to * a different part of the file. We don't want the exports duplicated in the AST, so we only create this table * as exports if we haven't already seen some other export section. */ SgAsmGenericSectionPtrList §ions = get_sections()->get_sections(); bool seen_exports = false; for (SgAsmGenericSectionPtrList::iterator si=sections.begin(); !seen_exports && si!=sections.end(); ++si) seen_exports = isSgAsmPEExportSection(*si); if (seen_exports) { tabsec = new SgAsmGenericSection(get_file(), this); } else { tabsec = new SgAsmPEExportSection(this); } break; } case 1: { /* Sometimes import sections are represented by a ".idata" section, and sometimes they're represented by an * RVA/Size pair, and sometimes both point to the same part of the file. We don't want the imports duplicated * in the AST, so we only create this table as imports if we haven't already seen some other import section. */ SgAsmGenericSectionPtrList §ions = get_sections()->get_sections(); bool seen_imports = false; for (SgAsmGenericSectionPtrList::iterator si=sections.begin(); !seen_imports && si!=sections.end(); ++si) seen_imports = isSgAsmPEImportSection(*si); if (seen_imports) { tabsec = new SgAsmGenericSection(get_file(), this); } else { tabsec = new SgAsmPEImportSection(this); } break; } default: { tabsec = new SgAsmGenericSection(get_file(), this); break; } } tabsec->set_name(new SgAsmBasicString(tabname)); tabsec->set_short_name(tabname_short); tabsec->set_synthesized(true); tabsec->set_purpose(SP_HEADER); tabsec->set_offset(file_offset); tabsec->set_size(pair->get_e_size()); tabsec->set_file_alignment(1); tabsec->set_mapped_alignment(1); tabsec->set_mapped_preferred_rva(pair->get_e_rva().get_rva()); tabsec->set_mapped_actual_va(pair->get_e_rva().get_rva()+get_base_va()); /*FIXME: not sure this is correct. [RPM 2009-09-11]*/ tabsec->set_mapped_size(pair->get_e_size()); tabsec->set_mapped_rperm(true); tabsec->set_mapped_wperm(false); tabsec->set_mapped_xperm(false); pair->set_section(tabsec); pair->set_e_rva(pair->get_e_rva().set_section(tabsec)); } /* Now parse the sections */ for (size_t i=0; i<p_rvasize_pairs->get_pairs().size(); i++) { SgAsmPERVASizePair *pair = p_rvasize_pairs->get_pairs()[i]; SgAsmGenericSection *tabsec = pair->get_section(); if (tabsec) tabsec->parse(); } }