diff options
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp')
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp | 103 |
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 + + + |

