summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-04-29 12:46:50 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-04-29 12:46:50 +0000
commit1c5f439f417f7d60e399886e769fa59283a0913b (patch)
tree49c6e0b371c4dfcc2876f7c0f4199cdcf9adc3b2 /lib
parent65baf804ba6ac8284c0e0f63c42cfb3b85aa89b0 (diff)
downloadllvm-1c5f439f417f7d60e399886e769fa59283a0913b.tar.gz
llvm-1c5f439f417f7d60e399886e769fa59283a0913b.tar.bz2
llvm-1c5f439f417f7d60e399886e769fa59283a0913b.tar.xz
Centralize the handling of the thumb bit.
This patch centralizes the handling of the thumb bit around MCStreamer::isThumbFunc and makes isThumbFunc handle aliases. This fixes a corner case, but the main advantage is having just one way to check if a MCSymbol is thumb or not. This should still be refactored to be ARM only, but at least now it is just one predicate that has to be refactored instead of 3 (isThumbFunc, ELF_Other_ThumbFunc, and SF_ThumbFunc). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207522 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/MC/ELFObjectWriter.cpp17
-rw-r--r--lib/MC/MCAssembler.cpp25
-rw-r--r--lib/MC/MCMachOStreamer.cpp4
-rw-r--r--lib/MC/MachObjectWriter.cpp3
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp6
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp4
6 files changed, 40 insertions, 19 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 1b7ac64258..2e07e22dc3 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -215,7 +215,8 @@ class ELFObjectWriter : public MCObjectWriter {
const MCAsmLayout &Layout,
SectionIndexMapTy &SectionIndexMap);
- bool shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA,
+ bool shouldRelocateWithSymbol(const MCAssembler &Asm,
+ const MCSymbolRefExpr *RefA,
const MCSymbolData *SD, uint64_t C,
unsigned Type) const;
@@ -486,6 +487,7 @@ void ELFObjectWriter::WriteHeader(const MCAssembler &Asm,
uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData,
const MCAsmLayout &Layout) {
+ const MCSymbol &OrigSymbol = OrigData.getSymbol();
MCSymbolData *Data = &OrigData;
if (Data->isCommon() && Data->isExternal())
return Data->getCommonAlignment();
@@ -512,8 +514,8 @@ uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData,
}
}
- if ((Data && Data->getFlags() & ELF_Other_ThumbFunc) ||
- OrigData.getFlags() & ELF_Other_ThumbFunc)
+ const MCAssembler &Asm = Layout.getAssembler();
+ if (Asm.isThumbFunc(&OrigSymbol))
Res |= 1;
if (!Symbol || !Symbol->isInSection())
@@ -641,8 +643,6 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD,
BaseSD = &Layout.getAssembler().getSymbolData(*Base);
Type = mergeTypeForSet(Type, MCELF::GetType(*BaseSD));
}
- if (OrigData.getFlags() & ELF_Other_ThumbFunc)
- Type = ELF::STT_FUNC;
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
// Other and Visibility share the same byte with Visibility using the lower
@@ -737,7 +737,8 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
// It is always valid to create a relocation with a symbol. It is preferable
// to use a relocation with a section if that is possible. Using the section
// allows us to omit some local symbols from the symbol table.
-bool ELFObjectWriter::shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA,
+bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
+ const MCSymbolRefExpr *RefA,
const MCSymbolData *SD,
uint64_t C,
unsigned Type) const {
@@ -825,7 +826,7 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA,
// bit. With a symbol that is done by just having the symbol have that bit
// set, so we would lose the bit if we relocated with the section.
// FIXME: We could use the section but add the bit to the relocation value.
- if (SD->getFlags() & ELF_Other_ThumbFunc)
+ if (Asm.isThumbFunc(&Sym))
return true;
if (TargetObjectWriter->needsRelocateWithSymbol(Type))
@@ -887,7 +888,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCSymbolData *SymAD = SymA ? &Asm.getSymbolData(*SymA) : nullptr;
unsigned Type = GetRelocType(Target, Fixup, IsPCRel);
- bool RelocateWithSymbol = shouldRelocateWithSymbol(RefA, SymAD, C, Type);
+ bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymAD, C, Type);
if (!RelocateWithSymbol && SymA && !SymA->isUndefined())
C += Layout.getSymbolOffset(SymAD);
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index b3b2bb3d31..08d7321438 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -323,6 +323,31 @@ void MCAssembler::reset() {
getLOHContainer().reset();
}
+bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const {
+ if (ThumbFuncs.count(Symbol))
+ return true;
+
+ if (!Symbol->isVariable())
+ return false;
+
+ // FIXME: It looks like gas support some cases of the form "foo + 2". It
+ // is not clear if that is a bug or a feature.
+ const MCExpr *Expr = Symbol->getVariableValue();
+ const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr);
+ if (!Ref)
+ return false;
+
+ if (Ref->getKind() != MCSymbolRefExpr::VK_None)
+ return false;
+
+ const MCSymbol &Sym = Ref->getSymbol();
+ if (!isThumbFunc(&Sym))
+ return false;
+
+ ThumbFuncs.insert(Symbol); // Cache it.
+ return true;
+}
+
bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {
// Non-temporary labels should always be visible to the linker.
if (!Symbol.isTemporary())
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 23d28b62ca..c103e41e3a 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -237,10 +237,6 @@ void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) {
// Remember that the function is a thumb function. Fixup and relocation
// values will need adjusted.
getAssembler().setIsThumbFunc(Symbol);
-
- // Mark the thumb bit on the symbol.
- MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
- SD.setFlags(SD.getFlags() | SF_ThumbFunc);
}
bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index b4e53be7d5..cbaf0b87d6 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -351,6 +351,9 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
}
}
+ if (Layout.getAssembler().isThumbFunc(&Symbol))
+ Flags |= SF_ThumbFunc;
+
// struct nlist (12 bytes)
Write32(MSD.StringIndex);
diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
index 6d5fd6a293..e55aa66713 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -609,12 +609,8 @@ private:
}
void EmitThumbFunc(MCSymbol *Func) override {
- // FIXME: Anything needed here to flag the function as thumb?
-
getAssembler().setIsThumbFunc(Func);
-
- MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func);
- SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc);
+ EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
}
// Helper functions for ARM exception handling directives
diff --git a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
index 38ed5632e4..ecfa4e54b2 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
@@ -206,11 +206,11 @@ RecordARMScatteredHalfRelocation(MachObjectWriter *Writer,
// The thumb bit shouldn't be set in the 'other-half' bit of the
// relocation, but it will be set in FixedValue if the base symbol
// is a thumb function. Clear it out here.
- if (A_SD->getFlags() & SF_ThumbFunc)
+ if (Asm.isThumbFunc(A))
FixedValue &= 0xfffffffe;
break;
case ARM::fixup_t2_movt_hi16:
- if (A_SD->getFlags() & SF_ThumbFunc)
+ if (Asm.isThumbFunc(A))
FixedValue &= 0xfffffffe;
MovtBit = 1;
// Fallthrough