Ejemplo n.º 1
0
static void getSectionsAndSymbols(const macho::Header &Header,
                                  MachOObjectFile *MachOObj,
                             InMemoryStruct<macho::SymtabLoadCommand> *SymtabLC,
                                  std::vector<SectionRef> &Sections,
                                  std::vector<SymbolRef> &Symbols,
                                  SmallVectorImpl<uint64_t> &FoundFns) {
  error_code ec;
  for (symbol_iterator SI = MachOObj->begin_symbols(),
       SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
    Symbols.push_back(*SI);

  for (section_iterator SI = MachOObj->begin_sections(),
       SE = MachOObj->end_sections(); SI != SE; SI.increment(ec)) {
    SectionRef SR = *SI;
    StringRef SectName;
    SR.getName(SectName);
    Sections.push_back(*SI);
  }

  for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
    const MachOObject::LoadCommandInfo &LCI =
       MachOObj->getObject()->getLoadCommandInfo(i);
    if (LCI.Command.Type == macho::LCT_FunctionStarts) {
      // We found a function starts segment, parse the addresses for later
      // consumption.
      InMemoryStruct<macho::LinkeditDataLoadCommand> LLC;
      MachOObj->getObject()->ReadLinkeditDataLoadCommand(LCI, LLC);

      MachOObj->getObject()->ReadULEB128s(LLC->DataOffset, FoundFns);
    }
  }
}
Ejemplo n.º 2
0
/// Given a relocation from __compact_unwind, consisting of the RelocationRef
/// and data being relocated, determine the best base Name and Addend to use for
/// display purposes.
///
/// 1. An Extern relocation will directly reference a symbol (and the data is
///    then already an addend), so use that.
/// 2. Otherwise the data is an offset in the object file's layout; try to find
//     a symbol before it in the same section, and use the offset from there.
/// 3. Finally, if all that fails, fall back to an offset from the start of the
///    referenced section.
static void findUnwindRelocNameAddend(const MachOObjectFile *Obj,
                                      std::map<uint64_t, SymbolRef> &Symbols,
                                      const RelocationRef &Reloc,
                                      uint64_t Addr,
                                      StringRef &Name, uint64_t &Addend) {
  if (Reloc.getSymbol() != Obj->symbol_end()) {
    Reloc.getSymbol()->getName(Name);
    Addend = Addr;
    return;
  }

  auto RE = Obj->getRelocation(Reloc.getRawDataRefImpl());
  SectionRef RelocSection = Obj->getRelocationSection(RE);

  uint64_t SectionAddr;
  RelocSection.getAddress(SectionAddr);

  auto Sym = Symbols.upper_bound(Addr);
  if (Sym == Symbols.begin()) {
    // The first symbol in the object is after this reference, the best we can
    // do is section-relative notation.
    RelocSection.getName(Name);
    Addend = Addr - SectionAddr;
    return;
  }

  // Go back one so that SymbolAddress <= Addr.
  --Sym;

  section_iterator SymSection = Obj->section_end();
  Sym->second.getSection(SymSection);
  if (RelocSection == *SymSection) {
    // There's a valid symbol in the same section before this reference.
    Sym->second.getName(Name);
    Addend = Addr - Sym->first;
    return;
  }

  // There is a symbol before this reference, but it's in a different
  // section. Probably not helpful to mention it, so use the section name.
  RelocSection.getName(Name);
  Addend = Addr - SectionAddr;
}
Ejemplo n.º 3
0
 explicit section(const SectionRef& sec) {
     StringRef name;
     if(error_code err = sec.getName(name))
         llvm_binary_fail(err);
     this->name_ = name.str();
     if (error_code err = sec.getAddress(this->addr_))
         llvm_binary_fail(err);
     
     if (error_code err = sec.getSize(this->size_))
         llvm_binary_fail(err);
 }
