summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp')
-rw-r--r--lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp
new file mode 100644
index 00000000000..a0b3dbfa5c6
--- /dev/null
+++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp
@@ -0,0 +1,103 @@
+//===- lib/FileFormat/MachO/ReferenceKinds.cpp ----------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "ReferenceKinds.h"
+
+#include "llvm/ADT/StringRef.h"
+
+
+namespace lld {
+namespace mach_o {
+
+
+struct Mapping {
+ const char* string;
+ Reference::Kind value;
+ uint32_t flags;
+};
+
+enum {
+ flagsNone = 0x0000,
+ flagsIsCallSite = 0x0001,
+ flagsUsesGOT = 0x0002,
+ flagsisGOTLoad = 0x0006,
+ flags32RipRel = 0x1000,
+};
+
+
+static const Mapping sKindMappingsx86_64[] = {
+ { "none", ReferenceKind::x86_64_none, flagsNone },
+ { "call32", ReferenceKind::x86_64_call32, flagsIsCallSite | flags32RipRel },
+ { "pcrel32", ReferenceKind::x86_64_pcRel32, flags32RipRel },
+ { "gotLoad32", ReferenceKind::x86_64_gotLoad32, flagsisGOTLoad | flags32RipRel },
+ { "gotUse32", ReferenceKind::x86_64_gotUse32, flagsUsesGOT | flags32RipRel },
+ { "lea32wasGot", ReferenceKind::x86_64_lea32WasGot, flags32RipRel },
+ { "lazyTarget", ReferenceKind::x86_64_lazyTarget, flagsNone },
+ { "lazyImm", ReferenceKind::x86_64_lazyImm, flagsNone },
+ { "gotTarget", ReferenceKind::x86_64_gotTarget, flagsNone },
+ { "pointer64", ReferenceKind::x86_64_pointer64, flagsNone },
+ { NULL, ReferenceKind::x86_64_none, flagsNone }
+};
+
+
+Reference::Kind ReferenceKind::fromString(StringRef kindName) {
+ for (const Mapping* p = sKindMappingsx86_64; p->string != NULL; ++p) {
+ if ( kindName.equals(p->string) )
+ return p->value;
+ }
+ assert(0 && "unknown darwin reference kind");
+ return 0;
+}
+
+StringRef ReferenceKind::toString(Reference::Kind kindValue) {
+ for (const Mapping* p = sKindMappingsx86_64; p->string != NULL; ++p) {
+ if ( kindValue == p->value)
+ return p->string;
+ }
+ return StringRef("???");
+}
+
+static const Mapping* mappingsForArch(WriterOptionsMachO::Architecture arch) {
+ switch ( arch ) {
+ case WriterOptionsMachO::arch_x86_64:
+ return sKindMappingsx86_64;
+ case WriterOptionsMachO::arch_x86:
+ case WriterOptionsMachO::arch_arm:
+ assert(0 && "references table not yet implemented for arch");
+ return nullptr;
+ }
+}
+
+bool ReferenceKind::isCallSite(WriterOptionsMachO::Architecture arch,
+ Reference::Kind kindValue) {
+ for (const Mapping* p = mappingsForArch(arch); p->string != NULL; ++p) {
+ if ( kindValue == p->value )
+ return (p->flags & flagsIsCallSite);
+ }
+ return false;
+}
+
+bool ReferenceKind::isRipRel32(Reference::Kind kindValue) {
+ for (const Mapping* p = sKindMappingsx86_64; p->string != NULL; ++p) {
+ if ( kindValue == p->value )
+ return (p->flags & flags32RipRel);
+ }
+ return false;
+}
+
+
+
+
+
+} // namespace mach_o
+} // namespace lld
+
+
+
OpenPOWER on IntegriCloud