summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/MC/MCAsmStreamer.cpp13
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp30
-rw-r--r--test/MC/ARM/thumb-types.s82
-rw-r--r--test/MC/ARM/thumb_set.s3
4 files changed, 126 insertions, 2 deletions
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 759058efcb..85d4dd79b3 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -57,6 +57,8 @@ private:
EHPrivateExtern = 1 << 2 };
DenseMap<const MCSymbol*, unsigned> FlagMap;
+ DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
+
bool needsSet(const MCExpr *Value);
void EmitRegisterName(int64_t Register);
@@ -252,6 +254,8 @@ public:
void EmitRawTextImpl(StringRef String) override;
void FinishImpl() override;
+
+ virtual MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) override;
};
} // end anonymous namespace.
@@ -1417,6 +1421,15 @@ void MCAsmStreamer::FinishImpl() {
EmitFrames(AsmBackend.get(), false);
}
+MCSymbolData &MCAsmStreamer::getOrCreateSymbolData(const MCSymbol *Symbol) {
+ MCSymbolData *&Entry = SymbolMap[Symbol];
+
+ if (!Entry)
+ Entry = new MCSymbolData(*Symbol, 0, 0, 0);
+
+ return *Entry;
+}
+
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
formatted_raw_ostream &OS,
bool isVerboseAsm, bool useCFI,
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index ccb1c641ef..1a15352279 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -25,7 +25,9 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCELF.h"
#include "llvm/MC/MCELFStreamer.h"
+#include "llvm/MC/MCELFSymbolFlags.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
@@ -8085,6 +8087,7 @@ bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
if (!isThumb())
SwitchMode();
+
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
return false;
}
@@ -8105,6 +8108,7 @@ bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
if (isThumb())
SwitchMode();
+
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
return false;
}
@@ -8113,6 +8117,32 @@ void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
if (NextSymbolIsThumb) {
getParser().getStreamer().EmitThumbFunc(Symbol);
NextSymbolIsThumb = false;
+ return;
+ }
+
+ if (!isThumb())
+ return;
+
+ const MCObjectFileInfo::Environment Format =
+ getContext().getObjectFileInfo()->getObjectFileType();
+ switch (Format) {
+ case MCObjectFileInfo::IsCOFF: {
+ const MCSymbolData &SD =
+ getParser().getStreamer().getOrCreateSymbolData(Symbol);
+ char Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
+ if (SD.getFlags() & (Type << COFF::SF_TypeShift))
+ getParser().getStreamer().EmitThumbFunc(Symbol);
+ break;
+ }
+ case MCObjectFileInfo::IsELF: {
+ const MCSymbolData &SD =
+ getParser().getStreamer().getOrCreateSymbolData(Symbol);
+ if (MCELF::GetType(SD) & (ELF::STT_FUNC << ELF_STT_Shift))
+ getParser().getStreamer().EmitThumbFunc(Symbol);
+ break;
+ }
+ case MCObjectFileInfo::IsMachO:
+ break;
}
}
diff --git a/test/MC/ARM/thumb-types.s b/test/MC/ARM/thumb-types.s
new file mode 100644
index 0000000000..2fd71525ba
--- /dev/null
+++ b/test/MC/ARM/thumb-types.s
@@ -0,0 +1,82 @@
+@ RUN: llvm-mc -triple armv7-elf -filetype obj -o - %s | llvm-readobj -t \
+@ RUN: | FileCheck %s
+
+ .syntax unified
+
+ .thumb
+
+ .type implicit_function,%function
+implicit_function:
+ nop
+
+ .type implicit_data,%object
+implicit_data:
+ .long 0
+
+ .arm
+ .type arm_function,%function
+arm_function:
+ nop
+
+ .thumb
+
+ .text
+
+untyped_text_label:
+ nop
+
+ .type explicit_function,%function
+explicit_function:
+ nop
+
+ .data
+
+untyped_data_label:
+ nop
+
+ .type explicit_data,%object
+explicit_data:
+ .long 0
+
+@ CHECK: Symbol {
+@ CHECK: Name: arm_function
+@ CHECK: Value: 0x6
+@ CHECK: Type: Function
+@ CHECK: }
+
+@ CHECK: Symbol {
+@ CHECK: Name: explicit_data
+@ CHECK: Value: 0x2
+@ CHECK: Type: Object
+@ CHECK: }
+
+@ CHECK: Symbol {
+@ CHECK: Name: explicit_function
+@ CHECK: Value: 0xD
+@ CHECK: Type: Function
+@ CHECK: }
+
+@ CHECK: Symbol {
+@ CHECK: Name: implicit_data
+@ CHECK: Value: 0x2
+@ CHECK: Type: Object
+@ CHECK: }
+
+@ CHECK: Symbol {
+@ CHECK: Name: implicit_function
+@ CHECK: Value: 0x1
+@ CHECK: Type: Function
+@ CHECK: }
+
+@ CHECK: Symbol {
+@ CHECK: Name: untyped_data_label
+@ CHECK: Value: 0x0
+@ CHECK: Type: None
+@ CHECK: }
+
+@ CHECK: Symbol {
+@ CHECK: Name: untyped_text_label
+@ CHECK: Value: 0xA
+@ CHECK: Type: None
+@ CHECK: }
+
diff --git a/test/MC/ARM/thumb_set.s b/test/MC/ARM/thumb_set.s
index 7381a98134..d0bc9858dd 100644
--- a/test/MC/ARM/thumb_set.s
+++ b/test/MC/ARM/thumb_set.s
@@ -79,8 +79,7 @@ beta:
@ CHECK: Symbol {
@ CHECK: Name: alpha
-@ CHECK: Value: 0x6
-@ XFAIL-CHECK: Value: 0x7
+@ CHECK: Value: 0x7
@ CHECK: Type: Function
@ CHECK: }