//===- 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