Exemplo n.º 1
0
/** Returns info about the size of the entries based on information already available. Any or all arguments may be null
 *  pointers if the caller is not interested in the value. */
rose_addr_t
SgAsmElfSectionTable::calculate_sizes(size_t *entsize, size_t *required, size_t *optional, size_t *entcount) const
{
    SgAsmElfFileHeader *fhdr = dynamic_cast<SgAsmElfFileHeader*>(get_header());
    ROSE_ASSERT(fhdr!=NULL);

    size_t struct_size = 0;
    size_t extra_size = fhdr->get_shextrasz();
    size_t entry_size = 0;
    size_t nentries = 0;

    /* Size of required part of each entry */
    if (4==fhdr->get_word_size()) {
        struct_size = sizeof(SgAsmElfSectionTableEntry::Elf32SectionTableEntry_disk);
    } else if (8==fhdr->get_word_size()) {
        struct_size = sizeof(SgAsmElfSectionTableEntry::Elf64SectionTableEntry_disk);
    } else {
        throw FormatError("bad ELF word size");
    }

    /* Entire entry should be at least large enough for the required part. */
    entry_size = struct_size;

    /* Size of optional parts. If we've parsed the table then use the largest optional part, otherwise assume the entry from
     * the ELF File Header is correct. */
    SgAsmGenericSectionPtrList sections = fhdr->get_sections()->get_sections();
    for (size_t i=0; i<sections.size(); i++) {
        SgAsmElfSection *elfsec = dynamic_cast<SgAsmElfSection*>(sections[i]);
        if (elfsec && elfsec->get_section_entry()) {
            ROSE_ASSERT(elfsec->get_id()>=0);
            nentries = std::max(nentries, (size_t)elfsec->get_id()+1);
            extra_size = std::max(extra_size, elfsec->get_section_entry()->get_extra().size());
        }
    }

    /* Total number of entries. Either we haven't parsed the section table yet (nor created the sections it defines) or we
     * have. In the former case we use the setting from the ELF File Header. Otherwise the table has to be large enough to
     * store the section with the largest ID (ID also serves as the index into the ELF Section Table). */
    if (0==nentries)
        nentries = fhdr->get_e_shnum();

    /* Return values */
    if (entsize)
        *entsize = entry_size;
    if (required)
        *required = struct_size;
    if (optional)
        *optional = extra_size;
    if (entcount)
        *entcount = nentries;
    return entry_size * nentries;
}
Exemplo n.º 2
0
/** Attaches a previously unattached ELF Section to the section table. If @p section is an  ELF String Section
 *  (SgAsmElfStringSection) that contains an ELF String Table (SgAsmElfStringTable) and the ELF Section Table has no
 *  associated string table then the @p section will be used as the string table to hold the section names.
 *
 *  This method complements SgAsmElfSection::init_from_section_table. This method initializes the section table from the
 *  section while init_from_section_table() initializes the section from the section table.
 *
 *  Returns the new section table entry linked into the AST. */
SgAsmElfSectionTableEntry *
SgAsmElfSectionTable::add_section(SgAsmElfSection *section)
{
    ROSE_ASSERT(section!=NULL);
    ROSE_ASSERT(section->get_file()==get_file());
    ROSE_ASSERT(section->get_header()==get_header());
    ROSE_ASSERT(section->get_section_entry()==NULL);            /* must not be in the section table yet */
    
    SgAsmElfFileHeader *fhdr = dynamic_cast<SgAsmElfFileHeader*>(get_header());
    ROSE_ASSERT(fhdr!=NULL);

    /* Assign an ID if there isn't one yet */
    if (section->get_id()<0) {
        int id = fhdr->get_e_shnum();
        fhdr->set_e_shnum(id+1);
        section->set_id(id);
    }

    /* If the supplied section is a string table and the ELF Section Table doesn't have a string table associated with it yet,
     * then use the supplied section as the string table to hold the names of the sections. When this happens, all sections
     * that are already defined in the ELF Section Table should have their names moved into the new string table. */
    SgAsmElfStringSection *strsec = NULL;
    if (fhdr->get_e_shstrndx()==0) {
        strsec = dynamic_cast<SgAsmElfStringSection*>(section);
        if (strsec) {
            fhdr->set_e_shstrndx(section->get_id());
            SgAsmGenericSectionList *all = fhdr->get_sections();
            for (size_t i=0; i<all->get_sections().size(); i++) {
                SgAsmElfSection *s = dynamic_cast<SgAsmElfSection*>(all->get_sections()[i]);
                if (s && s->get_id()>=0 && s->get_section_entry()!=NULL) {
                    s->allocate_name_to_storage(strsec);
                }
            }
        }
    } else {
        strsec = dynamic_cast<SgAsmElfStringSection*>(fhdr->get_section_by_id(fhdr->get_e_shstrndx()));
        ROSE_ASSERT(strsec!=NULL);
    }

    /* Make sure the name is in the correct string table */
    if (strsec)
        section->allocate_name_to_storage(strsec);

    /* Create a new section table entry. */
    SgAsmElfSectionTableEntry *shdr = new SgAsmElfSectionTableEntry;
    shdr->update_from_section(section);
    section->set_section_entry(shdr);

    return shdr;
}