HexagonLDBackend.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
1//===- HexagonLDBackend.cpp -----------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#include "Hexagon.h" 10#include "HexagonELFDynamic.h" 11#include "HexagonLDBackend.h" 12#include "HexagonRelocator.h" 13#include "HexagonGNUInfo.h" 14 15#include <llvm/ADT/Triple.h> 16#include <llvm/Support/Casting.h> 17 18#include <mcld/LinkerConfig.h> 19#include <mcld/IRBuilder.h> 20#include <mcld/Fragment/FillFragment.h> 21#include <mcld/Fragment/RegionFragment.h> 22#include <mcld/Support/MemoryRegion.h> 23#include <mcld/Support/MsgHandling.h> 24#include <mcld/Support/TargetRegistry.h> 25#include <mcld/Object/ObjectBuilder.h> 26 27#include <cstring> 28 29using namespace mcld; 30 31//===----------------------------------------------------------------------===// 32// HexagonLDBackend 33//===----------------------------------------------------------------------===// 34HexagonLDBackend::HexagonLDBackend(const LinkerConfig& pConfig, 35 HexagonGNUInfo* pInfo) 36 : GNULDBackend(pConfig, pInfo), 37 m_pRelocator(NULL), 38 m_pGOT(NULL), 39 m_pPLT(NULL), 40 m_pRelDyn(NULL), 41 m_pRelPLT(NULL), 42 m_pDynamic(NULL), 43 m_pGOTSymbol(NULL) { 44} 45 46HexagonLDBackend::~HexagonLDBackend() 47{ 48 delete m_pRelocator; 49 delete m_pGOT; 50 delete m_pPLT; 51 delete m_pRelDyn; 52 delete m_pRelPLT; 53 delete m_pDynamic; 54} 55 56bool HexagonLDBackend::initRelocator() 57{ 58 if (NULL == m_pRelocator) { 59 m_pRelocator = new HexagonRelocator(*this); 60 } 61 return true; 62} 63 64Relocator* HexagonLDBackend::getRelocator() 65{ 66 assert(NULL != m_pRelocator); 67 return m_pRelocator; 68} 69 70void HexagonLDBackend::doPreLayout(IRBuilder& pBuilder) 71{ 72 // initialize .dynamic data 73 if (!config().isCodeStatic() && NULL == m_pDynamic) 74 m_pDynamic = new HexagonELFDynamic(*this, config()); 75} 76 77void HexagonLDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) 78{ 79} 80 81/// dynamic - the dynamic section of the target machine. 82/// Use co-variant return type to return its own dynamic section. 83HexagonELFDynamic& HexagonLDBackend::dynamic() 84{ 85 assert(NULL != m_pDynamic); 86 return *m_pDynamic; 87} 88 89/// dynamic - the dynamic section of the target machine. 90/// Use co-variant return type to return its own dynamic section. 91const HexagonELFDynamic& HexagonLDBackend::dynamic() const 92{ 93 assert(NULL != m_pDynamic); 94 return *m_pDynamic; 95} 96 97void HexagonLDBackend::scanRelocation(Relocation& pReloc, 98 IRBuilder& pBuilder, 99 Module& pModule, 100 LDSection& pSection) 101{ 102 pReloc.updateAddend(); 103} 104 105uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection, 106 MemoryRegion& pRegion) const 107{ 108 return 0; 109} 110 111HexagonGOT& HexagonLDBackend::getGOT() 112{ 113 assert(NULL != m_pGOT); 114 return *m_pGOT; 115} 116 117const HexagonGOT& HexagonLDBackend::getGOT() const 118{ 119 assert(NULL != m_pGOT); 120 return *m_pGOT; 121} 122 123HexagonPLT& HexagonLDBackend::getPLT() 124{ 125 assert(NULL != m_pPLT && "PLT section not exist"); 126 return *m_pPLT; 127} 128 129const HexagonPLT& HexagonLDBackend::getPLT() const 130{ 131 assert(NULL != m_pPLT && "PLT section not exist"); 132 return *m_pPLT; 133} 134 135OutputRelocSection& HexagonLDBackend::getRelDyn() 136{ 137 assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 138 return *m_pRelDyn; 139} 140 141const OutputRelocSection& HexagonLDBackend::getRelDyn() const 142{ 143 assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 144 return *m_pRelDyn; 145} 146 147OutputRelocSection& HexagonLDBackend::getRelPLT() 148{ 149 assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 150 return *m_pRelPLT; 151} 152 153const OutputRelocSection& HexagonLDBackend::getRelPLT() const 154{ 155 assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 156 return *m_pRelPLT; 157} 158 159unsigned int 160HexagonLDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 161{ 162 const ELFFileFormat* file_format = getOutputFormat(); 163 164 if (&pSectHdr == &file_format->getGOT()) { 165 if (config().options().hasNow()) 166 return SHO_RELRO; 167 return SHO_RELRO_LAST; 168 } 169 170 if (&pSectHdr == &file_format->getPLT()) 171 return SHO_PLT; 172 173 return SHO_UNDEFINED; 174} 175 176void HexagonLDBackend::initTargetSections(Module& pModule, 177 ObjectBuilder& pBuilder) 178{ 179 if (LinkerConfig::Object != config().codeGenType()) { 180 ELFFileFormat* file_format = getOutputFormat(); 181 // initialize .got 182 LDSection& got = file_format->getGOT(); 183 m_pGOT = new HexagonGOT(got); 184 185 // initialize .plt 186 LDSection& plt = file_format->getPLT(); 187 m_pPLT = new HexagonPLT(plt, 188 *m_pGOT, 189 config()); 190 191 // initialize .rel.plt 192 LDSection& relplt = file_format->getRelPlt(); 193 relplt.setLink(&plt); 194 m_pRelPLT = new OutputRelocSection(pModule, relplt); 195 196 // initialize .rel.dyn 197 LDSection& reldyn = file_format->getRelDyn(); 198 m_pRelDyn = new OutputRelocSection(pModule, reldyn); 199 200 } 201} 202 203void HexagonLDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 204{ 205 if (LinkerConfig::Object != config().codeGenType()) { 206 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 207 // same name in input 208 m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 209 "_GLOBAL_OFFSET_TABLE_", 210 ResolveInfo::Object, 211 ResolveInfo::Define, 212 ResolveInfo::Local, 213 0x0, // size 214 0x0, // value 215 FragmentRef::Null(), 216 ResolveInfo::Hidden); 217 } 218} 219 220/// finalizeSymbol - finalize the symbol value 221bool HexagonLDBackend::finalizeTargetSymbols() 222{ 223 return true; 224} 225 226/// doCreateProgramHdrs - backend can implement this function to create the 227/// target-dependent segments 228void HexagonLDBackend::doCreateProgramHdrs(Module& pModule) 229{ 230 // TODO 231} 232 233namespace mcld { 234 235//===----------------------------------------------------------------------===// 236/// createHexagonLDBackend - the help funtion to create corresponding 237/// HexagonLDBackend 238TargetLDBackend* createHexagonLDBackend(const llvm::Target& pTarget, 239 const LinkerConfig& pConfig) 240{ 241 if (pConfig.targets().triple().isOSDarwin()) { 242 assert(0 && "MachO linker is not supported yet"); 243 /** 244 return new HexagonMachOLDBackend(createHexagonMachOArchiveReader, 245 createHexagonMachOObjectReader, 246 createHexagonMachOObjectWriter); 247 **/ 248 } 249 if (pConfig.targets().triple().isOSWindows()) { 250 assert(0 && "COFF linker is not supported yet"); 251 /** 252 return new HexagonCOFFLDBackend(createHexagonCOFFArchiveReader, 253 createHexagonCOFFObjectReader, 254 createHexagonCOFFObjectWriter); 255 **/ 256 } 257 return new HexagonLDBackend(pConfig, 258 new HexagonGNUInfo(pConfig.targets().triple())); 259} 260 261} // namespace of mcld 262 263//===----------------------------------------------------------------------===// 264// Force static initialization. 265//===----------------------------------------------------------------------===// 266extern "C" void MCLDInitializeHexagonLDBackend() { 267 // Register the linker backend 268 mcld::TargetRegistry::RegisterTargetLDBackend(TheHexagonTarget, 269 createHexagonLDBackend); 270} 271