std::pair<unsigned, unsigned>
RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
  MutexGuard locked(lock);

  // Grab the first Section ID. We'll use this later to construct the underlying
  // range for the returned LoadedObjectInfo.
  unsigned SectionsAddedBeginIdx = Sections.size();

  // Save information about our target
  Arch = (Triple::ArchType)Obj.getArch();
  IsTargetLittleEndian = Obj.isLittleEndian();

  // Compute the memory size required to load all sections to be loaded
  // and pass this information to the memory manager
  if (MemMgr->needsToReserveAllocationSpace()) {
    uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0;
    computeTotalAllocSize(Obj, CodeSize, DataSizeRO, DataSizeRW);
    MemMgr->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
  }

  // Used sections from the object file
  ObjSectionToIDMap LocalSections;

  // Common symbols requiring allocation, with their sizes and alignments
  CommonSymbolMap CommonSymbols;
  // Maximum required total memory to allocate all common symbols
  uint64_t CommonSize = 0;

  // Parse symbols
  DEBUG(dbgs() << "Parse symbols:\n");
  for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
       ++I) {
    object::SymbolRef::Type SymType;
    StringRef Name;
    Check(I->getType(SymType));
    Check(I->getName(Name));

    uint32_t Flags = I->getFlags();

    bool IsCommon = Flags & SymbolRef::SF_Common;
    if (IsCommon) {
      // Add the common symbols to a list.  We'll allocate them all below.
      if (!GlobalSymbolTable.count(Name)) {
        uint32_t Align;
        Check(I->getAlignment(Align));
        uint64_t Size = 0;
        Check(I->getSize(Size));
        CommonSize += Size + Align;
        CommonSymbols[*I] = CommonSymbolInfo(Size, Align);
      }
    } else {
      if (SymType == object::SymbolRef::ST_Function ||
          SymType == object::SymbolRef::ST_Data ||
          SymType == object::SymbolRef::ST_Unknown) {
        uint64_t SectOffset;
        StringRef SectionData;
        section_iterator SI = Obj.section_end();
        Check(getOffset(*I, SectOffset));
        Check(I->getSection(SI));
        if (SI == Obj.section_end())
          continue;
        Check(SI->getContents(SectionData));
        bool IsCode = SI->isText();
        unsigned SectionID =
            findOrEmitSection(Obj, *SI, IsCode, LocalSections);
        DEBUG(dbgs() << "\tOffset: " << format("%p", (uintptr_t)SectOffset)
                     << " flags: " << Flags << " SID: " << SectionID);
        GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
      }
    }
    DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n");
  }

  // Allocate common symbols
  if (CommonSize != 0)
    emitCommonSymbols(Obj, CommonSymbols, CommonSize, GlobalSymbolTable);

  // Parse and process relocations
  DEBUG(dbgs() << "Parse relocations:\n");
  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
       SI != SE; ++SI) {
    unsigned SectionID = 0;
    StubMap Stubs;
    section_iterator RelocatedSection = SI->getRelocatedSection();

    relocation_iterator I = SI->relocation_begin();
    relocation_iterator E = SI->relocation_end();

    if (I == E && !ProcessAllSections)
      continue;

    bool IsCode = RelocatedSection->isText();
    SectionID =
        findOrEmitSection(Obj, *RelocatedSection, IsCode, LocalSections);
    DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");

    for (; I != E;)
      I = processRelocationRef(SectionID, I, Obj, LocalSections, Stubs);

    // If there is an attached checker, notify it about the stubs for this
    // section so that they can be verified.
    if (Checker)
      Checker->registerStubMap(Obj.getFileName(), SectionID, Stubs);
  }

  // Give the subclasses a chance to tie-up any loose ends.
  finalizeLoad(Obj, LocalSections);

  unsigned SectionsAddedEndIdx = Sections.size();

  return std::make_pair(SectionsAddedBeginIdx, SectionsAddedEndIdx);
}
Beispiel #2
0
std::pair<unsigned, unsigned>
RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
  MutexGuard locked(lock);

  // Grab the first Section ID. We'll use this later to construct the underlying
  // range for the returned LoadedObjectInfo.
  unsigned SectionsAddedBeginIdx = Sections.size();

  // Save information about our target
  Arch = (Triple::ArchType)Obj.getArch();
  IsTargetLittleEndian = Obj.isLittleEndian();

  // Compute the memory size required to load all sections to be loaded
  // and pass this information to the memory manager
  if (MemMgr->needsToReserveAllocationSpace()) {
    uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0;
    computeTotalAllocSize(Obj, CodeSize, DataSizeRO, DataSizeRW);
    MemMgr->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
  }

  // Used sections from the object file
  ObjSectionToIDMap LocalSections;

  // Common symbols requiring allocation, with their sizes and alignments
  CommonSymbolList CommonSymbols;

  // Parse symbols
  DEBUG(dbgs() << "Parse symbols:\n");
  for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
       ++I) {
    uint32_t Flags = I->getFlags();

    bool IsCommon = Flags & SymbolRef::SF_Common;
    bool IsWeak = Flags & SymbolRef::SF_Weak;
    if (IsCommon) {
      CommonSymbols.push_back(*I);
    } else {
      object::SymbolRef::Type SymType;
      Check(I->getType(SymType));

      if (SymType == object::SymbolRef::ST_Function ||
          SymType == object::SymbolRef::ST_Data ||
          SymType == object::SymbolRef::ST_Unknown) {

        StringRef Name;
        uint64_t SectOffset;
        Check(I->getName(Name));
        Check(getOffset(*I, SectOffset));
        section_iterator SI = Obj.section_end();
        Check(I->getSection(SI));
        if (SI == Obj.section_end())
          continue;
        StringRef SectionData;
        Check(SI->getContents(SectionData));
        // TODO: It make make sense to delay emitting the section for weak
        // symbols until they are actually required, but that's not possible
        // currently, because we only know whether we will need the symbol
        // in resolveRelocations, which happens after we have already finalized
        // the Load.
        bool IsCode = SI->isText();
        unsigned SectionID =
            findOrEmitSection(Obj, *SI, IsCode, LocalSections);
        DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name
                     << " SID: " << SectionID << " Offset: "
                     << format("%p", (uintptr_t)SectOffset)
                     << " flags: " << Flags << "\n");
        SymbolInfo::Visibility Vis =
          (Flags & SymbolRef::SF_Exported) ?
            SymbolInfo::Default : SymbolInfo::Hidden;
        if (!IsWeak)
        {
          GlobalSymbolTable[Name] = SymbolInfo(SectionID, SectOffset, Vis);
        } else {
          WeakSymbolTable[Name] = SymbolInfo(SectionID, SectOffset, Vis);
        }
      }
    }
  }

  // Allocate common symbols
  emitCommonSymbols(Obj, CommonSymbols);

  // Parse and process relocations
  DEBUG(dbgs() << "Parse relocations:\n");
  for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
       SI != SE; ++SI) {
    unsigned SectionID = 0;
    StubMap Stubs;
    section_iterator RelocatedSection = SI->getRelocatedSection();

    relocation_iterator I = SI->relocation_begin();
    relocation_iterator E = SI->relocation_end();

    if (I == E && !ProcessAllSections)
      continue;

    bool IsCode = RelocatedSection->isText();
    SectionID =
        findOrEmitSection(Obj, *RelocatedSection, IsCode, LocalSections);
    DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");

    for (; I != E;)
      I = processRelocationRef(SectionID, I, Obj, LocalSections, Stubs);

    // If there is an attached checker, notify it about the stubs for this
    // section so that they can be verified.
    if (Checker)
      Checker->registerStubMap(Obj.getFileName(), SectionID, Stubs);
  }

  // Give the subclasses a chance to tie-up any loose ends.
  finalizeLoad(Obj, LocalSections);

  unsigned SectionsAddedEndIdx = Sections.size();

  return std::make_pair(SectionsAddedBeginIdx, SectionsAddedEndIdx);
}