forked from OSchip/llvm-project
ARM Fixups relative to thumb functions need to have the low bit of the value
set for interworking to work properly. rdar://8755956 llvm-svn: 121778
This commit is contained in:
parent
69b582fa94
commit
41955ff958
|
@ -11,6 +11,7 @@
|
|||
#define LLVM_MC_MCASSEMBLER_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
|
@ -662,6 +663,15 @@ private:
|
|||
|
||||
std::vector<IndirectSymbolData> IndirectSymbols;
|
||||
|
||||
/// The set of function symbols for which a .thumb_func directive has
|
||||
/// been seen.
|
||||
//
|
||||
// FIXME: We really would like this in target specific code rather than
|
||||
// here. Maybe when the relocation stuff moves to target specific,
|
||||
// this can go with it? The streamer would need some target specific
|
||||
// refactoring too.
|
||||
SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
|
||||
|
||||
unsigned RelaxAll : 1;
|
||||
unsigned SubsectionsViaSymbols : 1;
|
||||
|
||||
|
@ -738,6 +748,14 @@ public:
|
|||
void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout,
|
||||
MCObjectWriter *OW) const;
|
||||
|
||||
/// Check whether a given symbol has been flagged with .thumb_func.
|
||||
bool isThumbFunc(const MCSymbol *Func) const {
|
||||
return ThumbFuncs.count(Func);
|
||||
}
|
||||
|
||||
/// Flag a function symbol as the target of a .thumb_func directive.
|
||||
void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
|
||||
|
||||
public:
|
||||
/// Construct a new assembler instance.
|
||||
///
|
||||
|
|
|
@ -235,12 +235,15 @@ bool MCAssembler::EvaluateFixup(const MCObjectWriter &Writer,
|
|||
bool IsPCRel = Emitter.getFixupKindInfo(
|
||||
Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel;
|
||||
bool IsResolved = true;
|
||||
bool IsThumb = false;
|
||||
if (const MCSymbolRefExpr *A = Target.getSymA()) {
|
||||
const MCSymbol &Sym = A->getSymbol().AliasedSymbol();
|
||||
if (Sym.isDefined())
|
||||
Value += Layout.getSymbolOffset(&getSymbolData(Sym));
|
||||
else
|
||||
IsResolved = false;
|
||||
if (isThumbFunc(&Sym))
|
||||
IsThumb = true;
|
||||
}
|
||||
if (const MCSymbolRefExpr *B = Target.getSymB()) {
|
||||
const MCSymbol &Sym = B->getSymbol().AliasedSymbol();
|
||||
|
@ -263,6 +266,13 @@ bool MCAssembler::EvaluateFixup(const MCObjectWriter &Writer,
|
|||
Value -= Layout.getFragmentOffset(DF) + Fixup.getOffset();
|
||||
}
|
||||
|
||||
// ARM fixups based from a thumb function address need to have the low
|
||||
// bit set. The actual value is always at least 16-bit aligned, so the
|
||||
// low bit is normally clear and available for use as an ISA flag for
|
||||
// interworking.
|
||||
if (IsThumb)
|
||||
Value |= 1;
|
||||
|
||||
return IsResolved;
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,10 @@ void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
|
|||
|
||||
void MCMachOStreamer::EmitThumbFunc(MCSymbol *Func) {
|
||||
// FIXME: Flag the function ISA as thumb with DW_AT_APPLE_isa.
|
||||
|
||||
// Remember that the function is a thumb function. Fixup and relocation
|
||||
// values will need adjusted.
|
||||
getAssembler().setIsThumbFunc(Func);
|
||||
}
|
||||
|
||||
void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
|
||||
|
|
Loading…
Reference in New Issue