Пример #1
0
/* Copy a LC_DYSYMTAB load command from the input file to the output
   file, adjusting the file offset fields.  */
static void
copy_dysymtab (struct load_command *lc, long delta)
{
  struct dysymtab_command *dstp = (struct dysymtab_command *) lc;
  vm_address_t base;

#ifdef _LP64
  /* First writable segment address.  */
  base = data_segment_scp->vmaddr;
#else
  /* First segment address in the file (unless MH_SPLIT_SEGS set). */
  base = 0;
#endif

  unrelocate ("local", dstp->locreloff, dstp->nlocrel, base);
  unrelocate ("external", dstp->extreloff, dstp->nextrel, base);

  if (dstp->nextrel > 0) {
    dstp->extreloff += delta;
  }

  if (dstp->nlocrel > 0) {
    dstp->locreloff += delta;
  }

  if (dstp->nindirectsyms > 0)
    dstp->indirectsymoff += delta;

  printf ("Writing LC_DYSYMTAB command\n");

  if (!unexec_write (curr_header_offset, lc, lc->cmdsize))
    unexec_error ("cannot write symtab command to header");

  curr_header_offset += lc->cmdsize;
}
Пример #2
0
 bool
 insertProc(VMAInterval ival, Proc* proc)
 {
   VMAInterval ival_ur(unrelocate(ival.beg()), unrelocate(ival.end()));
   std::pair<ProcMap::iterator, bool> ret =
     m_procMap.insert(ProcMap::value_type(ival_ur, proc));
   return ret.second;
 }
Пример #3
0
 // returns false if an overlapping segment already exists
 bool
 insertSeg(VMAInterval ival, Seg* seg)
 {
   VMAInterval ival_ur(unrelocate(ival.beg()), unrelocate(ival.end()));
   std::pair<SegMap::iterator, bool> ret =
     m_segMap.insert(SegMap::value_type(ival_ur, seg));
   return ret.second;
 }
Пример #4
0
 // NOTE: does not check for duplicates
 void
 insertInsn(VMA vma, ushort opIndex, Insn* insn)
 {
   VMA vma_ur = unrelocate(vma);
   VMA opvma = isa->convertVMAToOpVMA(vma_ur, opIndex);
   m_insnMap.insert(InsnMap::value_type(opvma, insn));
 }
Пример #5
0
 Proc*
 findProc(VMA vma) const
 {
   VMA vma_ur = unrelocate(vma);
   VMAInterval ival_ur(vma_ur, vma_ur + 1); // size must be > 0
   ProcMap::const_iterator it = m_procMap.find(ival_ur);
   Proc* proc = (it != m_procMap.end()) ? it->second : NULL;
   return proc;
 }
Пример #6
0
 Seg*
 findSeg(VMA vma) const
 {
   VMA vma_ur = unrelocate(vma);
   VMAInterval ival_ur(vma_ur, vma_ur + 1); // size must be > 0
   SegMap::const_iterator it = m_segMap.find(ival_ur);
   Seg* seg = (it != m_segMap.end()) ? it->second : NULL;
   return seg;
 }
Пример #7
0
 Insn*
 findInsnNear(VMA vma, ushort opIndex) const
 {
   VMA vma_ur = unrelocate(vma);
   VMA opvma = isa->convertVMAToOpVMA(vma_ur, opIndex);
   
   InsnMap::const_iterator it = m_insnMap.lower_bound(opvma);
   Insn* insn = (it != m_insnMap.end()) ? it->second : NULL;
   return insn;
 }
Пример #8
0
/* Copy a LC_DYSYMTAB load command from the input file to the output
   file, adjusting the file offset fields.  */
static void
copy_dysymtab (struct load_command *lc, long delta)
{
  struct dysymtab_command *dstp = (struct dysymtab_command *) lc;
  vm_address_t base;

#ifdef _LP64
#if __ppc64__
  {
    int i;

    base = 0;
    for (i = 0; i < nlc; i++)
      if (lca[i]->cmd == LC_SEGMENT)
	{
	  struct segment_command *scp = (struct segment_command *) lca[i];

	  if (scp->vmaddr + scp->vmsize > 0x100000000
	      && (scp->initprot & VM_PROT_WRITE) != 0)
	    {
	      base = data_segment_scp->vmaddr;
	      break;
	    }
	}
  }
#else
  /* First writable segment address.  */
  base = data_segment_scp->vmaddr;
#endif
#else
  /* First segment address in the file (unless MH_SPLIT_SEGS set). */
  base = 0;
#endif

  unrelocate ("local", dstp->locreloff, dstp->nlocrel, base);
  unrelocate ("external", dstp->extreloff, dstp->nextrel, base);

  if (dstp->nextrel > 0) {
    dstp->extreloff += delta;
  }

  if (dstp->nlocrel > 0) {
    dstp->locreloff += delta;
  }

  if (dstp->nindirectsyms > 0)
    dstp->indirectsymoff += delta;

  printf ("Writing LC_DYSYMTAB command\n");

  if (!unexec_write (curr_header_offset, lc, lc->cmdsize))
    unexec_error ("cannot write symtab command to header");

  curr_header_offset += lc->cmdsize;

#if __ppc64__
  /* Check if the relocation base needs to be changed.  */
  if (base == 0)
    {
      vm_address_t newbase = 0;
      int i;

      for (i = 0; i < num_unexec_regions; i++)
	if (unexec_regions[i].range.address + unexec_regions[i].range.size
	    > 0x100000000)
	  {
	    newbase = data_segment_scp->vmaddr;
	    break;
	  }

      if (newbase)
	{
	  rebase_reloc_address (dstp->locreloff, dstp->nlocrel, delta, newbase);
	  rebase_reloc_address (dstp->extreloff, dstp->nextrel, delta, newbase);
	}
    }
#endif
}