blob: a0b3dbfa5c614613e736f7ceeebd50b25ecc169a [file] [log] [blame]
//===- 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