Ejemplo n.º 4
0
static void
getSectionsAndSymbols(const MachO::mach_header Header,
                      MachOObjectFile *MachOObj,
                      std::vector<SectionRef> &Sections,
                      std::vector<SymbolRef> &Symbols,
                      SmallVectorImpl<uint64_t> &FoundFns,
                      uint64_t &BaseSegmentAddress) {
  for (symbol_iterator SI = MachOObj->symbol_begin(),
                       SE = MachOObj->symbol_end();
       SI != SE; ++SI)
    Symbols.push_back(*SI);

  for (section_iterator SI = MachOObj->section_begin(),
                        SE = MachOObj->section_end();
       SI != SE; ++SI) {
    SectionRef SR = *SI;
    StringRef SectName;
    SR.getName(SectName);
    Sections.push_back(*SI);
  }

  MachOObjectFile::LoadCommandInfo Command =
    MachOObj->getFirstLoadCommandInfo();
  bool BaseSegmentAddressSet = false;
  for (unsigned i = 0; ; ++i) {
    if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
      // We found a function starts segment, parse the addresses for later
      // consumption.
      MachO::linkedit_data_command LLC =
        MachOObj->getLinkeditDataLoadCommand(Command);

      MachOObj->ReadULEB128s(LLC.dataoff, FoundFns);
    }
    else if (Command.C.cmd == MachO::LC_SEGMENT) {
      MachO::segment_command SLC =
        MachOObj->getSegmentLoadCommand(Command);
      StringRef SegName = SLC.segname;
      if(!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
        BaseSegmentAddressSet = true;
        BaseSegmentAddress = SLC.vmaddr;
      }
    }

    if (i == Header.ncmds - 1)
      break;
    else
      Command = MachOObj->getNextLoadCommandInfo(Command);
  }
}
  /// Return true if the provided section is an offload section and return the
  /// triple by reference.
  static bool IsOffloadSection(SectionRef CurSection,
                               StringRef &OffloadTriple) {
    StringRef SectionName;
    CurSection.getName(SectionName);

    if (SectionName.empty())
      return false;

    // If it does not start with the reserved suffix, just skip this section.
    if (!SectionName.startswith(OFFLOAD_BUNDLER_MAGIC_STR))
      return false;

    // Return the triple that is right after the reserved prefix.
    OffloadTriple = SectionName.substr(sizeof(OFFLOAD_BUNDLER_MAGIC_STR) - 1);
    return true;
  }
