llvm-project/lld/lib/ReaderWriter/MachO/SimpleAtoms.hpp

248 lines
5.8 KiB
C++

//===- lib/ReaderWriter/MachO/SimpleAtoms.hpp -----------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_MACHO_SIMPLE_ATOM_H_
#define LLD_READER_WRITER_MACHO_SIMPLE_ATOM_H_
#include <vector>
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/UndefinedAtom.h"
#include "lld/Core/File.h"
#include "lld/Core/Reference.h"
namespace lld {
namespace mach_o {
//
// Simple File
//
class SimpleFile : public File {
public:
SimpleFile(StringRef path)
: File(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 {
assert(0 && "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;
}
private:
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
};
//
// Simple Reference
//
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 Kind kind() const {
return _kind;
}
virtual void setKind(Kind k) {
_kind = k;
}
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;
Kind _kind;
};
//
// Generic Atom base class
//
class SimpleDefinedAtom : public DefinedAtom {
public:
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 StringRef customSectionName() const {
return StringRef();
}
virtual DeadStripKind deadStrip() const {
return DefinedAtom::deadStripNormal;
}
virtual bool isThumb() const {
return false;
}
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));
}
private:
const File& _file;
uint32_t _ordinal;
std::vector<SimpleReference> _references;
};
//
// Generic UndefinedAtom base class
//
class SimpleUndefinedAtom : public UndefinedAtom {
public:
SimpleUndefinedAtom(const File &f, StringRef name)
: _file(f), _name(name) {
}
/// file - returns the File that produced/owns this Atom
virtual const class 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;
};
} // namespace mach_o
} // namespace lld
#endif // LLD_READER_WRITER_MACHO_SIMPLE_ATOM_H_