summaryrefslogtreecommitdiffstats
path: root/lib/Target/X86/X86AsmBackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/X86AsmBackend.cpp')
-rw-r--r--lib/Target/X86/X86AsmBackend.cpp56
1 files changed, 51 insertions, 5 deletions
diff --git a/lib/Target/X86/X86AsmBackend.cpp b/lib/Target/X86/X86AsmBackend.cpp
index e6654ef..a44afc6 100644
--- a/lib/Target/X86/X86AsmBackend.cpp
+++ b/lib/Target/X86/X86AsmBackend.cpp
@@ -9,6 +9,7 @@
#include "llvm/Target/TargetAsmBackend.h"
#include "X86.h"
+#include "llvm/MC/MCSectionMachO.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetAsmBackend.h"
using namespace llvm;
@@ -17,18 +18,63 @@ namespace {
class X86AsmBackend : public TargetAsmBackend {
public:
- X86AsmBackend(const Target &T, MCAssembler &A)
+ X86AsmBackend(const Target &T)
: TargetAsmBackend(T) {}
};
+class DarwinX86AsmBackend : public X86AsmBackend {
+public:
+ DarwinX86AsmBackend(const Target &T)
+ : X86AsmBackend(T) {}
+
+ virtual bool hasAbsolutizedSet() const { return true; }
+
+ virtual bool hasScatteredSymbols() const { return true; }
+};
+
+class DarwinX86_32AsmBackend : public DarwinX86AsmBackend {
+public:
+ DarwinX86_32AsmBackend(const Target &T)
+ : DarwinX86AsmBackend(T) {}
+};
+
+class DarwinX86_64AsmBackend : public DarwinX86AsmBackend {
+public:
+ DarwinX86_64AsmBackend(const Target &T)
+ : DarwinX86AsmBackend(T) {}
+
+ virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
+ // Temporary labels in the string literals sections require symbols. The
+ // issue is that the x86_64 relocation format does not allow symbol +
+ // offset, and so the linker does not have enough information to resolve the
+ // access to the appropriate atom unless an external relocation is used. For
+ // non-cstring sections, we expect the compiler to use a non-temporary label
+ // for anything that could have an addend pointing outside the symbol.
+ //
+ // See <rdar://problem/4765733>.
+ const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
+ return SMO.getType() == MCSectionMachO::S_CSTRING_LITERALS;
+ }
+};
+
}
TargetAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
- MCAssembler &A) {
- return new X86AsmBackend(T, A);
+ const std::string &TT) {
+ switch (Triple(TT).getOS()) {
+ case Triple::Darwin:
+ return new DarwinX86_32AsmBackend(T);
+ default:
+ return new X86AsmBackend(T);
+ }
}
TargetAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
- MCAssembler &A) {
- return new X86AsmBackend(T, A);
+ const std::string &TT) {
+ switch (Triple(TT).getOS()) {
+ case Triple::Darwin:
+ return new DarwinX86_64AsmBackend(T);
+ default:
+ return new X86AsmBackend(T);
+ }
}
OpenPOWER on IntegriCloud