コード例 #1
0
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;
}