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 29 using namespace mcld; 30 31 //===----------------------------------------------------------------------===// 32 // HexagonLDBackend 33 //===----------------------------------------------------------------------===// 34 HexagonLDBackend::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 46 HexagonLDBackend::~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 56 bool HexagonLDBackend::initRelocator() 57 { 58 if (NULL == m_pRelocator) { 59 m_pRelocator = new HexagonRelocator(*this); 60 } 61 return true; 62 } 63 64 Relocator* HexagonLDBackend::getRelocator() 65 { 66 assert(NULL != m_pRelocator); 67 return m_pRelocator; 68 } 69 70 void 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 77 void 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. 83 HexagonELFDynamic& 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. 91 const HexagonELFDynamic& HexagonLDBackend::dynamic() const 92 { 93 assert(NULL != m_pDynamic); 94 return *m_pDynamic; 95 } 96 97 void HexagonLDBackend::scanRelocation(Relocation& pReloc, 98 IRBuilder& pBuilder, 99 Module& pModule, 100 LDSection& pSection) 101 { 102 pReloc.updateAddend(); 103 } 104 105 uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection, 106 MemoryRegion& pRegion) const 107 { 108 return 0; 109 } 110 111 HexagonGOT& HexagonLDBackend::getGOT() 112 { 113 assert(NULL != m_pGOT); 114 return *m_pGOT; 115 } 116 117 const HexagonGOT& HexagonLDBackend::getGOT() const 118 { 119 assert(NULL != m_pGOT); 120 return *m_pGOT; 121 } 122 123 HexagonPLT& HexagonLDBackend::getPLT() 124 { 125 assert(NULL != m_pPLT && "PLT section not exist"); 126 return *m_pPLT; 127 } 128 129 const HexagonPLT& HexagonLDBackend::getPLT() const 130 { 131 assert(NULL != m_pPLT && "PLT section not exist"); 132 return *m_pPLT; 133 } 134 135 OutputRelocSection& HexagonLDBackend::getRelDyn() 136 { 137 assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 138 return *m_pRelDyn; 139 } 140 141 const OutputRelocSection& HexagonLDBackend::getRelDyn() const 142 { 143 assert(NULL != m_pRelDyn && ".rel.dyn section not exist"); 144 return *m_pRelDyn; 145 } 146 147 OutputRelocSection& HexagonLDBackend::getRelPLT() 148 { 149 assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 150 return *m_pRelPLT; 151 } 152 153 const OutputRelocSection& HexagonLDBackend::getRelPLT() const 154 { 155 assert(NULL != m_pRelPLT && ".rel.plt section not exist"); 156 return *m_pRelPLT; 157 } 158 159 unsigned int 160 HexagonLDBackend::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 176 void 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 203 void 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 221 bool HexagonLDBackend::finalizeTargetSymbols() 222 { 223 return true; 224 } 225 226 /// doCreateProgramHdrs - backend can implement this function to create the 227 /// target-dependent segments 228 void HexagonLDBackend::doCreateProgramHdrs(Module& pModule) 229 { 230 // TODO 231 } 232 233 namespace mcld { 234 235 //===----------------------------------------------------------------------===// 236 /// createHexagonLDBackend - the help funtion to create corresponding 237 /// HexagonLDBackend 238 TargetLDBackend* 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 //===----------------------------------------------------------------------===// 266 extern "C" void MCLDInitializeHexagonLDBackend() { 267 // Register the linker backend 268 mcld::TargetRegistry::RegisterTargetLDBackend(TheHexagonTarget, 269 createHexagonLDBackend); 270 } 271