llvm-project/lld/include/lld/ReaderWriter/Simple.h

208 lines
6.2 KiB
C++

//===- lld/Core/Simple.h - Simple implementations of Atom and File --------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provide simple implementations for Atoms and File.
///
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_SIMPLE_H
#define LLD_READER_WRITER_SIMPLE_H
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/File.h"
#include "lld/Core/Reference.h"
#include "lld/Core/UndefinedAtom.h"
namespace lld {
class SimpleFile : public MutableFile {
public:
SimpleFile(const LinkingContext &context, StringRef path)
: MutableFile(context, path) {}
virtual void addAtom(const Atom &atom) {
if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(&atom)) {
_definedAtoms._atoms.push_back(defAtom);
} else if (
const UndefinedAtom *undefAtom = dyn_cast<UndefinedAtom>(&atom)) {
_undefinedAtoms._atoms.push_back(undefAtom);
} else if (
const SharedLibraryAtom *slAtom = dyn_cast<SharedLibraryAtom>(&atom)) {
_sharedLibraryAtoms._atoms.push_back(slAtom);
} else if (const AbsoluteAtom *abAtom = dyn_cast<AbsoluteAtom>(&atom)) {
_absoluteAtoms._atoms.push_back(abAtom);
} else {
llvm_unreachable("atom has unknown definition kind");
}
}
virtual const atom_collection<DefinedAtom> &defined() const {
return _definedAtoms;
}
virtual const atom_collection<UndefinedAtom> &undefined() const {
return _undefinedAtoms;
}
virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
return _sharedLibraryAtoms;
}
virtual const atom_collection<AbsoluteAtom> &absolute() const {
return _absoluteAtoms;
}
virtual DefinedAtomRange definedAtoms() {
return make_range(_definedAtoms._atoms);
}
protected:
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
};
class FileToMutable : public SimpleFile {
public:
explicit FileToMutable(const LinkingContext &context, File &file)
: SimpleFile(context, file.path()), _file(file) {
for (auto definedAtom : _file.defined())
_definedAtoms._atoms.push_back(std::move(definedAtom));
for (auto undefAtom : _file.undefined())
_undefinedAtoms._atoms.push_back(std::move(undefAtom));
for (auto shlibAtom : _file.sharedLibrary())
_sharedLibraryAtoms._atoms.push_back(std::move(shlibAtom));
for (auto absAtom : _file.absolute())
_absoluteAtoms._atoms.push_back(std::move(absAtom));
}
private:
const File &_file;
};
class SimpleReference : public Reference {
public:
SimpleReference(Reference::Kind k, uint64_t off, const Atom *t,
Reference::Addend a)
: _target(t), _offsetInAtom(off), _addend(a) {
_kind = k;
}
virtual uint64_t offsetInAtom() const { return _offsetInAtom; }
virtual const Atom *target() const { return _target; }
virtual Addend addend() const { return _addend; }
virtual void setAddend(Addend a) { _addend = a; }
virtual void setTarget(const Atom *newAtom) { _target = newAtom; }
private:
const Atom *_target;
uint64_t _offsetInAtom;
Addend _addend;
};
class SimpleDefinedAtom : public DefinedAtom {
public:
explicit SimpleDefinedAtom(const File &f) : _file(f) {
static uint32_t lastOrdinal = 0;
_ordinal = lastOrdinal++;
}
virtual const File &file() const { return _file; }
virtual StringRef name() const { return StringRef(); }
virtual uint64_t ordinal() const { return _ordinal; }
virtual Scope scope() const { return DefinedAtom::scopeLinkageUnit; }
virtual Interposable interposable() const { return DefinedAtom::interposeNo; }
virtual Merge merge() const { return DefinedAtom::mergeNo; }
virtual Alignment alignment() const { return Alignment(0, 0); }
virtual SectionChoice sectionChoice() const {
return DefinedAtom::sectionBasedOnContent;
}
virtual SectionPosition sectionPosition() const {
return DefinedAtom::sectionPositionAny;
}
virtual StringRef customSectionName() const { return StringRef(); }
virtual DeadStripKind deadStrip() const {
return DefinedAtom::deadStripNormal;
}
virtual bool isAlias() const { return false; }
virtual DefinedAtom::reference_iterator begin() const {
uintptr_t index = 0;
const void *it = reinterpret_cast<const void *>(index);
return reference_iterator(*this, it);
}
virtual DefinedAtom::reference_iterator end() const {
uintptr_t index = _references.size();
const void *it = reinterpret_cast<const void *>(index);
return reference_iterator(*this, it);
}
virtual const Reference *derefIterator(const void *it) const {
uintptr_t index = reinterpret_cast<uintptr_t>(it);
assert(index < _references.size());
return &_references[index];
}
virtual void incrementIterator(const void *&it) const {
uintptr_t index = reinterpret_cast<uintptr_t>(it);
++index;
it = reinterpret_cast<const void *>(index);
}
void addReference(Reference::Kind kind, uint64_t offset, const Atom *target,
Reference::Addend addend) {
_references.push_back(SimpleReference(kind, offset, target, addend));
}
void setOrdinal(uint64_t ord) { _ordinal = ord; }
private:
const File &_file;
uint64_t _ordinal;
std::vector<SimpleReference> _references;
};
class SimpleUndefinedAtom : public UndefinedAtom {
public:
SimpleUndefinedAtom(const File &f, StringRef name) : _file(f), _name(name) {
assert(!name.empty() && "UndefinedAtoms must have a name");
}
/// file - returns the File that produced/owns this Atom
virtual const File &file() const { return _file; }
/// name - The name of the atom. For a function atom, it is the (mangled)
/// name of the function.
virtual StringRef name() const { return _name; }
virtual CanBeNull canBeNull() const { return UndefinedAtom::canBeNullNever; }
private:
const File &_file;
StringRef _name;
};
} // end namespace lld
#endif