Exemplo n.º 1
0
  void perform(std::unique_ptr<MutableFile> &mergedFile) override {
    // Scan all references in all atoms.
    for (const DefinedAtom *atom : mergedFile->defined()) {
      for (const Reference *ref : *atom) {
        // Look at instructions accessing the GOT.
        bool canBypassGOT;
        if (!_archHandler.isGOTAccess(*ref, canBypassGOT))
          continue;
        const Atom *target = ref->target();
        assert(target != nullptr);

        if (!shouldReplaceTargetWithGOTAtom(target, canBypassGOT)) {
          // Update reference kind to reflect that target is a direct accesss.
          _archHandler.updateReferenceToGOT(ref, false);
        } else {
          // Replace the target with a reference to a GOT entry.
          const DefinedAtom *gotEntry = makeGOTEntry(target);
          const_cast<Reference *>(ref)->setTarget(gotEntry);
          // Update reference kind to reflect that target is now a GOT entry.
          _archHandler.updateReferenceToGOT(ref, true);
        }
      }
    }

    // add all created GOT Atoms to master file
    for (auto &it : _targetToGOT)
      mergedFile->addAtom(*it.second);
  }
Exemplo n.º 2
0
  llvm::Error perform(SimpleFile &mergedFile) override {
    // Scan all references in all atoms.
    for (const DefinedAtom *atom : mergedFile.defined()) {
      for (const Reference *ref : *atom) {
        // Look at instructions accessing the GOT.
        bool canBypassGOT;
        if (!_archHandler.isGOTAccess(*ref, canBypassGOT))
          continue;
        const Atom *target = ref->target();
        assert(target != nullptr);

        if (!shouldReplaceTargetWithGOTAtom(target, canBypassGOT)) {
          // Update reference kind to reflect that target is a direct accesss.
          _archHandler.updateReferenceToGOT(ref, false);
        } else {
          // Replace the target with a reference to a GOT entry.
          const DefinedAtom *gotEntry = makeGOTEntry(target);
          const_cast<Reference *>(ref)->setTarget(gotEntry);
          // Update reference kind to reflect that target is now a GOT entry.
          _archHandler.updateReferenceToGOT(ref, true);
        }
      }
    }

    // Sort and add all created GOT Atoms to master file
    std::vector<const GOTEntryAtom *> entries;
    entries.reserve(_targetToGOT.size());
    for (auto &it : _targetToGOT)
      entries.push_back(it.second);
    std::sort(entries.begin(), entries.end(),
              [](const GOTEntryAtom *left, const GOTEntryAtom *right) {
      return (left->slotName().compare(right->slotName()) < 0);
    });
    for (const GOTEntryAtom *slot : entries)
      mergedFile.addAtom(*slot);

    return llvm::Error::success();
  }
Exemplo n.º 3
0
void GOTPass::perform(MutableFile &mergedFile) {
  // Use map so all pointers to same symbol use same GOT entry.
  llvm::DenseMap<const Atom*, const DefinedAtom*> targetToGOT;

  // Scan all references in all atoms.
  for(const DefinedAtom *atom : mergedFile.defined()) {
    for (const Reference *ref : *atom) {
      // Look at instructions accessing the GOT.
      bool canBypassGOT;
      if (!isGOTAccess(ref->kind(), canBypassGOT))
        continue;
      const Atom *target = ref->target();
      assert(target != nullptr);

      if (!shouldReplaceTargetWithGOTAtom(target, canBypassGOT)) {
        // Update reference kind to reflect that target is a direct accesss.
        updateReferenceToGOT(ref, false);
        continue;
      }
      // Replace the target with a reference to a GOT entry.
      const DefinedAtom *gotEntry = findGOTAtom(target, targetToGOT);
      if (!gotEntry) {
        gotEntry = makeGOTEntry(*target);
        assert(gotEntry != nullptr);
        assert(gotEntry->contentType() == DefinedAtom::typeGOT);
        targetToGOT[target] = gotEntry;
      }
      const_cast<Reference *>(ref)->setTarget(gotEntry);
      // Update reference kind to reflect that target is now a GOT entry.
      updateReferenceToGOT(ref, true);
    }
  }

  // add all created GOT Atoms to master file
  for (auto &it : targetToGOT) {
    mergedFile.addAtom(*it.second);
  }
}