llvm.org GIT mirror llvm / 930ca98
Fix pr19645. The fix itself is fairly simple: move getAccessVariant to MCValue so that we replace the old weak expression evaluation with the far more general EvaluateAsRelocatable. This then requires that EvaluateAsRelocatable stop when it finds a non trivial reference kind. And that in turn requires the ELF writer to look harder for weak references. Last but not least, this found a case where we were being bug by bug compatible with gas and accepting an invalid input. I reported pr19647 to track it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207920 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 6 years ago
13 changed file(s) with 55 addition(s) and 58 deletion(s). Raw diff Collapse all Expand all
8787
8888 MCFixupKind getKind() const { return MCFixupKind(Kind); }
8989
90 MCSymbolRefExpr::VariantKind getAccessVariant() const;
91
9290 uint32_t getOffset() const { return Offset; }
9391 void setOffset(uint32_t Value) { Offset = Value; }
9492
1313 #ifndef LLVM_MC_MCVALUE_H
1414 #define LLVM_MC_MCVALUE_H
1515
16 #include "llvm/MC/MCExpr.h"
1617 #include "llvm/MC/MCSymbol.h"
1718 #include "llvm/Support/DataTypes.h"
1819 #include
1920
2021 namespace llvm {
2122 class MCAsmInfo;
22 class MCSymbol;
23 class MCSymbolRefExpr;
2423 class raw_ostream;
2524
2625 /// MCValue - This represents an "assembler immediate". In its most
6059 /// dump - Print the value to stderr.
6160 void dump() const;
6261
62 MCSymbolRefExpr::VariantKind getAccessVariant() const;
63
6364 static MCValue get(const MCSymbolRefExpr *SymA,
6465 const MCSymbolRefExpr *SymB = nullptr,
6566 int64_t Val = 0, uint32_t RefKind = 0) {
1515 MCELF.cpp
1616 MCELFObjectTargetWriter.cpp
1717 MCELFStreamer.cpp
18 MCFixup.cpp
1918 MCFunction.cpp
2019 MCExpr.cpp
2120 MCExternalSymbolizer.cpp
786786 return false;
787787 }
788788
789 static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) {
790 const MCSymbol &Sym = Ref.getSymbol();
791
792 if (Ref.getKind() == MCSymbolRefExpr::VK_WEAKREF)
793 return &Sym;
794
795 if (!Sym.isVariable())
796 return nullptr;
797
798 const MCExpr *Expr = Sym.getVariableValue();
799 const auto *Inner = dyn_cast(Expr);
800 if (!Inner)
801 return nullptr;
802
803 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF)
804 return &Inner->getSymbol();
805 return nullptr;
806 }
807
789808 void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
790809 const MCAsmLayout &Layout,
791810 const MCFragment *Fragment,
871890 if (const MCSymbol *R = Renames.lookup(SymA))
872891 SymA = R;
873892
874 if (RefA->getKind() == MCSymbolRefExpr::VK_WEAKREF)
875 WeakrefUsedInReloc.insert(SymA);
893 if (const MCSymbol *WeakRef = getWeakRef(*RefA))
894 WeakrefUsedInReloc.insert(WeakRef);
876895 else
877896 UsedInReloc.insert(SymA);
878897 }
657657
658658 case SymbolRef: {
659659 const MCSymbolRefExpr *SRE = cast(this);
660 bool IsWeakRef = SRE->getKind() == MCSymbolRefExpr::VK_WEAKREF;
661660 const MCSymbol &Sym = SRE->getSymbol();
662661 const MCAsmInfo &MCAsmInfo = SRE->getMCAsmInfo();
663662
664663 // Evaluate recursively if this is a variable.
665 if (Sym.isVariable() && !IsWeakRef) {
664 if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) {
666665 if (Sym.getVariableValue()->EvaluateAsRelocatableImpl(
667666 Res, Asm, Layout, Addrs, true, ForceVarExpansion)) {
668667 const MCSymbolRefExpr *A = Res.getSymA();
+0
-42
lib/MC/MCFixup.cpp less more
None //===- MCFixup.cpp - Assembly Fixup Implementation ------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/MC/MCFixup.h"
10 using namespace llvm;
11
12 static MCSymbolRefExpr::VariantKind getAccessVariant(const MCExpr *Expr) {
13 switch (Expr->getKind()) {
14 case MCExpr::Unary: {
15 assert(getAccessVariant(cast(Expr)->getSubExpr()) ==
16 MCSymbolRefExpr::VK_None);
17 return MCSymbolRefExpr::VK_None;
18 }
19
20 case MCExpr::Target:
21 llvm_unreachable("unsupported");
22
23 case MCExpr::Constant:
24 return MCSymbolRefExpr::VK_None;
25
26 case MCExpr::SymbolRef: {
27 const MCSymbolRefExpr *SRE = cast(Expr);
28 return SRE->getKind();
29 }
30 case MCExpr::Binary: {
31 const MCBinaryExpr *ABE = cast(Expr);
32 assert(getAccessVariant(ABE->getRHS()) == MCSymbolRefExpr::VK_None);
33 return getAccessVariant(ABE->getLHS());
34 }
35 }
36 llvm_unreachable("unknown MCExpr kind");
37 }
38
39 MCSymbolRefExpr::VariantKind MCFixup::getAccessVariant() const {
40 return ::getAccessVariant(getValue());
41 }
99 #include "llvm/MC/MCValue.h"
1010 #include "llvm/MC/MCExpr.h"
1111 #include "llvm/Support/Debug.h"
12 #include "llvm/Support/ErrorHandling.h"
1213 #include "llvm/Support/raw_ostream.h"
1314
1415 using namespace llvm;
4041 print(dbgs(), nullptr);
4142 }
4243 #endif
44
45 MCSymbolRefExpr::VariantKind MCValue::getAccessVariant() const {
46 const MCSymbolRefExpr *B = getSymB();
47 if (B) {
48 if (B->getKind() != MCSymbolRefExpr::VK_None)
49 llvm_unreachable("unsupported");
50 }
51
52 const MCSymbolRefExpr *A = getSymA();
53 if (!A)
54 return MCSymbolRefExpr::VK_None;
55
56 MCSymbolRefExpr::VariantKind Kind = A->getKind();
57 if (Kind == MCSymbolRefExpr::VK_WEAKREF)
58 return MCSymbolRefExpr::VK_None;
59 return Kind;
60 }
7373 unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
7474 const MCFixup &Fixup,
7575 bool IsPCRel) const {
76 MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant();
76 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
7777
7878 unsigned Type = 0;
7979 if (IsPCRel) {
4040 PPCELFObjectWriter::~PPCELFObjectWriter() {
4141 }
4242
43 static MCSymbolRefExpr::VariantKind getAccessVariant(const MCFixup &Fixup) {
43 static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
44 const MCFixup &Fixup) {
4445 const MCExpr *Expr = Fixup.getValue();
4546
4647 if (Expr->getKind() != MCExpr::Target)
47 return Fixup.getAccessVariant();
48 return Target.getAccessVariant();
4849
4950 switch (cast(Expr)->getKind()) {
5051 case PPCMCExpr::VK_PPC_None:
7172 const MCFixup &Fixup,
7273 bool IsPCRel) const
7374 {
74 MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Fixup);
75 MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
7576
7677 // determine the type of the relocation
7778 unsigned Type;
8181 unsigned SystemZObjectWriter::GetRelocType(const MCValue &Target,
8282 const MCFixup &Fixup,
8383 bool IsPCRel) const {
84 MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant();
84 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
8585 unsigned Kind = Fixup.getKind();
8686 switch (Modifier) {
8787 case MCSymbolRefExpr::VK_None:
4242 bool IsPCRel) const {
4343 // determine the type of the relocation
4444
45 MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant();
45 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
4646 unsigned Type;
4747 if (getEMachine() == ELF::EM_X86_64) {
4848 if (IsPCRel) {
6161 // CHECK-NEXT: 0x9E R_386_PC16 und_symbol 0x0
6262 // Relocation 28 (und_symbol-bar2) is of type R_386_PC8
6363 // CHECK-NEXT: 0xA0 R_386_PC8 und_symbol 0x0
64 // CHECK-NEXT: 0xA3 R_386_GOTOFF und_symbol 0x0
6465 // CHECK-NEXT: }
6566 // CHECK-NEXT: ]
6667
126127 .word und_symbol-bar2
127128 .byte und_symbol-bar2
128129
130 leal 1 + und_symbol@GOTOFF, %edi
131
129132 .section zedsec,"awT",@progbits
130133 zed:
131134 .long 0
2424 .word foo-bar
2525 .byte foo-bar
2626
27 # this should probably be an error...
2728 zed = foo +2
2829 call zed@PLT
2930
5657 // CHECK-NEXT: 0x85 R_X86_64_TPOFF64 baz 0x0
5758 // CHECK-NEXT: 0x8D R_X86_64_PC16 foo 0x8D
5859 // CHECK-NEXT: 0x8F R_X86_64_PC8 foo 0x8F
59 // CHECK-NEXT: 0x91 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFE
60 // CHECK-NEXT: 0x91 R_X86_64_PLT32 zed 0xFFFFFFFFFFFFFFFC
6061 // CHECK-NEXT: 0x98 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFB
6162 // CHECK-NEXT: 0x9D R_X86_64_GOTPC32 _GLOBAL_OFFSET_TABLE_ 0x1
6263 // CHECK-NEXT: 0xA3 R_X86_64_GOTPC64 _GLOBAL_OFFSET_TABLE_ 0x2