summaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/PECOFF/Pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ReaderWriter/PECOFF/Pass.cpp')
-rw-r--r--lib/ReaderWriter/PECOFF/Pass.cpp95
1 files changed, 95 insertions, 0 deletions
diff --git a/lib/ReaderWriter/PECOFF/Pass.cpp b/lib/ReaderWriter/PECOFF/Pass.cpp
new file mode 100644
index 000000000000..ed731984e378
--- /dev/null
+++ b/lib/ReaderWriter/PECOFF/Pass.cpp
@@ -0,0 +1,95 @@
+//===- lib/ReaderWriter/PECOFF/Pass.cpp -----------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Atoms.h"
+#include "Pass.h"
+#include "lld/Core/File.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/COFF.h"
+
+namespace lld {
+namespace pecoff {
+
+static void addReloc(COFFBaseDefinedAtom *atom, const Atom *target,
+ size_t offsetInAtom, Reference::KindArch arch,
+ Reference::KindValue relType) {
+ atom->addReference(llvm::make_unique<SimpleReference>(
+ Reference::KindNamespace::COFF, arch, relType, offsetInAtom, target, 0));
+}
+
+void addDir64Reloc(COFFBaseDefinedAtom *atom, const Atom *target,
+ llvm::COFF::MachineTypes machine, size_t offsetInAtom) {
+ switch (machine) {
+ case llvm::COFF::IMAGE_FILE_MACHINE_I386:
+ addReloc(atom, target, offsetInAtom, Reference::KindArch::x86,
+ llvm::COFF::IMAGE_REL_I386_DIR32);
+ return;
+ case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
+ addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64,
+ llvm::COFF::IMAGE_REL_AMD64_ADDR64);
+ return;
+ default:
+ llvm_unreachable("unsupported machine type");
+ }
+}
+
+void addDir32Reloc(COFFBaseDefinedAtom *atom, const Atom *target,
+ llvm::COFF::MachineTypes machine, size_t offsetInAtom) {
+ switch (machine) {
+ case llvm::COFF::IMAGE_FILE_MACHINE_I386:
+ addReloc(atom, target, offsetInAtom, Reference::KindArch::x86,
+ llvm::COFF::IMAGE_REL_I386_DIR32);
+ return;
+ case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
+ addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64,
+ llvm::COFF::IMAGE_REL_AMD64_ADDR32);
+ return;
+ default:
+ llvm_unreachable("unsupported machine type");
+ }
+}
+
+void addDir32NBReloc(COFFBaseDefinedAtom *atom, const Atom *target,
+ llvm::COFF::MachineTypes machine, size_t offsetInAtom) {
+ switch (machine) {
+ case llvm::COFF::IMAGE_FILE_MACHINE_I386:
+ addReloc(atom, target, offsetInAtom, Reference::KindArch::x86,
+ llvm::COFF::IMAGE_REL_I386_DIR32NB);
+ return;
+ case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
+ addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64,
+ llvm::COFF::IMAGE_REL_AMD64_ADDR32NB);
+ return;
+ case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
+ addReloc(atom, target, offsetInAtom, Reference::KindArch::ARM,
+ llvm::COFF::IMAGE_REL_ARM_ADDR32NB);
+ return;
+ default:
+ llvm_unreachable("unsupported machine type");
+ }
+}
+
+void addRel32Reloc(COFFBaseDefinedAtom *atom, const Atom *target,
+ llvm::COFF::MachineTypes machine, size_t offsetInAtom) {
+ switch (machine) {
+ case llvm::COFF::IMAGE_FILE_MACHINE_I386:
+ addReloc(atom, target, offsetInAtom, Reference::KindArch::x86,
+ llvm::COFF::IMAGE_REL_I386_REL32);
+ return;
+ case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
+ addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64,
+ llvm::COFF::IMAGE_REL_AMD64_REL32);
+ return;
+ default:
+ llvm_unreachable("unsupported machine type");
+ }
+}
+
+} // end namespace pecoff
+} // end namespace lld