コード例 #1
0
void
SgAsmElfSection::dump(FILE *f, const char *prefix, ssize_t idx) const
{
    char p[4096];
    if (idx>=0) {
        sprintf(p, "%sElfSection[%zd].", prefix, idx);
    } else {
        sprintf(p, "%sElfSection.", prefix);
    }
    int w = std::max(1, DUMP_FIELD_WIDTH-(int)strlen(p));
    
    SgAsmGenericSection::dump(f, p, -1);
    
    if (get_section_entry())
        get_section_entry()->dump(f, p, -1);
    if (get_segment_entry())
        get_segment_entry()->dump(f, p, -1);

    if (p_linked_section) {
        fprintf(f, "%s%-*s = [%d] \"%s\"\n", p, w, "linked_to",
                p_linked_section->get_id(), p_linked_section->get_name()->get_string(true).c_str());
    } else {
        fprintf(f, "%s%-*s = NULL\n",    p, w, "linked_to");
    }

    if (variantT() == V_SgAsmElfSection) //unless a base class
        hexdump(f, 0, std::string(p)+"data at ", p_data);
}
コード例 #2
0
rose_addr_t
SgAsmElfSection::calculate_sizes(size_t r32size, size_t r64size,       /*size of required parts*/
                                 const std::vector<size_t> &optsizes,  /*size of optional parts and number of parts parsed*/
                                 size_t *entsize, size_t *required, size_t *optional, size_t *entcount) const
{
    size_t struct_size = 0;
    size_t extra_size = 0;
    size_t entry_size = 0;
    size_t nentries = 0;
    SgAsmElfFileHeader *fhdr = get_elf_header();

    /* Assume ELF Section Table Entry is correct for now for the size of each entry in the table. */
    ROSE_ASSERT(get_section_entry()!=NULL);
    entry_size = get_section_entry()->get_sh_entsize();

    /* Size of required part of each entry */
    if (0==r32size && 0==r64size) {
        /* Probably called by four-argument SgAsmElfSection::calculate_sizes and we don't know the sizes of the required parts
         * because there isn't a parser for this type of section, or the section doesn't contain a table. In the latter case
         * the ELF Section Table has a zero sh_entsize and we'll treat the section as if it were a table with one huge entry.
         * Otherwise we'll assume that the struct size is the same as the sh_entsize and there's no optional data. */
        struct_size = entry_size>0 ? entry_size : get_size();
    } else if (4==fhdr->get_word_size()) {
        struct_size = r32size;
    } else if (8==fhdr->get_word_size()) {
        struct_size = r64size;
    } else {
        throw FormatError("bad ELF word size");
    }

    /* Entire entry should be at least large enough for the required part. This also takes care of the case when the ELF
     * Section Table Entry has a zero-valued sh_entsize */
    entry_size = std::max(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 Section Table is correct. */
    nentries = optsizes.size();
    if (nentries>0) {
        for (size_t i=0; i<nentries; i++) {
            extra_size = std::max(extra_size, optsizes[i]);
        }
        entry_size = std::min(entry_size, struct_size+extra_size);
    } else {
        extra_size = entry_size - struct_size;
        nentries = entry_size>0 ? get_size() / entry_size : 0;
    }

    /* 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;
}
コード例 #3
0
bool
SgAsmElfSection::reallocate()
{
    bool reallocated = false;
    SgAsmElfSectionTableEntry *sechdr = get_section_entry();
    SgAsmElfSegmentTableEntry *seghdr = get_segment_entry();

    /* Change section size if this section was defined in the ELF Section Table */
    if (sechdr!=NULL) {
        rose_addr_t need = calculate_sizes(NULL, NULL, NULL, NULL);
        if (need < get_size()) {
            if (is_mapped()) {
                ROSE_ASSERT(get_mapped_size()==get_size());
                set_mapped_size(need);
            }
            set_size(need);
            reallocated = true;
        } else if (need > get_size()) {
            get_file()->shift_extend(this, 0, need-get_size(), SgAsmGenericFile::ADDRSP_ALL, SgAsmGenericFile::ELASTIC_HOLE);
            reallocated = true;
        }
    }

    /* Update entry in the ELF Section Table and/or ELF Segment Table */
    if (sechdr)
        sechdr->update_from_section(this);
    if (seghdr)
        seghdr->update_from_section(this);
    
    return reallocated;
}
コード例 #4
0
ファイル: ElfSymbolTable.C プロジェクト: LindaLovelace/rose
/** Called prior to unparsing. Updates symbol entries with name offsets */
bool
SgAsmElfSymbolSection::reallocate()
{
    bool reallocated = SgAsmElfSection::reallocate();

    /* Update parts of the section and segment tables not updated by superclass */
    SgAsmElfSectionTableEntry *secent = get_section_entry();
    if (secent)
        secent->set_sh_type(p_is_dynamic ?
                            SgAsmElfSectionTableEntry::SHT_DYNSYM :
                            SgAsmElfSectionTableEntry::SHT_SYMTAB);
    return reallocated;
}
コード例 #5
0
ファイル: ElfStringTable.C プロジェクト: Sciumo/rose
/** Reallocate space for the string section if necessary. Note that reallocation is lazy here -- we don't shrink the section,
 *  we only enlarge it (if you want the section to shrink then call SgAsmGenericStrtab::reallocate(bool) with a true value
 *  rather than calling this function. SgAsmElfStringSection::reallocate is called in response to unparsing a file and gives
 *  the string table a chance to extend its container section if it needs to allocate more space for strings. */
bool
SgAsmElfStringSection::reallocate()
{
    bool reallocated = SgAsmElfSection::reallocate();
    if (get_strtab()->reallocate(false))
        reallocated = true;

    /* Update parts of the section and segment tables not updated by superclass */
    SgAsmElfSectionTableEntry *secent = get_section_entry();
    if (secent)
        secent->set_sh_type(SgAsmElfSectionTableEntry::SHT_STRTAB);

    return reallocated;
}
コード例 #6
0
ファイル: ElfSymbolTable.C プロジェクト: LindaLovelace/rose
/** Write symbol table sections back to disk */
void
SgAsmElfSymbolSection::unparse(std::ostream &f) const
{
    SgAsmElfFileHeader *fhdr = get_elf_header();
    ROSE_ASSERT(fhdr);
    ByteOrder sex = fhdr->get_sex();

    size_t entry_size, struct_size, extra_size, nentries;
    calculate_sizes(&entry_size, &struct_size, &extra_size, &nentries);
    
    /* Adjust the entry size stored in the ELF Section Table */
    get_section_entry()->set_sh_entsize(entry_size);

    /* Write each entry's required part followed by the optional part */
    for (size_t i=0; i<nentries; i++) {
        SgAsmElfSymbol::Elf32SymbolEntry_disk disk32;
        SgAsmElfSymbol::Elf64SymbolEntry_disk disk64;
        void *disk=NULL;

        SgAsmElfSymbol *entry = p_symbols->get_symbols()[i];
        
        if (4==fhdr->get_word_size()) {
            disk = entry->encode(sex, &disk32);
        } else if (8==fhdr->get_word_size()) {
            disk = entry->encode(sex, &disk64);
        } else {
            ROSE_ASSERT(!"unsupported word size");
        }

        rose_addr_t spos = i * entry_size;
        spos = write(f, spos, struct_size, disk);
        if (entry->get_extra().size()>0) {
            ROSE_ASSERT(entry->get_extra().size()<=extra_size);
            write(f, spos, entry->get_extra());
        }
    }

    unparse_holes(f);
}
コード例 #7
0
ファイル: ElfSymbolTable.C プロジェクト: LindaLovelace/rose
/** Initializes this ELF Symbol Section by parsing a file. */
SgAsmElfSymbolSection *
SgAsmElfSymbolSection::parse()
{
    SgAsmElfSection::parse();

    SgAsmElfFileHeader *fhdr = get_elf_header();
    ROSE_ASSERT(fhdr!=NULL);
    SgAsmElfSectionTableEntry *shdr = get_section_entry();
    ROSE_ASSERT(shdr!=NULL);
    SgAsmElfStringSection *strsec = dynamic_cast<SgAsmElfStringSection*>(get_linked_section());
    ROSE_ASSERT(strsec!=NULL);

    size_t entry_size, struct_size, extra_size, nentries;
    calculate_sizes(&entry_size, &struct_size, &extra_size, &nentries);
    ROSE_ASSERT(entry_size==shdr->get_sh_entsize());

    /* Parse each entry */
    for (size_t i=0; i<nentries; i++) {
        SgAsmElfSymbol *entry=0;
        if (4==fhdr->get_word_size()) {
            entry = new SgAsmElfSymbol(this); /*adds symbol to this symbol table*/
            SgAsmElfSymbol::Elf32SymbolEntry_disk disk;
            read_content_local(i*entry_size, &disk, struct_size);
            entry->parse(fhdr->get_sex(), &disk);
        } else if (8==fhdr->get_word_size()) {
            entry = new SgAsmElfSymbol(this); /*adds symbol to this symbol table*/
            SgAsmElfSymbol::Elf64SymbolEntry_disk disk;
            read_content_local(i*entry_size, &disk, struct_size);
            entry->parse(fhdr->get_sex(), &disk);
        } else {
            throw FormatError("unsupported ELF word size");
        }
        if (extra_size>0)
            entry->get_extra() = read_content_local_ucl(i*entry_size+struct_size, extra_size);
    }
    return this;
}
コード例 #8
0
 virtual bool reallocate() {
     bool retval = SgAsmElfSection::reallocate();        /* returns true if size or position of any section changed */
     SgAsmElfSectionTableEntry *ste = get_section_entry();
     ste->set_sh_flags(ste->get_sh_flags() | SgAsmElfSectionTableEntry::SHF_ALLOC); /* set the SHF_ALLOC bit */
     return retval;
 }