ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PeImportSection.C
Go to the documentation of this file.
1 /* SgAsmPEImportSection, normally named ".idata" if it appears in the section table. Most modern PE executables don't create a
2  * special section in the section table, but rather have the SgAsmPEFileHeader::PAIR_IMPORTS RVA/Size pair point to part of the
3  * memory mapped from another read-only section, such as the ".text" section. */
4 #include "sage3basic.h"
5 #include <stdarg.h>
6 
153 
156 bool
158 {
159  static const size_t max_to_print=15;
160 
161  bool printed=false;
162  va_list ap;
163  va_start(ap, fmt);
164 
165  if (mesg_nprinted < max_to_print) {
166  vfprintf(stderr, fmt, ap);
167  printed = true;
168  } else if (mesg_nprinted == max_to_print) {
169  fprintf(stderr, "Import message limit reached; import diagnostics are now suppressed.\n");
170  }
171 
172  ++mesg_nprinted;
173  va_end(ap);
174  return printed;
175 }
176 
177 void
179 {
180  set_synthesized(true);
181 
182  SgAsmBasicString *name = new SgAsmBasicString("PE Section Table");
183  set_name(name);
184  name->set_parent(this);
185 
187 
190 }
191 
197 {
200 
202  ROSE_ASSERT(fhdr!=NULL);
203 
204  ROSE_ASSERT(is_mapped());
205  rose_addr_t idir_va = get_mapped_actual_va();
206 
207  /* Parse each Import Directory. The list of directories is terminated with a zero-filled entry, which is not added to this
208  * import section. */
209  for (size_t i = 0; 1; i++) {
210  /* Import directory entry */
212  if (NULL==idir->parse(idir_va)) {
213  /* We've reached the zero entry. Remove this directory from the section and delete it. */
216  break;
217  }
219 #if 1 /* FIXME: Do we really want this stuff duplicated in the AST? [RPM 2008-12-12] */
221  fhdr->add_dll(new SgAsmGenericDLL(name2));
222 #endif
223  }
224  return this;
225 }
226 
228 void
230 {
231  ROSE_ASSERT(get_import_directories()!=NULL);
233 
234  /* Make sure it's not already on the list */
235  ROSE_ASSERT(dirlist.end()==std::find(dirlist.begin(), dirlist.end(), d));
236 
237  dirlist.push_back(d);
240 }
241 
243 void
245 {
247  SgAsmPEImportDirectoryPtrList::iterator found = std::find(dirlist.begin(), dirlist.end(), d);
248  if (found!=dirlist.end()) {
249  dirlist.erase(found);
250  d->set_parent(NULL);
251  }
252 }
253 
259 bool
261 {
263  bool reallocated = SgAsmPESection::reallocate();
264  rose_rva_t end_rva(this->get_mapped_preferred_rva(), this);
266 
267  /* Space needed for the list of import directory structs. The list is terminated with a zero entry. */
268  size_t nimports = dirlist.size();
269  end_rva.increment((1 + nimports) * sizeof(SgAsmPEImportDirectory::PEImportDirectory_disk));
270 
271  /* Space needed for the data of each import directory. */
272  for (size_t i=0; i<nimports; i++)
273  end_rva.increment(dirlist[i]->reallocate(end_rva));
274 
275  /* Adjust the section size */
276  rose_addr_t need = end_rva.get_rel();
277  if (need < get_size()) {
278  if (is_mapped())
279  set_mapped_size(need);
280  set_size(need);
281  reallocated = true;
282  } else if (need > get_size()) {
284  reallocated = true;
285  }
286 
287  return reallocated;
288 }
289 
297 size_t
299 {
300  rose_rva_t rva = start_at;
302  for (SgAsmPEImportDirectoryPtrList::const_iterator di=dirs.begin(); di!=dirs.end(); ++di) {
303  (*di)->set_iat_rva(rva);
304  size_t need = (*di)->iat_required_size();
305  (*di)->set_iat_nalloc(need);
306  rva.increment(need);
307  }
308  return rva.get_rel() - start_at.get_rel();
309 }
310 
311 
312 /* Write the import section back to disk */
313 void
314 SgAsmPEImportSection::unparse(std::ostream &f) const
315 {
317 #if 1 /* DEBUGGING [RPM 2010-11-09] */
318  {
319  uint8_t byte = 0;
320  for (size_t i=0; i<get_size(); i++)
321  write(f, i, 1, &byte);
322  }
323 #endif
324 
325  unparse_holes(f);
326 
327  /* Import Directory Entries and all they point to (even in other sections) */
328  for (size_t i=0; i<get_import_directories()->get_vector().size(); i++) {
330  try {
331  idir->unparse(f, this, i);
332  } catch(const ShortWrite&) {
333  import_mesg("SgAsmImportSection::unparse: error: Import Directory #%zu skipped (short write)\n", i);
334  }
335  }
336 
337  /* Zero terminated */
339  memset(&zero, 0, sizeof zero);
340  write(f, get_import_directories()->get_vector().size()*sizeof(zero), sizeof zero, &zero);
341 }
342 
343 /* Print debugging info */
344 void
345 SgAsmPEImportSection::dump(FILE *f, const char *prefix, ssize_t idx) const
346 {
347  char p[4096];
348  if (idx>=0) {
349  sprintf(p, "%sPEImportSection[%zd].", prefix, idx);
350  } else {
351  sprintf(p, "%sPEImportSection.", prefix);
352  }
353 
354  const int w = std::max(1, DUMP_FIELD_WIDTH-(int)strlen(p));
355 
356  SgAsmPESection::dump(f, p, -1);
357  fprintf(f, "%s%-*s = %zu\n", p, w, "ndirectories", p_import_directories->get_vector().size());
358  for (size_t i=0; i<p_import_directories->get_vector().size(); i++)
359  p_import_directories->get_vector()[i]->dump(f, p, i);
360 
361  if (variantT() == V_SgAsmPEImportSection) //unless a base class
362  hexdump(f, 0, std::string(p)+"data at ", p_data);
363 }