SgAsmCoffSymbolTable* SgAsmCoffSymbolTable::parse() { /* Set the section size according to the number of entries indicated in the header. */ SgAsmPEFileHeader *fhdr = dynamic_cast<SgAsmPEFileHeader*>(get_header()); ROSE_ASSERT(fhdr!=NULL); set_offset(fhdr->get_e_coff_symtab()); set_size(fhdr->get_e_coff_nsyms()*SgAsmCoffSymbol::COFFSymbol_disk_size); SgAsmGenericSection::parse(); /* The string table immediately follows the symbols. The first four bytes of the string table are the size of the * string table in little endian. */ rose_addr_t strtab_offset = get_offset() + fhdr->get_e_coff_nsyms() * SgAsmCoffSymbol::COFFSymbol_disk_size; p_strtab = new SgAsmGenericSection(fhdr->get_file(), fhdr); p_strtab->set_offset(strtab_offset); p_strtab->set_size(sizeof(uint32_t)); p_strtab->set_synthesized(true); p_strtab->set_name(new SgAsmBasicString("COFF Symbol Strtab")); p_strtab->set_purpose(SP_HEADER); p_strtab->parse(); uint32_t word; p_strtab->read_content(0, &word, sizeof word); rose_addr_t strtab_size = ByteOrder::le_to_host(word); if (strtab_size < sizeof(uint32_t)) throw FormatError("COFF symbol table string table size is less than four bytes"); p_strtab->extend(strtab_size - sizeof(uint32_t)); /* Parse symbols until we've parsed the required number or we run off the end of the section. */ for (size_t i = 0; i < fhdr->get_e_coff_nsyms(); i++) { try { SgAsmCoffSymbol *symbol = new SgAsmCoffSymbol(fhdr, this, p_strtab, i); i += symbol->get_st_num_aux_entries(); p_symbols->get_symbols().push_back(symbol); } catch (const ShortRead &e) { fprintf(stderr, "SgAsmCoffSymbolTable::parse: warning: read past end of section \"%s\" [%d]\n" " symbol #%zu at file offset 0x%08"PRIx64"\n" " skipping %zu symbols (including this one)\n", get_name()->get_string(true).c_str(), get_id(), i, e.offset, fhdr->get_e_coff_nsyms()-i); break; } } return this; }