//===- lib/MC/MachObjectWriter.cpp - Mach-O File Writer -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCMachObjectWriter.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCMachOSymbolFlags.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Object/MachOFormat.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetAsmBackend.h"
// FIXME: Gross.
#include "../Target/X86/X86FixupKinds.h"
#include <vector>
using namespace llvm;
using namespace llvm::object;
// FIXME: this has been copied from (or to) X86AsmBackend.cpp
static unsigned getFixupKindLog2Size(unsigned Kind) {
switch (Kind) {
// FIXME: Until ARM has it's own relocation stuff spun off, it comes
// through here and we don't want it to puke all over. Any reasonable
// values will only come when ARM relocation support gets added, at which
// point this will be X86 only again and the llvm_unreachable can be
// re-enabled.
default: return 0;// llvm_unreachable("invalid fixup kind!");
case FK_PCRel_1:
case FK_Data_1: return 0;
case FK_PCRel_2:
case FK_Data_2: return 1;
case FK_PCRel_4:
case X86::reloc_riprel_4byte:
case X86::reloc_riprel_4byte_movq_load:
case X86::reloc_signed_4byte:
case FK_Data_4: return 2;
case FK_Data_8: return 3;
}
}
static bool doesSymbolRequireExternRelocation(MCSymbolData *SD) {
// Undefined symbols are always extern.
if (SD->Symbol->isUndefined())
return true;
// References to weak definitions require external relocation entries; the
// definition may not always be the one in the same object file.
if (SD->getFlags() & SF_WeakDefinition)
return true;
// Otherwise, we can use an internal relocation.
return false;
}
static bool isScatteredFixupFullyResolved(const MCAssembler &Asm,
const MCValue Target,
const MCSymbolData *BaseSymbol) {
// The effective fixup address is
// addr(atom(A)) + offset(A)
// - addr(atom(B)) - offset(B)
// - addr(BaseSymbol) + <fixup offset from base symbol>
// and the offsets are not relocatable, so the fixup is fully resolved when
// addr(atom(A)) - addr(atom(B)) - addr(BaseSymbol) == 0.
//
// Note that "false" is almost always conservatively correct (it means we emit
// a relocation which is unnecessary), except when it would force us to emit a
// relocation which the target cannot encode.
const MCSymbolData *A_Base = 0, *B_Base = 0;