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:
Jim Grosbach 2010-12-14 18:46:57 +00:00
parent 74ba8b77e6
commit 25d3e79b23
3 changed files with 32 additions and 0 deletions

View File

@ -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.
///

View File

@ -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;
}

View File

@ -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) {