#include "llvm/MC/MCMachObjectWriter.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCValue.h"
-#include "llvm/Object/MachOFormat.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/MachO.h"
using namespace llvm;
-using namespace llvm::object;
namespace {
class PPCMachObjectWriter : public MCMachObjectTargetWriter {
void RecordRelocation(MachObjectWriter *Writer, const MCAssembler &Asm,
const MCAsmLayout &Layout, const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
- uint64_t &FixedValue) {
+ uint64_t &FixedValue) override {
if (Writer->is64Bit()) {
report_fatal_error("Relocation emission for MachO/PPC64 unimplemented.");
} else
Target.isAbsolute() ? MCSymbolRefExpr::VK_None
: Target.getSymA()->getKind();
// determine the type of the relocation
- unsigned Type = macho::RIT_Vanilla;
+ unsigned Type = MachO::GENERIC_RELOC_VANILLA;
if (IsPCRel) { // relative to PC
switch ((unsigned)FixupKind) {
default:
report_fatal_error("Unimplemented fixup kind (relative)");
case PPC::fixup_ppc_br24:
- Type = macho::RIT_PPC_BR24; // R_PPC_REL24
+ Type = MachO::PPC_RELOC_BR24; // R_PPC_REL24
break;
case PPC::fixup_ppc_brcond14:
- Type = macho::RIT_PPC_BR14;
+ Type = MachO::PPC_RELOC_BR14;
break;
case PPC::fixup_ppc_half16:
switch (Modifier) {
default:
llvm_unreachable("Unsupported modifier for half16 fixup");
case MCSymbolRefExpr::VK_PPC_HA:
- Type = macho::RIT_PPC_HA16;
+ Type = MachO::PPC_RELOC_HA16;
break;
case MCSymbolRefExpr::VK_PPC_LO:
- Type = macho::RIT_PPC_LO16;
+ Type = MachO::PPC_RELOC_LO16;
break;
case MCSymbolRefExpr::VK_PPC_HI:
- Type = macho::RIT_PPC_HI16;
+ Type = MachO::PPC_RELOC_HI16;
break;
}
break;
default:
llvm_unreachable("Unsupported modifier for half16 fixup");
case MCSymbolRefExpr::VK_PPC_HA:
- Type = macho::RIT_PPC_HA16_SECTDIFF;
+ Type = MachO::PPC_RELOC_HA16_SECTDIFF;
break;
case MCSymbolRefExpr::VK_PPC_LO:
- Type = macho::RIT_PPC_LO16_SECTDIFF;
+ Type = MachO::PPC_RELOC_LO16_SECTDIFF;
break;
case MCSymbolRefExpr::VK_PPC_HI:
- Type = macho::RIT_PPC_HI16_SECTDIFF;
+ Type = MachO::PPC_RELOC_HI16_SECTDIFF;
break;
}
break;
return Type;
}
-static void makeRelocationInfo(macho::RelocationEntry &MRE,
+static void makeRelocationInfo(MachO::any_relocation_info &MRE,
const uint32_t FixupOffset, const uint32_t Index,
const unsigned IsPCRel, const unsigned Log2Size,
const unsigned IsExtern, const unsigned Type) {
- MRE.Word0 = FixupOffset;
+ MRE.r_word0 = FixupOffset;
// The bitfield offsets that work (as determined by trial-and-error)
// are different than what is documented in the mach-o manuals.
- // Is this an endianness issue w/ PPC?
- MRE.Word1 = ((Index << 8) | // was << 0
- (IsPCRel << 7) | // was << 24
- (Log2Size << 5) | // was << 25
- (IsExtern << 4) | // was << 27
- (Type << 0)); // was << 28
+ // This appears to be an endianness issue; reversing the order of the
+ // documented bitfields in <llvm/Support/MachO.h> fixes this (but
+ // breaks x86/ARM assembly).
+ MRE.r_word1 = ((Index << 8) | // was << 0
+ (IsPCRel << 7) | // was << 24
+ (Log2Size << 5) | // was << 25
+ (IsExtern << 4) | // was << 27
+ (Type << 0)); // was << 28
}
static void
-makeScatteredRelocationInfo(macho::RelocationEntry &MRE, const uint32_t Addr,
- const unsigned Type, const unsigned Log2Size,
- const unsigned IsPCRel, const uint32_t Value2) {
+makeScatteredRelocationInfo(MachO::any_relocation_info &MRE,
+ const uint32_t Addr, const unsigned Type,
+ const unsigned Log2Size, const unsigned IsPCRel,
+ const uint32_t Value2) {
// For notes on bitfield positions and endianness, see:
// https://developer.apple.com/library/mac/documentation/developertools/conceptual/MachORuntime/Reference/reference.html#//apple_ref/doc/uid/20001298-scattered_relocation_entry
- MRE.Word0 = ((Addr << 0) | (Type << 24) | (Log2Size << 28) | (IsPCRel << 30) |
- macho::RF_Scattered);
- MRE.Word1 = Value2;
+ MRE.r_word0 = ((Addr << 0) | (Type << 24) | (Log2Size << 28) |
+ (IsPCRel << 30) | MachO::R_SCATTERED);
+ MRE.r_word1 = Value2;
}
/// Compute fixup offset (address).
uint32_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
// On Mach-O, ppc_fixup_half16 relocations must refer to the
// start of the instruction, not the second halfword, as ELF does
- if (Fixup.getKind() == PPC::fixup_ppc_half16)
+ if (unsigned(Fixup.getKind()) == PPC::fixup_ppc_half16)
FixupOffset &= ~uint32_t(3);
return FixupOffset;
}
// See <reloc.h>.
const MCSymbol *A = &Target.getSymA()->getSymbol();
- MCSymbolData *A_SD = &Asm.getSymbolData(*A);
+ const MCSymbolData *A_SD = &Asm.getSymbolData(*A);
if (!A_SD->getFragment())
report_fatal_error("symbol '" + A->getName() +
uint32_t Value2 = 0;
if (const MCSymbolRefExpr *B = Target.getSymB()) {
- MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol());
+ const MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol());
if (!B_SD->getFragment())
report_fatal_error("symbol '" + B->getSymbol().getName() +
"' can not be undefined in a subtraction expression");
- // FIXME: is Type correct? see include/llvm/Object/MachOFormat.h
+ // FIXME: is Type correct? see include/llvm/Support/MachO.h
Value2 = Writer->getSymbolAddress(B_SD, Layout);
FixedValue -= Writer->getSectionAddress(B_SD->getFragment()->getParent());
}
// FIXME: does FixedValue get used??
// Relocations are written out in reverse order, so the PAIR comes first.
- if (Type == macho::RIT_PPC_SECTDIFF || Type == macho::RIT_PPC_HI16_SECTDIFF ||
- Type == macho::RIT_PPC_LO16_SECTDIFF ||
- Type == macho::RIT_PPC_HA16_SECTDIFF ||
- Type == macho::RIT_PPC_LO14_SECTDIFF ||
- Type == macho::RIT_PPC_LOCAL_SECTDIFF) {
+ if (Type == MachO::PPC_RELOC_SECTDIFF ||
+ Type == MachO::PPC_RELOC_HI16_SECTDIFF ||
+ Type == MachO::PPC_RELOC_LO16_SECTDIFF ||
+ Type == MachO::PPC_RELOC_HA16_SECTDIFF ||
+ Type == MachO::PPC_RELOC_LO14_SECTDIFF ||
+ Type == MachO::PPC_RELOC_LOCAL_SECTDIFF) {
// X86 had this piece, but ARM does not
// If the offset is too large to fit in a scattered relocation,
// we're hosed. It's an unfortunate limitation of the MachO format.
// see PPCMCExpr::EvaluateAsRelocatableImpl()
uint32_t other_half = 0;
switch (Type) {
- case macho::RIT_PPC_LO16_SECTDIFF:
+ case MachO::PPC_RELOC_LO16_SECTDIFF:
other_half = (FixedValue >> 16) & 0xffff;
// applyFixupOffset longer extracts the high part because it now assumes
// this was already done.
// So we need to adjust FixedValue again here.
FixedValue &= 0xffff;
break;
- case macho::RIT_PPC_HA16_SECTDIFF:
+ case MachO::PPC_RELOC_HA16_SECTDIFF:
other_half = FixedValue & 0xffff;
FixedValue =
((FixedValue >> 16) + ((FixedValue & 0x8000) ? 1 : 0)) & 0xffff;
break;
- case macho::RIT_PPC_HI16_SECTDIFF:
+ case MachO::PPC_RELOC_HI16_SECTDIFF:
other_half = FixedValue & 0xffff;
FixedValue = (FixedValue >> 16) & 0xffff;
break;
break;
}
- macho::RelocationEntry MRE;
- makeScatteredRelocationInfo(MRE, other_half, macho::RIT_Pair, Log2Size,
- IsPCRel, Value2);
+ MachO::any_relocation_info MRE;
+ makeScatteredRelocationInfo(MRE, other_half, MachO::GENERIC_RELOC_PAIR,
+ Log2Size, IsPCRel, Value2);
Writer->addRelocation(Fragment->getParent(), MRE);
} else {
// If the offset is more than 24-bits, it won't fit in a scattered
if (FixupOffset > 0xffffff)
return false;
}
- macho::RelocationEntry MRE;
+ MachO::any_relocation_info MRE;
makeScatteredRelocationInfo(MRE, FixupOffset, Type, Log2Size, IsPCRel, Value);
Writer->addRelocation(Fragment->getParent(), MRE);
return true;
// relocations.
if (Target.getSymB() &&
// Q: are branch targets ever scattered?
- RelocType != macho::RIT_PPC_BR24 && RelocType != macho::RIT_PPC_BR14) {
+ RelocType != MachO::PPC_RELOC_BR24 &&
+ RelocType != MachO::PPC_RELOC_BR14) {
RecordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, Target,
Log2Size, FixedValue);
return;
// this doesn't seem right for RIT_PPC_BR24
// Get the symbol data, if any.
- MCSymbolData *SD = 0;
+ const MCSymbolData *SD = nullptr;
if (Target.getSymA())
SD = &Asm.getSymbolData(Target.getSymA()->getSymbol());
}
// struct relocation_info (8 bytes)
- macho::RelocationEntry MRE;
+ MachO::any_relocation_info MRE;
makeRelocationInfo(MRE, FixupOffset, Index, IsPCRel, Log2Size, IsExtern,
Type);
Writer->addRelocation(Fragment->getParent(), MRE);