Exemple #1
0
/** Adjust the current offset of a section. This is virtual because some sections may need to do something special. This
 * function should not adjust the offset of other sections, or the mapping of any section. */
void
SgAsmGenericSection::set_offset(rose_addr_t offset)
{
    if (p_offset!=offset)
        set_isModified(true);
    p_offset = offset;
}
Exemple #2
0
/** Adjust the current size of a section. This is virtual because some sections may need to do something special. This function
 * should not adjust the size of other sections, or the mapping of any section (see SgAsmGenericFile::resize() for that). */
void
SgAsmGenericSection::set_size(rose_addr_t size)
{
    if (p_size!=size)
        set_isModified(true);
    p_size = size;
}
Exemple #3
0
/** Moves a mapped section without consideration of other sections that might be mapped. */
void
SgAsmGenericSection::set_mapped_preferred_rva(rose_addr_t a)
{
    ROSE_ASSERT(this != NULL);
    if (p_mapped_preferred_rva!=a)
        set_isModified(true);
    p_mapped_preferred_rva = a;
}
Exemple #4
0
/** Resizes a mapped section without consideration of other sections that might be mapped. See also
 *  SgAsmGenericFile::mapped_resize(). */
void
SgAsmGenericSection::set_mapped_size(rose_addr_t size)
{
    ROSE_ASSERT(this != NULL);
    if (p_mapped_size!=size)
        set_isModified(true);
    p_mapped_size = size;
}
/* Creates the storage item for the string at the specified offset. If "shared" is true then attempt to re-use a previous storage
 * object, otherwise create a new one. Each storage object is considered to be a separate string, therefore when two strings
 * share the same storage object, changing one string changes the other. */
SgAsmStringStorage *
SgAsmCoffStrtab::create_storage(rose_addr_t offset, bool shared)
{
    ROSE_ASSERT(offset!=SgAsmGenericString::unallocated);
    SgAsmGenericSection *container = get_container();

    /* Has the string already been created? */
    if (shared) {
        for (referenced_t::iterator i=p_storage_list.begin(); i!=p_storage_list.end(); ++i) {
            if ((*i)->get_offset()==offset && (*i)!=p_dont_free)
                return *i;
        }
    }

    /* Read string length byte */
    unsigned char byte;
    container->read_content_local(offset, &byte, 1);
    unsigned len = byte;

    /* Make sure new storage isn't inside some other string. (We don't support nested strings in COFF where the length byte of
     * the nested string is one of the characters of the outer string.) */
    for (referenced_t::iterator i=p_storage_list.begin(); i!=p_storage_list.end(); ++i) {
        ROSE_ASSERT((*i)->get_offset()==SgAsmGenericString::unallocated ||
                    offset + 1 + len <= (*i)->get_offset() ||
                    offset >= 1 + (*i)->get_string().size());
    }

    /* Create storage object */
    char *buf = new char[len];
    container->read_content_local(offset+1, buf, len);
    SgAsmStringStorage *storage = new SgAsmStringStorage(this, std::string(buf, len), offset);
    delete[] buf;

    /* It's a bad idea to free (e.g., modify) strings before we've identified all the strings in the table. Consider
     * the case where two strings have the same value and point to the same offset (i.e., they share storage). If we modify one
     * before we know about the other then (at best) we modify the other one also.
     *
     * The only time we can guarantee this is OK is when the new storage points to the same file location as "dont_free"
     * since the latter is guaranteed to never be freed or shared. This exception is used when creating a new, unallocated
     * string (see SgAsmStoredString(SgAsmGenericStrtab,const std::string&)). */
    if (p_num_freed>0 && (!p_dont_free || offset!=p_dont_free->get_offset())) {
        fprintf(stderr,
                "SgAsmCoffStrtab::create_storage(%"PRIu64"): %zu other string%s (of %zu created) in [%d] \"%s\""
                " %s been modified and/or reallocated!\n",
                offset, p_num_freed, 1==p_num_freed?"":"s", p_storage_list.size(),
                container->get_id(), container->get_name()->get_string(true).c_str(),
                1==p_num_freed?"has":"have");
        ROSE_ASSERT(0==p_num_freed);
    }

    set_isModified(true);
    p_storage_list.push_back(storage);
    return storage;
}
Exemple #6
0
/** Set name and adjust parent. */
void
SgAsmElfNoteEntry::set_name(SgAsmGenericString *name)
{
    if (name!=p_name) {
        if (p_name) {
            p_name->set_parent(NULL);
            SageInterface::deleteAST(p_name);
        }
        p_name = name;
        if (p_name)
            p_name->set_parent(this);
        set_isModified(true);
    }
}
Exemple #7
0
/** Set the section name node.  If you just want to change the name of a section use the existing name node and change its
 *  string value.  Assigning a new SgAsmGenericString to the section also changes the parent of the specified string node. */
