now Reader and Writer subclasses for each file format. Each Reader and Writer subclass defines an "options" class which controls how that Reader or Writer operates. llvm-svn: 157774
104 lines
3.0 KiB
C++
104 lines
3.0 KiB
C++
//===- 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
|
|
|
|
|
|
|