summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2014-11-24 18:09:47 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2014-11-24 18:09:47 +0000
commita69bcd5ed0fc53129e3b606e4ca37806d9b9c4bf (patch)
tree9a8f486eb52ec8d8f05c8f4cfdd569158f5f169a /llvm/lib/Target
parentc38deee8076f300e29214648108eddf33db3e200 (diff)
downloadbcm5719-llvm-a69bcd5ed0fc53129e3b606e4ca37806d9b9c4bf.tar.gz
bcm5719-llvm-a69bcd5ed0fc53129e3b606e4ca37806d9b9c4bf.zip
[PowerPC] Fix PR 21652 - copy st_other bits on symbol assignment
When processing an assignment in the integrated assembler that sets a symbol to the value of another symbol, we need to copy the st_other bits that encode the local entry point offset. Modeled after MipsTargetELFStreamer::emitAssignment handling of the ELF::STO_MIPS_MICROMIPS flag. llvm-svn: 222672
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index 00be8f444d3..f2da3896168 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -184,6 +184,23 @@ public:
if ((Flags & ELF::EF_PPC64_ABI) == 0)
MCA.setELFHeaderEFlags(Flags | 2);
}
+ void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override {
+ // When encoding an assignment to set symbol A to symbol B, also copy
+ // the st_other bits encoding the local entry point offset.
+ if (Value->getKind() != MCExpr::SymbolRef)
+ return;
+ const MCSymbol &RhsSym =
+ static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
+ MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym);
+ MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol);
+ // The "other" values are stored in the last 6 bits of the second byte.
+ // The traditional defines for STO values assume the full byte and thus
+ // the shift to pack it.
+ unsigned Other = MCELF::getOther(SymbolData) << 2;
+ Other &= ~ELF::STO_PPC64_LOCAL_MASK;
+ Other |= (MCELF::getOther(Data) << 2) & ELF::STO_PPC64_LOCAL_MASK;
+ MCELF::setOther(SymbolData, Other >> 2);
+ }
};
class PPCTargetMachOStreamer : public PPCTargetStreamer {
OpenPOWER on IntegriCloud