void
SgAsmGenericSection::set_name(SgAsmGenericString *s)
{
    if (s!=p_name) {
        if (p_name) {
            p_name->set_parent(NULL);
            SageInterface::deleteAST(p_name);
        }
        p_name = s;
        if (p_name)
            p_name->set_parent(this);
        set_isModified(true);
    }
}
Exemple #8
0
void
SgAsmPERVASizePair::set_section(SgAsmGenericSection *section)
{
    if (section!=p_section)
        set_isModified(true);
    p_section = section;
    if (section) {
        set_e_rva(rose_rva_t(section->get_mapped_preferred_rva(), section));
        set_e_size(section->get_mapped_size());
    } else {
        set_e_rva(0);
        set_e_size(0);
    }
}
Exemple #9
0
/** Creates the storage item for the string at the specified offset. If 'shared' is true then attempt to re-use a previous
 *  storage object, otherwise always create a new one. Each storage object is considered a separate string, therefore when two
 *  strings share the same storage object, changing one string changes the other. */
SgAsmStringStorage *
SgAsmElfStrtab::create_storage(rose_addr_t offset, bool shared)
{
    ROSE_ASSERT(offset!=SgAsmGenericString::unallocated);

    /* Has this string already been created? If so, return previous storage object. However, never share the empty_string at
     * offset zero created when this string table was constructed because the ELF spec says it needs to stay there whether
     * referenced or not. */
    if (shared) {
        for (referenced_t::iterator i=p_storage_list.begin(); i!=p_storage_list.end(); i++) {
            if ((*i)->get_offset()==offset && (*i) != p_dont_free)
                return *i;
        }
    }

    /* Create a new storage object at this offset. */
    SgAsmStringStorage *storage = NULL;
    if (0==offset && 0==get_container()->get_data().size()) {
        ROSE_ASSERT(get_container()->get_size()>=1);
        storage = new SgAsmStringStorage(this, "", 0);
    } else {
        std::string s = get_container()->read_content_local_str(offset);
        storage = new SgAsmStringStorage(this, s, offset);
    }

    /* It's a bad idea to free (e.g., modify) strings before we've identified all the strings in the table. Consider
     * the case where offset 1 is "domain" and offset 3 is "main" (i.e., they overlap). If we modify "main" before knowing
     * about "domain" then we'll end up freeing the last part of "domain" (and possibly replacing it with something else)!
     *
     * The only time we can guarantee this is OK is when the new storage points to the same file location as "dont_free"
     * since the latter is guaranteed to never be freed or shared. This exception is used when creating a new, unallocated
     * string (see SgAsmStoredString(SgAsmGenericStrtab,const std::string&)). */
    if (p_num_freed>0 && (!p_dont_free || offset!=p_dont_free->get_offset())) {
        fprintf(stderr,
                "SgAsmElfStrtab::create_storage(%"PRIu64"): %" PRIuPTR " other string%s (of %" PRIuPTR " created) in [%d] \"%s\""
                " %s been modified and/or reallocated!\n",
                offset, p_num_freed, 1==p_num_freed?"":"s", p_storage_list.size(),
                get_container()->get_id(), get_container()->get_name()->get_string(true).c_str(),
                1==p_num_freed?"has":"have");
        ROSE_ASSERT(0==p_num_freed);
    }
    
    p_storage_list.push_back(storage);
    set_isModified(true);
    return storage;
}
Exemple #10
0
/** Extend a section by some number of bytes during the construction and/or parsing phase. This is function is considered to
 *  be part of the parsing and construction of a section--it changes the part of the file that's considered the "original
 *  size" of the section. To adjust the size of a section after the executable file is parsed, see SgAsmGenericFile::resize().
 *  Sections are allowed to extend beyond the end of the file and the original data (p_data) is extended only up to the end
 *  of the file. */
void
SgAsmGenericSection::extend(rose_addr_t size)
{
    ROSE_ASSERT(get_file() != NULL);
    ROSE_ASSERT(get_file()->get_tracking_references()); /*can only be called during the parsing phase*/
    rose_addr_t new_size = get_size() + size;

    /* Ending file address for section using new size, limited by total file size */
    rose_addr_t new_end = std::min(get_file()->get_orig_size(), get_offset()+new_size);
    if (get_offset()<=new_end) {
        p_data.resize(new_end-get_offset());
    } else {
        ROSE_ASSERT(0==p_data.size());
    }

    if (p_size!=new_size)
        set_isModified(true);
    p_size = new_size;
}
void
SgAsmElfSection::set_linked_section(SgAsmElfSection* linked_section) {
    set_isModified(true);
    p_linked_section = linked_section;
}