/** 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; }
/** 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; }
/** 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; }
/** 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; }
/** 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); } }
/** 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); } }
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); } }
/** 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; }
/** 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; }