156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//===-- X86TargetObjectFile.cpp - X86 Object Info -------------------------===// 256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// 356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// The LLVM Compiler Infrastructure 456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// 556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// This file is distributed under the University of Illinois Open Source 656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// License. See LICENSE.TXT for details. 756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson// 856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson//===----------------------------------------------------------------------===// 956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 1056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "X86TargetObjectFile.h" 1156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "llvm/IR/Mangler.h" 1256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "llvm/IR/Operator.h" 1356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "llvm/MC/MCContext.h" 1456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "llvm/MC/MCExpr.h" 1556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "llvm/MC/MCSectionELF.h" 1656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "llvm/Support/Dwarf.h" 1756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "llvm/Target/TargetLowering.h" 1856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 1956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonusing namespace llvm; 2056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonusing namespace dwarf; 2156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 2256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonconst MCExpr *X86_64MachoTargetObjectFile::getTTypeGlobalReference( 2356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const GlobalValue *GV, unsigned Encoding, Mangler &Mang, 2456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const TargetMachine &TM, MachineModuleInfo *MMI, 2556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson MCStreamer &Streamer) const { 2656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 2756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // On Darwin/X86-64, we can reference dwarf symbols with foo@GOTPCREL+4, which 2856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // is an indirect pc-relative reference. 2956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if ((Encoding & DW_EH_PE_indirect) && (Encoding & DW_EH_PE_pcrel)) { 3056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const MCSymbol *Sym = TM.getSymbol(GV, Mang); 3156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const MCExpr *Res = 3256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, getContext()); 3356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const MCExpr *Four = MCConstantExpr::Create(4, getContext()); 3456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return MCBinaryExpr::CreateAdd(Res, Four, getContext()); 3556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 3656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 3756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return TargetLoweringObjectFileMachO::getTTypeGlobalReference( 3856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson GV, Encoding, Mang, TM, MMI, Streamer); 3956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson} 4056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 4156ed4167b942ec265f9cee70ac4d71d10b3835ceBen DodsonMCSymbol *X86_64MachoTargetObjectFile::getCFIPersonalitySymbol( 4256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM, 4356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson MachineModuleInfo *MMI) const { 4456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return TM.getSymbol(GV, Mang); 4556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson} 4656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 4756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonvoid 4856ed4167b942ec265f9cee70ac4d71d10b3835ceBen DodsonX86LinuxTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { 4956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson TargetLoweringObjectFileELF::Initialize(Ctx, TM); 5056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson InitializeELF(TM.Options.UseInitArray); 5156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson} 5256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 5356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonconst MCExpr * 5456ed4167b942ec265f9cee70ac4d71d10b3835ceBen DodsonX86LinuxTargetObjectFile::getDebugThreadLocalSymbol( 5556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const MCSymbol *Sym) const { 5656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_DTPOFF, getContext()); 5756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson} 5856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 5956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonconst MCExpr *X86WindowsTargetObjectFile::getExecutableRelativeSymbol( 6056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const ConstantExpr *CE, Mangler &Mang, const TargetMachine &TM) const { 6156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // We are looking for the difference of two symbols, need a subtraction 6256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // operation. 6356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const SubOperator *Sub = dyn_cast<SubOperator>(CE); 6456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (!Sub) 6556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return nullptr; 6656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 6756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // Symbols must first be numbers before we can subtract them, we need to see a 6856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // ptrtoint on both subtraction operands. 6956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const PtrToIntOperator *SubLHS = 7056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson dyn_cast<PtrToIntOperator>(Sub->getOperand(0)); 7156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const PtrToIntOperator *SubRHS = 7256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson dyn_cast<PtrToIntOperator>(Sub->getOperand(1)); 7356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (!SubLHS || !SubRHS) 7456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return nullptr; 7556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 7656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // Our symbols should exist in address space zero, cowardly no-op if 7756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // otherwise. 7856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (SubLHS->getPointerAddressSpace() != 0 || 7956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson SubRHS->getPointerAddressSpace() != 0) 8056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return nullptr; 8156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 8256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // Both ptrtoint instructions must wrap global variables: 8356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // - Only global variables are eligible for image relative relocations. 8456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // - The subtrahend refers to the special symbol __ImageBase, a global. 8556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const GlobalVariable *GVLHS = 8656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson dyn_cast<GlobalVariable>(SubLHS->getPointerOperand()); 8756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson const GlobalVariable *GVRHS = 8856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson dyn_cast<GlobalVariable>(SubRHS->getPointerOperand()); 8956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (!GVLHS || !GVRHS) 9056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return nullptr; 9156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 9256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // We expect __ImageBase to be a global variable without a section, externally 9356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // defined. 9456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // 9556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // It should look something like this: @__ImageBase = external constant i8 9656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (GVRHS->isThreadLocal() || GVRHS->getName() != "__ImageBase" || 9756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson !GVRHS->hasExternalLinkage() || GVRHS->hasInitializer() || 9856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson GVRHS->hasSection()) 9956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return nullptr; 10056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 10156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // An image-relative, thread-local, symbol makes no sense. 10256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (GVLHS->isThreadLocal()) 10356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return nullptr; 10456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 10556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return MCSymbolRefExpr::Create(TM.getSymbol(GVLHS, Mang), 10656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson MCSymbolRefExpr::VK_COFF_IMGREL32, 10756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson getContext()); 10856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson} 10956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson