llvm.org GIT mirror llvm / 4af106a
Add back r203962, r204028 and r204059. This reverts commit r204137. This includes a fix for handling aliases of aliases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204178 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 6 years ago
7 changed file(s) with 415 addition(s) and 43 deletion(s). Raw diff Collapse all Expand all
1717 #include "llvm/Support/Compiler.h"
1818
1919 namespace llvm {
20 class MCAsmLayout;
2021 class MCExpr;
2122 class MCSection;
2223 class MCContext;
144145 // itself.
145146 const MCSymbol &AliasedSymbol() const;
146147
148 // If this symbol is not a variable, return itself. If it is a variable,
149 // evaluate it and check if it is of the form Base + ConstantOffset. If so,
150 // return Base, if not, return nullptr.
151 const MCSymbol *getBaseSymbol(const MCAsmLayout &Layout) const;
152
147153 void setVariableValue(const MCExpr *Value);
148154
149155 /// @}
270270 /// \param RevGroupMap - Maps a signature symbol to the group section.
271271 /// \param NumRegularSections - Number of non-relocation sections.
272272 void ComputeSymbolTable(MCAssembler &Asm,
273 const MCAsmLayout &Layout,
273274 const SectionIndexMapTy &SectionIndexMap,
274275 RevGroupMapTy RevGroupMap,
275276 unsigned NumRegularSections);
461462 }
462463 }
463464
464 uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
465 uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData,
465466 const MCAsmLayout &Layout) {
466 if (Data.isCommon() && Data.isExternal())
467 return Data.getCommonAlignment();
468
469 const MCSymbol &Symbol = Data.getSymbol();
470
471 if (Symbol.isAbsolute() && Symbol.isVariable()) {
472 if (const MCExpr *Value = Symbol.getVariableValue()) {
473 int64_t IntValue;
474 if (Value->EvaluateAsAbsolute(IntValue, Layout))
475 return (uint64_t)IntValue;
476 }
477 }
478
479 if (!Symbol.isInSection())
467 MCSymbolData *Data = &OrigData;
468 if (Data->isCommon() && Data->isExternal())
469 return Data->getCommonAlignment();
470
471 const MCSymbol *Symbol = &Data->getSymbol();
472 const bool IsThumbFunc = OrigData.getFlags() & ELF_Other_ThumbFunc;
473
474 uint64_t Res = 0;
475 if (Symbol->isVariable()) {
476 const MCExpr *Expr = Symbol->getVariableValue();
477 MCValue Value;
478 if (!Expr->EvaluateAsRelocatable(Value, &Layout))
479 return 0;
480 if (Value.getSymB())
481 return 0;
482
483 Res = Value.getConstant();
484 if (IsThumbFunc)
485 Res |= 1;
486
487 const MCSymbolRefExpr *A = Value.getSymA();
488 if (!A)
489 return Res;
490
491 Symbol = &A->getSymbol();
492 Data = &Layout.getAssembler().getSymbolData(*Symbol);
493 }
494
495 if (!Symbol->isInSection())
480496 return 0;
481497
482
483 if (Data.getFragment()) {
484 if (Data.getFlags() & ELF_Other_ThumbFunc)
485 return Layout.getSymbolOffset(&Data)+1;
486 else
487 return Layout.getSymbolOffset(&Data);
488 }
489
490 return 0;
498 if (!Data->getFragment())
499 return 0;
500
501 Res += Layout.getSymbolOffset(Data);
502 if (IsThumbFunc || Data->getFlags() & ELF_Other_ThumbFunc)
503 Res |= 1;
504
505 return Res;
491506 }
492507
493508 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
568583 ELFSymbolData &MSD,
569584 const MCAsmLayout &Layout) {
570585 MCSymbolData &OrigData = *MSD.SymbolData;
571 MCSymbolData &Data =
572 Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
586 const MCSymbol *Base = OrigData.getSymbol().getBaseSymbol(Layout);
587 const MCSymbolData &Data =
588 Base ? Layout.getAssembler().getSymbolData(*Base) : OrigData;
573589
574590 bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
575591 Data.getSymbol().isVariable();
577593 // Binding and Type share the same byte as upper and lower nibbles
578594 uint8_t Binding = MCELF::GetBinding(OrigData);
579595 uint8_t Type = mergeTypeForSet(MCELF::GetType(OrigData), MCELF::GetType(Data));
596 if (OrigData.getFlags() & ELF_Other_ThumbFunc)
597 Type = ELF::STT_FUNC;
580598 uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
581599
582600 // Other and Visibility share the same byte with Visibility using the lower
585603 uint8_t Other = MCELF::getOther(OrigData) << (ELF_STO_Shift - ELF_STV_Shift);
586604 Other |= Visibility;
587605
588 uint64_t Value = SymbolValue(Data, Layout);
606 uint64_t Value = SymbolValue(OrigData, Layout);
589607 uint64_t Size = 0;
590608
591609 assert(!(Data.isCommon() && !Data.isExternal()));
896914 }
897915 }
898916
899 void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
900 const SectionIndexMapTy &SectionIndexMap,
901 RevGroupMapTy RevGroupMap,
902 unsigned NumRegularSections) {
917 void
918 ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
919 const SectionIndexMapTy &SectionIndexMap,
920 RevGroupMapTy RevGroupMap,
921 unsigned NumRegularSections) {
903922 // FIXME: Is this the correct place to do this?
904923 // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
905924 if (NeedsGOT) {
947966
948967 ELFSymbolData MSD;
949968 MSD.SymbolData = it;
950 const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
969 const MCSymbol *BaseSymbol = Symbol.getBaseSymbol(Layout);
951970
952971 // Undefined symbols are global, but this is the first place we
953972 // are able to set it.
954973 bool Local = isLocal(*it, isSignature, Used);
955974 if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) {
956 MCSymbolData &SD = Asm.getSymbolData(RefSymbol);
975 assert(BaseSymbol);
976 MCSymbolData &SD = Asm.getSymbolData(*BaseSymbol);
957977 MCELF::SetBinding(*it, ELF::STB_GLOBAL);
958978 MCELF::SetBinding(SD, ELF::STB_GLOBAL);
959979 }
960980
961 if (RefSymbol.isUndefined() && !Used && WeakrefUsed)
962 MCELF::SetBinding(*it, ELF::STB_WEAK);
963
964 if (it->isCommon()) {
981 if (!BaseSymbol) {
982 MSD.SectionIndex = ELF::SHN_ABS;
983 } else if (it->isCommon()) {
965984 assert(!Local);
966985 MSD.SectionIndex = ELF::SHN_COMMON;
967 } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) {
968 MSD.SectionIndex = ELF::SHN_ABS;
969 } else if (RefSymbol.isUndefined()) {
986 } else if (BaseSymbol->isUndefined()) {
970987 if (isSignature && !Used)
971988 MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]);
972989 else
973990 MSD.SectionIndex = ELF::SHN_UNDEF;
991 if (!Used && WeakrefUsed)
992 MCELF::SetBinding(*it, ELF::STB_WEAK);
974993 } else {
975994 const MCSectionELF &Section =
976 static_cast(RefSymbol.getSection());
995 static_cast(BaseSymbol->getSection());
977996 MSD.SectionIndex = SectionIndexMap.lookup(&Section);
978997 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
979998 NeedsSymtabShndx = true;
15591578 unsigned NumRegularSections = NumUserSections + NumIndexedSections;
15601579
15611580 // Compute symbol table information.
1562 ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections);
1563
1581 ComputeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
1582 NumRegularSections);
15641583
15651584 WriteRelocations(Asm, const_cast(Layout), RelMap);
15661585
88
99 #include "llvm/MC/MCSymbol.h"
1010 #include "llvm/MC/MCExpr.h"
11 #include "llvm/MC/MCValue.h"
1112 #include "llvm/Support/Debug.h"
1213 #include "llvm/Support/raw_ostream.h"
1314 using namespace llvm;
4849 S = &Ref->getSymbol();
4950 }
5051 return *S;
52 }
53
54 const MCSymbol *MCSymbol::getBaseSymbol(const MCAsmLayout &Layout) const {
55 // FIXME: shouldn't EvaluateAsRelocatable be responsible for following as many
56 // variables as possible?
57
58 const MCSymbol *S = this;
59 while (S->isVariable()) {
60 const MCExpr *Expr = S->getVariableValue();
61 MCValue Value;
62 if (!Expr->EvaluateAsRelocatable(Value, &Layout))
63 return nullptr;
64
65 if (Value.getSymB())
66 return nullptr;
67 const MCSymbolRefExpr *A = Value.getSymA();
68 if (!A)
69 return nullptr;
70 S = &A->getSymbol();
71 }
72 return S;
5173 }
5274
5375 void MCSymbol::setVariableValue(const MCExpr *Value) {
2929 #include "llvm/MC/MCInst.h"
3030 #include "llvm/MC/MCInstrDesc.h"
3131 #include "llvm/MC/MCInstrInfo.h"
32 #include "llvm/MC/MCObjectFileInfo.h"
3233 #include "llvm/MC/MCParser/MCAsmLexer.h"
3334 #include "llvm/MC/MCParser/MCAsmParser.h"
3435 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
4041 #include "llvm/MC/MCTargetAsmParser.h"
4142 #include "llvm/Support/ARMBuildAttributes.h"
4243 #include "llvm/Support/ARMEHABI.h"
44 #include "llvm/Support/COFF.h"
4345 #include "llvm/Support/Debug.h"
4446 #include "llvm/Support/ELF.h"
4547 #include "llvm/Support/MathExtras.h"
228230 bool parseDirectiveObjectArch(SMLoc L);
229231 bool parseDirectiveArchExtension(SMLoc L);
230232 bool parseDirectiveAlign(SMLoc L);
233 bool parseDirectiveThumbSet(SMLoc L);
231234
232235 StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
233236 bool &CarrySetting, unsigned &ProcessorIMod,
80298032 return parseDirectiveArchExtension(DirectiveID.getLoc());
80308033 else if (IDVal == ".align")
80318034 return parseDirectiveAlign(DirectiveID.getLoc());
8035 else if (IDVal == ".thumb_set")
8036 return parseDirectiveThumbSet(DirectiveID.getLoc());
80328037 return true;
80338038 }
80348039
90829087 getStreamer().EmitCodeAlignment(4, 0);
90839088 else
90849089 getStreamer().EmitValueToAlignment(4, 0, 1, 0);
9090
9091 return false;
9092 }
9093
9094 /// parseDirectiveThumbSet
9095 /// ::= .thumb_set name, value
9096 bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
9097 StringRef Name;
9098 if (Parser.parseIdentifier(Name)) {
9099 TokError("expected identifier after '.thumb_set'");
9100 Parser.eatToEndOfStatement();
9101 return false;
9102 }
9103
9104 if (getLexer().isNot(AsmToken::Comma)) {
9105 TokError("expected comma after name '" + Name + "'");
9106 Parser.eatToEndOfStatement();
9107 return false;
9108 }
9109 Lex();
9110
9111 const MCExpr *Value;
9112 if (Parser.parseExpression(Value)) {
9113 TokError("missing expression");
9114 Parser.eatToEndOfStatement();
9115 return false;
9116 }
9117
9118 if (getLexer().isNot(AsmToken::EndOfStatement)) {
9119 TokError("unexpected token");
9120 Parser.eatToEndOfStatement();
9121 return false;
9122 }
9123 Lex();
9124
9125 MCSymbol *Alias = getContext().GetOrCreateSymbol(Name);
9126 if (const MCSymbolRefExpr *SRE = dyn_cast(Value)) {
9127 MCSymbol *Sym = getContext().LookupSymbol(SRE->getSymbol().getName());
9128 if (!Sym->isDefined()) {
9129 getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
9130 getStreamer().EmitAssignment(Alias, Value);
9131 return false;
9132 }
9133
9134 const MCObjectFileInfo::Environment Format =
9135 getContext().getObjectFileInfo()->getObjectFileType();
9136 switch (Format) {
9137 case MCObjectFileInfo::IsCOFF: {
9138 char Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
9139 getStreamer().EmitCOFFSymbolType(Type);
9140 // .set values are always local in COFF
9141 getStreamer().EmitSymbolAttribute(Alias, MCSA_Local);
9142 break;
9143 }
9144 case MCObjectFileInfo::IsELF:
9145 getStreamer().EmitSymbolAttribute(Alias, MCSA_ELF_TypeFunction);
9146 break;
9147 case MCObjectFileInfo::IsMachO:
9148 break;
9149 }
9150 }
9151
9152 // FIXME: set the function as being a thumb function via the assembler
9153 getStreamer().EmitThumbFunc(Alias);
9154 getStreamer().EmitAssignment(Alias, Value);
90859155
90869156 return false;
90879157 }
0 @ RUN: not llvm-mc -triple armv7-eabi -o /dev/null 2>&1 %s | FileCheck %s
1
2 .syntax unified
3
4 .thumb
5
6 .thumb_set
7
8 @ CHECK: error: expected identifier after '.thumb_set'
9 @ CHECK: .thumb_set
10 @ CHECL: ^
11
12 .thumb_set ., 0x0b5e55ed
13
14 @ CHECK: error: expected identifier after '.thumb_set'
15 @ CHECK: .thumb_set ., 0x0b5e55ed
16 @ CHECK: ^
17
18 .thumb_set labelled, 0x1abe11ed
19 .thumb_set invalid, :lower16:labelled
20
21 @ CHECK: error: unknown token in expression
22 @ CHECK: .thumb_set invalid, :lower16:labelled
23 @ CHECK: ^
24
25 .thumb_set missing_comma
26
27 @ CHECK: error: expected comma after name 'missing_comma'
28 @ CHECK: .thumb_set missing_comma
29 @ CHECK: ^
30
31 .thumb_set missing_expression,
32
33 @ CHECK: error: missing expression
34 @ CHECK: .thumb_set missing_expression,
35 @ CHECK: ^
36
37 .thumb_set trailer_trash, 0x11fe1e55,
38
39 @ CHECK: error: unexpected token
40 @ CHECK: .thumb_set trailer_trash, 0x11fe1e55,
41 @ CHECK: ^
42
0 @ RUN: llvm-mc -triple armv7-eabi -filetype obj -o - %s | llvm-readobj -t \
1 @ RUN: | FileCheck %s
2
3 .syntax unified
4
5 .arm
6
7 .type arm_func,%function
8 arm_func:
9 nop
10
11 .thumb_set alias_arm_func, arm_func
12
13 .thumb
14
15 .type thumb_func,%function
16 .thumb_func
17 thumb_func:
18 nop
19
20 .thumb_set alias_thumb_func, thumb_func
21
22 .thumb_set seedless, 0x5eed1e55
23 .thumb_set eggsalad, seedless + 0x87788358
24 .thumb_set faceless, ~eggsalad + 0xe133c002
25
26 .thumb_set alias_undefined_data, badblood
27
28 .data
29
30 .type badblood,%object
31 badblood:
32 .long 0xbadb100d
33
34 .type bedazzle,%object
35 bedazzle:
36 .long 0xbeda221e
37
38 .text
39 .thumb
40
41 .thumb_set alias_defined_data, bedazzle
42
43 .type alpha,%function
44 alpha:
45 nop
46
47 .type beta,%function
48 beta:
49 bkpt
50
51 .thumb_set beta, alpha
52
53 .thumb_set alias_undefined, undefined
54
55 @ CHECK: Symbol {
56 @ CHECK: Name: alias_arm_func
57 @ CHECK: Value: 0x1
58 @ CHECK: Type: Function
59 @ CHECK: }
60
61 @ CHECK: Symbol {
62 @ CHECK: Name: alias_defined_data
63 @ CHECK: Value: 0x5
64 @ CHECK: Type: Function
65 @ CHECK: }
66
67 @ CHECK: Symbol {
68 @ CHECK: Name: alias_thumb_func
69 @ CHECK: Value: 0x5
70 @ CHECK: Type: Function
71 @ CHECK: }
72
73 @ CHECK: Symbol {
74 @ CHECK: Name: alias_undefined_data
75 @ CHECK: Value: 0x0
76 @ CHECK: Type: Object
77 @ CHECK: }
78
79 @ CHECK: Symbol {
80 @ CHECK: Name: alpha
81 @ CHECK: Value: 0x6
82 @ XFAIL-CHECK: Value: 0x7
83 @ CHECK: Type: Function
84 @ CHECK: }
85
86 @ CHECK: Symbol {
87 @ CHECK: Name: arm_func
88 @ CHECK: Value: 0x0
89 @ CHECK: Type: Function
90 @ CHECK: }
91
92 @ CHECK: Symbol {
93 @ CHECK: Name: bedazzle
94 @ CHECK: Value: 0x4
95 @ CHECK: Type: Object
96 @ CHECK: }
97
98 @ CHECK: Symbol {
99 @ CHECK: Name: beta
100 @ CHECK: Value: 0x7
101 @ CHECK: Type: Function
102 @ CHECK: }
103
104 @ CHECK: Symbol {
105 @ CHECK: Name: eggsalad
106 @ CHECK: Value: 0xE665A1AD
107 @ CHECK: Type: Function
108 @ CHECK: }
109
110 @ CHECK: Symbol {
111 @ CHECK: Name: faceless
112 @ CHECK: Value: 0xFACE1E55
113 @ CHECK: Type: Function
114 @ CHECK: }
115
116 @ CHECK: Symbol {
117 @ CHECK: Name: seedless
118 @ CHECK: Value: 0x5EED1E55
119 @ CHECK: Type: Function
120 @ CHECK: }
121
122 @ CHECK: Symbol {
123 @ CHECK: Name: thumb_func
124 @ CHECK: Value: 0x5
125 @ CHECK: Type: Function
126 @ CHECK: }
127
128 @ CHECK: Symbol {
129 @ CHECK: Name: badblood
130 @ CHECK: Value: 0x0
131 @ CHECK: Type: Object
132 @ CHECK: }
133
134 @ CHECK: Symbol {
135 @ CHECK: Name: undefined
136 @ CHECK: Value: 0x0
137 @ CHECK: Type: None
138 @ CHECK: }
139
0 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -t - | FileCheck %s
1
2 // Test that a variable declared with "var = other_var + cst" is in the same
3 // section as other_var and its value is the value of other_var + cst.
4
5 .data
6 .globl sym_a
7 .byte 42
8 .type sym_a, @object
9 sym_a:
10
11 // CHECK: Symbol {
12 // CHECK: Name: sym_a
13 // CHECK-NEXT: Value: 0x1
14 // CHECK-NEXT: Size: 0
15 // CHECK-NEXT: Binding: Global
16 // CHECK-NEXT: Type: Object
17 // CHECK-NEXT: Other: 0
18 // CHECK-NEXT: Section: .data
19 // CHECK-NEXT: }
20
21 .long 42
22 .globl sym_b
23 sym_b:
24 .globl sym_c
25 sym_c = sym_a
26 // CHECK: Symbol {
27 // CHECK: Name: sym_c
28 // CHECK-NEXT: Value: 0x1
29 // CHECK-NEXT: Size: 0
30 // CHECK-NEXT: Binding: Global
31 // CHECK-NEXT: Type: Object
32 // CHECK-NEXT: Other: 0
33 // CHECK-NEXT: Section: .data
34 // CHECK-NEXT: }
35
36 .globl sym_d
37 sym_d = sym_a + 1
38 // CHECK: Symbol {
39 // CHECK: Name: sym_d
40 // CHECK-NEXT: Value: 0x2
41 // CHECK-NEXT: Size: 0
42 // CHECK-NEXT: Binding: Global
43 // CHECK-NEXT: Type: Object
44 // CHECK-NEXT: Other: 0
45 // CHECK-NEXT: Section: .data
46 // CHECK-NEXT: }
47
48 .globl sym_e
49 sym_e = sym_a + (sym_b - sym_a) * 3
50 // CHECK: Symbol {
51 // CHECK: Name: sym_e
52 // CHECK-NEXT: Value: 0xD
53 // CHECK-NEXT: Size: 0
54 // CHECK-NEXT: Binding: Global
55 // CHECK-NEXT: Type: Object
56 // CHECK-NEXT: Other: 0
57 // CHECK-NEXT: Section: .data
58 // CHECK-NEXT: }
59
60
61 .globl sym_f
62 sym_f = sym_a + (1 - 1)
63 // CHECK: Symbol {
64 // CHECK: Name: sym_f
65 // CHECK-NEXT: Value: 0x1
66 // CHECK-NEXT: Size: 0
67 // CHECK-NEXT: Binding: Global
68 // CHECK-NEXT: Type: Object
69 // CHECK-NEXT: Other: 0
70 // CHECK-NEXT: Section: .data
71 // CHECK-NEXT: }