unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
// See <reloc.h>.
- uint32_t Address = Layout.getFragmentOffset(Fragment) + Fixup.Offset;
+ uint32_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.Offset;
+ uint32_t FixupAddress = Layout.getFragmentAddress(Fragment) + Fixup.Offset;
int64_t Value = 0;
unsigned Index = 0;
unsigned IsExtern = 0;
Type = RIT_X86_64_Unsigned;
MachRelocationEntry MRE;
- MRE.Word0 = Address;
+ MRE.Word0 = FixupOffset;
MRE.Word1 = ((Index << 0) |
(IsPCRel << 24) |
(Log2Size << 25) |
// Add the local offset, if needed.
if (Base != &SD)
Value += Layout.getSymbolAddress(&SD) - Layout.getSymbolAddress(Base);
- } else {
+ } else if (Symbol->isInSection()) {
// The index is the section ordinal (1-based).
Index = SD.getFragment()->getParent()->getOrdinal() + 1;
IsExtern = 0;
Value += Layout.getSymbolAddress(&SD);
if (IsPCRel)
- Value -= Address + (1 << Log2Size);
+ Value -= FixupAddress + (1 << Log2Size);
+ } else {
+ report_fatal_error("unsupported relocation of undefined symbol '" +
+ Symbol->getName() + "'");
}
MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind();
// struct relocation_info (8 bytes)
MachRelocationEntry MRE;
- MRE.Word0 = Address;
+ MRE.Word0 = FixupOffset;
MRE.Word1 = ((Index << 0) |
(IsPCRel << 24) |
(Log2Size << 25) |
const MCFragment *Fragment,
const MCAsmFixup &Fixup, MCValue Target,
uint64_t &FixedValue) {
- uint32_t Address = Layout.getFragmentOffset(Fragment) + Fixup.Offset;
+ uint32_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.Offset;
unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind);
unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
unsigned Type = RIT_Vanilla;
}
MachRelocationEntry MRE;
- MRE.Word0 = ((Address << 0) |
- (Type << 24) |
- (Log2Size << 28) |
- (IsPCRel << 30) |
+ MRE.Word0 = ((FixupOffset << 0) |
+ (Type << 24) |
+ (Log2Size << 28) |
+ (IsPCRel << 30) |
RF_Scattered);
MRE.Word1 = Value;
Relocations[Fragment->getParent()].push_back(MRE);
// If this is a difference or a defined symbol plus an offset, then we need
// a scattered relocation entry.
+ // Differences always require scattered relocations.
+ if (Target.getSymB())
+ return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup,
+ Target, FixedValue);
+
+ // Get the symbol data, if any.
+ MCSymbolData *SD = 0;
+ if (Target.getSymA())
+ SD = &Asm.getSymbolData(Target.getSymA()->getSymbol());
+
+ // If this is an internal relocation with an offset, it also needs a
+ // scattered relocation entry.
uint32_t Offset = Target.getConstant();
if (IsPCRel)
Offset += 1 << Log2Size;
- if (Target.getSymB() ||
- (Target.getSymA() && !Target.getSymA()->getSymbol().isUndefined() &&
- Offset)) {
- RecordScatteredRelocation(Asm, Layout, Fragment, Fixup,Target,FixedValue);
- return;
- }
+ if (Offset && SD && !doesSymbolRequireExternRelocation(SD))
+ return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup,
+ Target, FixedValue);
// See <reloc.h>.
- uint32_t Address = Layout.getFragmentOffset(Fragment) + Fixup.Offset;
+ uint32_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.Offset;
uint32_t Value = 0;
unsigned Index = 0;
unsigned IsExtern = 0;
Type = RIT_Vanilla;
Value = 0;
} else {
- const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
- MCSymbolData *SD = &Asm.getSymbolData(*Symbol);
-
// Check whether we need an external or internal relocation.
if (doesSymbolRequireExternRelocation(SD)) {
IsExtern = 1;
// struct relocation_info (8 bytes)
MachRelocationEntry MRE;
- MRE.Word0 = Address;
+ MRE.Word0 = FixupOffset;
MRE.Word1 = ((Index << 0) |
(IsPCRel << 24) |
(Log2Size << 25) |