llvm.org GIT mirror llvm / 7afe000
ARM IAS: properly handle function entries in .thumb When a label is parsed, check if there is type information available for the label. If so, check if the symbol is a function. If the symbol is a function and we are in thumb mode and no explicit thumb_func has been emitted, adjust the symbol data to indicate that the function definition is a thumb function. The application of this inferencing is improved value handling in the object file (the required thumb bit is set on symbols which are thumb functions). It also helps improve compatibility with binutils. The one complication that arises from this handling is the MCAsmStreamer. The default implementation of getOrCreateSymbolData in MCStreamer does not support tracking the symbol data. In order to support the semantics of thumb functions, track symbol data in assembly streamer. Although O(n) in number of labels in the TU, this is already done in various other streamers and as such the memory overhead is not a practical concern in this scenario. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204544 91177308-0d34-0410-b5e6-96231b3b80d8 Saleem Abdulrasool 6 years ago
4 changed file(s) with 126 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
5656 EHPrivateExtern = 1 << 2 };
5757 DenseMap FlagMap;
5858
59 DenseMap SymbolMap;
60
5961 bool needsSet(const MCExpr *Value);
6062
6163 void EmitRegisterName(int64_t Register);
251253 void EmitRawTextImpl(StringRef String) override;
252254
253255 void FinishImpl() override;
256
257 virtual MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) override;
254258 };
255259
256260 } // end anonymous namespace.
14161420 EmitFrames(AsmBackend.get(), false);
14171421 }
14181422
1423 MCSymbolData &MCAsmStreamer::getOrCreateSymbolData(const MCSymbol *Symbol) {
1424 MCSymbolData *&Entry = SymbolMap[Symbol];
1425
1426 if (!Entry)
1427 Entry = new MCSymbolData(*Symbol, 0, 0, 0);
1428
1429 return *Entry;
1430 }
1431
14191432 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
14201433 formatted_raw_ostream &OS,
14211434 bool isVerboseAsm, bool useCFI,
2424 #include "llvm/MC/MCAssembler.h"
2525 #include "llvm/MC/MCContext.h"
2626 #include "llvm/MC/MCDisassembler.h"
27 #include "llvm/MC/MCELF.h"
2728 #include "llvm/MC/MCELFStreamer.h"
29 #include "llvm/MC/MCELFSymbolFlags.h"
2830 #include "llvm/MC/MCExpr.h"
2931 #include "llvm/MC/MCInst.h"
3032 #include "llvm/MC/MCInstrDesc.h"
80848086
80858087 if (!isThumb())
80868088 SwitchMode();
8089
80878090 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
80888091 return false;
80898092 }
81048107
81058108 if (isThumb())
81068109 SwitchMode();
8110
81078111 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
81088112 return false;
81098113 }
81128116 if (NextSymbolIsThumb) {
81138117 getParser().getStreamer().EmitThumbFunc(Symbol);
81148118 NextSymbolIsThumb = false;
8119 return;
8120 }
8121
8122 if (!isThumb())
8123 return;
8124
8125 const MCObjectFileInfo::Environment Format =
8126 getContext().getObjectFileInfo()->getObjectFileType();
8127 switch (Format) {
8128 case MCObjectFileInfo::IsCOFF: {
8129 const MCSymbolData &SD =
8130 getParser().getStreamer().getOrCreateSymbolData(Symbol);
8131 char Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
8132 if (SD.getFlags() & (Type << COFF::SF_TypeShift))
8133 getParser().getStreamer().EmitThumbFunc(Symbol);
8134 break;
8135 }
8136 case MCObjectFileInfo::IsELF: {
8137 const MCSymbolData &SD =
8138 getParser().getStreamer().getOrCreateSymbolData(Symbol);
8139 if (MCELF::GetType(SD) & (ELF::STT_FUNC << ELF_STT_Shift))
8140 getParser().getStreamer().EmitThumbFunc(Symbol);
8141 break;
8142 }
8143 case MCObjectFileInfo::IsMachO:
8144 break;
81158145 }
81168146 }
81178147
0 @ RUN: llvm-mc -triple armv7-elf -filetype obj -o - %s | llvm-readobj -t \
1 @ RUN: | FileCheck %s
2
3 .syntax unified
4
5 .thumb
6
7 .type implicit_function,%function
8 implicit_function:
9 nop
10
11 .type implicit_data,%object
12 implicit_data:
13 .long 0
14
15 .arm
16 .type arm_function,%function
17 arm_function:
18 nop
19
20 .thumb
21
22 .text
23
24 untyped_text_label:
25 nop
26
27 .type explicit_function,%function
28 explicit_function:
29 nop
30
31 .data
32
33 untyped_data_label:
34 nop
35
36 .type explicit_data,%object
37 explicit_data:
38 .long 0
39
40 @ CHECK: Symbol {
41 @ CHECK: Name: arm_function
42 @ CHECK: Value: 0x6
43 @ CHECK: Type: Function
44 @ CHECK: }
45
46 @ CHECK: Symbol {
47 @ CHECK: Name: explicit_data
48 @ CHECK: Value: 0x2
49 @ CHECK: Type: Object
50 @ CHECK: }
51
52 @ CHECK: Symbol {
53 @ CHECK: Name: explicit_function
54 @ CHECK: Value: 0xD
55 @ CHECK: Type: Function
56 @ CHECK: }
57
58 @ CHECK: Symbol {
59 @ CHECK: Name: implicit_data
60 @ CHECK: Value: 0x2
61 @ CHECK: Type: Object
62 @ CHECK: }
63
64 @ CHECK: Symbol {
65 @ CHECK: Name: implicit_function
66 @ CHECK: Value: 0x1
67 @ CHECK: Type: Function
68 @ CHECK: }
69
70 @ CHECK: Symbol {
71 @ CHECK: Name: untyped_data_label
72 @ CHECK: Value: 0x0
73 @ CHECK: Type: None
74 @ CHECK: }
75
76 @ CHECK: Symbol {
77 @ CHECK: Name: untyped_text_label
78 @ CHECK: Value: 0xA
79 @ CHECK: Type: None
80 @ CHECK: }
81
7878
7979 @ CHECK: Symbol {
8080 @ CHECK: Name: alpha
81 @ CHECK: Value: 0x6
82 @ XFAIL-CHECK: Value: 0x7
81 @ CHECK: Value: 0x7
8382 @ CHECK: Type: Function
8483 @ CHECK: }
8584