예제 #1
0
/** Tries to find a suitable offset for a string such that it overlaps with some other string already allocated. If the new
 *  string is the same as the end of some other string (new="main", existing="domain") then we just use an offset into that
 *  string since the space is already allocated for the existing string. If the new string ends with an existing string
 *  (new="domain", existing="main") and there's enough free space before the existing string (two bytes in this case) then
 *  we allocate some of that free space and use a suitable offset. In any case, upon return storage->get_offset() will return
 *  the allocated offset if successful, or SgAsmGenericString::unallocated if we couldn't find an overlap. */
void
SgAsmElfStrtab::allocate_overlap(SgAsmStringStorage *storage)
{
    ROSE_ASSERT(storage->get_offset()==SgAsmGenericString::unallocated);
    size_t need = storage->get_string().size();
    for (size_t i=0; i<p_storage_list.size(); i++) {
        SgAsmStringStorage *existing = p_storage_list[i];
        if (existing->get_offset()!=SgAsmGenericString::unallocated) {
            size_t have = existing->get_string().size();
            if (need<=have && 0==existing->get_string().compare(have-need, need, storage->get_string())) {
                /* An existing string ends with the new string. */
                storage->set_offset(existing->get_offset() + (have-need));
                return;
            } else if (need>have && existing->get_offset()>=need-have &&
                       0==storage->get_string().compare(need-have, have, existing->get_string())) {
                /* New string ends with an existing string. Check for, and allocate, free space. */
                rose_addr_t offset = existing->get_offset() - (need-have); /* positive diffs checked above */
                AddressInterval allocationRequest = AddressInterval::baseSize(offset, need-have);
                if (get_freelist().contains(allocationRequest)) {
                    get_freelist().erase(allocationRequest);
                    storage->set_offset(offset);
                    return;
                }
            }
        }
    }
}
예제 #2
0
/** Write string table back to disk. Free space is zeroed out; holes are left as they are. */
void
SgAsmElfStrtab::unparse(std::ostream &f) const
{
    SgAsmGenericSection *container = get_container();
    
    /* Write strings with NUL termination. Shared strings will be written more than once, but that's OK. */
    for (size_t i=0; i<p_storage_list.size(); i++) {
        SgAsmStringStorage *storage = p_storage_list[i];
        ROSE_ASSERT(storage->get_offset()!=SgAsmGenericString::unallocated);
        rose_addr_t at = container->write(f, storage->get_offset(), storage->get_string());
        container->write(f, at, '\0');
    }
    
    /* Fill free areas with zero */
    BOOST_FOREACH (const AddressInterval &interval, get_freelist().intervals())
        container->write(f, interval.least(), std::string(interval.size(), '\0'));
}
예제 #3
0
/* Write string table back to disk. Free space is zeroed out; holes are left as they are. */
void
SgAsmCoffStrtab::unparse(std::ostream &f) const
{
    SgAsmGenericSection *container = get_container();

    /* Write length coded strings. Shared strings will be written more than once, but that's OK. */
    for (size_t i=0; i<p_storage_list.size(); i++) {
        SgAsmStringStorage *storage = p_storage_list[i];
        ROSE_ASSERT(storage->get_offset()!=SgAsmGenericString::unallocated);
        rose_addr_t at = container->write(f, storage->get_offset(), storage->get_string());
        container->write(f, at, '\0');
    }

    /* Fill free areas with zero */
    for (ExtentMap::const_iterator i=get_freelist().begin(); i!=get_freelist().end(); ++i) {
        container->write(f, i->first.first(), std::string(i->first.size(), '\0'));
    }
}