Ejemplo n.º 6
0
static void
getSectionsAndSymbols(const macho::Header Header,
                      MachOObjectFile *MachOObj,
                      std::vector<SectionRef> &Sections,
                      std::vector<SymbolRef> &Symbols,
                      SmallVectorImpl<uint64_t> &FoundFns) {
  error_code ec;
  for (symbol_iterator SI = MachOObj->begin_symbols(),
       SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
    Symbols.push_back(*SI);

  for (section_iterator SI = MachOObj->begin_sections(),
       SE = MachOObj->end_sections(); SI != SE; SI.increment(ec)) {
    SectionRef SR = *SI;
    StringRef SectName;
    SR.getName(SectName);
    Sections.push_back(*SI);
  }

  MachOObjectFile::LoadCommandInfo Command =
    MachOObj->getFirstLoadCommandInfo();
  for (unsigned i = 0; ; ++i) {
    if (Command.C.Type == macho::LCT_FunctionStarts) {
      // We found a function starts segment, parse the addresses for later
      // consumption.
      macho::LinkeditDataLoadCommand LLC =
        MachOObj->getLinkeditDataLoadCommand(Command);

      MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns);
    }

    if (i == Header.NumLoadCommands - 1)
      break;
    else
      Command = MachOObj->getNextLoadCommandInfo(Command);
  }
}
Ejemplo n.º 7
0
unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
                                      const SectionRef &Section,
                                      bool IsCode) {

  unsigned StubBufSize = 0,
           StubSize = getMaxStubSize();
  error_code err;
  if (StubSize > 0) {
    for (relocation_iterator i = Section.begin_relocations(),
         e = Section.end_relocations(); i != e; i.increment(err), Check(err))
      StubBufSize += StubSize;
  }
  StringRef data;
  uint64_t Alignment64;
  Check(Section.getContents(data));
  Check(Section.getAlignment(Alignment64));

  unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
  bool IsRequired;
  bool IsVirtual;
  bool IsZeroInit;
  uint64_t DataSize;
  StringRef Name;
  Check(Section.isRequiredForExecution(IsRequired));
  Check(Section.isVirtual(IsVirtual));
  Check(Section.isZeroInit(IsZeroInit));
  Check(Section.getSize(DataSize));
  Check(Section.getName(Name));

  unsigned Allocate;
  unsigned SectionID = Sections.size();
  uint8_t *Addr;
  const char *pData = 0;

  // Some sections, such as debug info, don't need to be loaded for execution.
  // Leave those where they are.
  if (IsRequired) {
    Allocate = DataSize + StubBufSize;
    Addr = IsCode
      ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID)
      : MemMgr->allocateDataSection(Allocate, Alignment, SectionID);
    if (!Addr)
      report_fatal_error("Unable to allocate section memory!");

    // Virtual sections have no data in the object image, so leave pData = 0
    if (!IsVirtual)
      pData = data.data();

    // Zero-initialize or copy the data from the image
    if (IsZeroInit || IsVirtual)
      memset(Addr, 0, DataSize);
    else
      memcpy(Addr, pData, DataSize);

    DEBUG(dbgs() << "emitSection SectionID: " << SectionID
                 << " Name: " << Name
                 << " obj addr: " << format("%p", pData)
                 << " new addr: " << format("%p", Addr)
                 << " DataSize: " << DataSize
                 << " StubBufSize: " << StubBufSize
                 << " Allocate: " << Allocate
                 << "\n");
    Obj.updateSectionAddress(Section, (uint64_t)Addr);
  }
  else {
    // Even if we didn't load the section, we need to record an entry for it
    // to handle later processing (and by 'handle' I mean don't do anything
    // with these sections).
    Allocate = 0;
    Addr = 0;
    DEBUG(dbgs() << "emitSection SectionID: " << SectionID
                 << " Name: " << Name
                 << " obj addr: " << format("%p", data.data())
                 << " new addr: 0"
                 << " DataSize: " << DataSize
                 << " StubBufSize: " << StubBufSize
                 << " Allocate: " << Allocate
                 << "\n");
  }

  Sections.push_back(SectionEntry(Name, Addr, Allocate, DataSize,
				  (uintptr_t)pData));
  return SectionID;
}
Ejemplo n.º 8
0
unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
                                      const SectionRef &Section,
                                      bool IsCode) {

  unsigned StubBufSize = 0,
           StubSize = getMaxStubSize();
  error_code err;
  const ObjectFile *ObjFile = Obj.getObjectFile();
  // FIXME: this is an inefficient way to handle this. We should computed the
  // necessary section allocation size in loadObject by walking all the sections
  // once.
  if (StubSize > 0) {
    for (section_iterator SI = ObjFile->begin_sections(),
           SE = ObjFile->end_sections();
         SI != SE; SI.increment(err), Check(err)) {
      section_iterator RelSecI = SI->getRelocatedSection();
      if (!(RelSecI == Section))
        continue;

      for (relocation_iterator I = SI->begin_relocations(),
             E = SI->end_relocations(); I != E; I.increment(err), Check(err)) {
        StubBufSize += StubSize;
      }
    }
  }

  StringRef data;
  uint64_t Alignment64;
  Check(Section.getContents(data));
  Check(Section.getAlignment(Alignment64));

  unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
  bool IsRequired;
  bool IsVirtual;
  bool IsZeroInit;
  bool IsReadOnly;
  uint64_t DataSize;
  StringRef Name;
  Check(Section.isRequiredForExecution(IsRequired));
  Check(Section.isVirtual(IsVirtual));
  Check(Section.isZeroInit(IsZeroInit));
  Check(Section.isReadOnlyData(IsReadOnly));
  Check(Section.getSize(DataSize));
  Check(Section.getName(Name));
  if (StubSize > 0) {
    unsigned StubAlignment = getStubAlignment();
    unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment);
    if (StubAlignment > EndAlignment)
      StubBufSize += StubAlignment - EndAlignment;
  }

  unsigned Allocate;
  unsigned SectionID = Sections.size();
  uint8_t *Addr;
  const char *pData = 0;

  // Some sections, such as debug info, don't need to be loaded for execution.
  // Leave those where they are.
  if (IsRequired) {
    Allocate = DataSize + StubBufSize;
    Addr = IsCode
      ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID)
      : MemMgr->allocateDataSection(Allocate, Alignment, SectionID, IsReadOnly);
    if (!Addr)
      report_fatal_error("Unable to allocate section memory!");

    // Virtual sections have no data in the object image, so leave pData = 0
    if (!IsVirtual)
      pData = data.data();

    // Zero-initialize or copy the data from the image
    if (IsZeroInit || IsVirtual)
      memset(Addr, 0, DataSize);
    else
      memcpy(Addr, pData, DataSize);

    DEBUG(dbgs() << "emitSection SectionID: " << SectionID
                 << " Name: " << Name
                 << " obj addr: " << format("%p", pData)
                 << " new addr: " << format("%p", Addr)
                 << " DataSize: " << DataSize
                 << " StubBufSize: " << StubBufSize
                 << " Allocate: " << Allocate
                 << "\n");
    Obj.updateSectionAddress(Section, (uint64_t)Addr);
  }
  else {
    // Even if we didn't load the section, we need to record an entry for it
    // to handle later processing (and by 'handle' I mean don't do anything
    // with these sections).
    Allocate = 0;
    Addr = 0;
    DEBUG(dbgs() << "emitSection SectionID: " << SectionID
                 << " Name: " << Name
                 << " obj addr: " << format("%p", data.data())
                 << " new addr: 0"
                 << " DataSize: " << DataSize
                 << " StubBufSize: " << StubBufSize
                 << " Allocate: " << Allocate
                 << "\n");
  }

  Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
  return SectionID;
}
Ejemplo n.º 9
0
unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
                                      const SectionRef &Section, bool IsCode) {

  StringRef data;
  uint64_t Alignment64;
  Check(Section.getContents(data));
  Check(Section.getAlignment(Alignment64));

  unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
  bool IsRequired;
  bool IsVirtual;
  bool IsZeroInit;
  bool IsReadOnly;
  uint64_t DataSize;
  unsigned PaddingSize = 0;
  unsigned StubBufSize = 0;
  StringRef Name;
  Check(Section.isRequiredForExecution(IsRequired));
  Check(Section.isVirtual(IsVirtual));
  Check(Section.isZeroInit(IsZeroInit));
  Check(Section.isReadOnlyData(IsReadOnly));
  Check(Section.getSize(DataSize));
  Check(Section.getName(Name));

  StubBufSize = computeSectionStubBufSize(Obj, Section);

  // The .eh_frame section (at least on Linux) needs an extra four bytes padded
  // with zeroes added at the end.  For MachO objects, this section has a
  // slightly different name, so this won't have any effect for MachO objects.
  if (Name == ".eh_frame")
    PaddingSize = 4;

  uintptr_t Allocate;
  unsigned SectionID = Sections.size();
  uint8_t *Addr;
  const char *pData = 0;

  // Some sections, such as debug info, don't need to be loaded for execution.
  // Leave those where they are.
  if (IsRequired) {
    Allocate = DataSize + PaddingSize + StubBufSize;
    Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID,
                                                Name)
                  : MemMgr->allocateDataSection(Allocate, Alignment, SectionID,
                                                Name, IsReadOnly);
    if (!Addr)
      report_fatal_error("Unable to allocate section memory!");

    // Virtual sections have no data in the object image, so leave pData = 0
    if (!IsVirtual)
      pData = data.data();

    // Zero-initialize or copy the data from the image
    if (IsZeroInit || IsVirtual)
      memset(Addr, 0, DataSize);
    else
      memcpy(Addr, pData, DataSize);

    // Fill in any extra bytes we allocated for padding
    if (PaddingSize != 0) {
      memset(Addr + DataSize, 0, PaddingSize);
      // Update the DataSize variable so that the stub offset is set correctly.
      DataSize += PaddingSize;
    }

    DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
                 << " obj addr: " << format("%p", pData)
                 << " new addr: " << format("%p", Addr)
                 << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
                 << " Allocate: " << Allocate << "\n");
    Obj.updateSectionAddress(Section, (uint64_t)Addr);
  } else {
    // Even if we didn't load the section, we need to record an entry for it
    // to handle later processing (and by 'handle' I mean don't do anything
    // with these sections).
    Allocate = 0;
    Addr = 0;
    DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
                 << " obj addr: " << format("%p", data.data()) << " new addr: 0"
                 << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
                 << " Allocate: " << Allocate << "\n");
  }

  Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
  return SectionID;
}
Ejemplo n.º 10
0
error_or<std::string> getName(const SectionRef &sec) {
    StringRef name;
    if (error_code ec = sec.getName(name))
        return failure(ec.message());
    return success(name.str());
}