blob: da2399e0603a71a03f8b634090fe35d6c54f5367 [file] [log] [blame]
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001//===- MipsLDBackend.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//===----------------------------------------------------------------------===//
Shih-wei Liaocedee4b2012-08-02 23:13:03 -07009#include "Mips.h"
10#include "MipsELFDynamic.h"
11#include "MipsLDBackend.h"
12#include "MipsRelocationFactory.h"
13
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070014#include <llvm/ADT/Triple.h>
15#include <llvm/Support/ELF.h>
16
Shih-wei Liao22add6f2012-12-15 17:21:00 -080017#include <mcld/Module.h>
18#include <mcld/LinkerConfig.h>
19#include <mcld/IRBuilder.h>
20#include <mcld/MC/Attribute.h>
21#include <mcld/Fragment/FillFragment.h>
22#include <mcld/Fragment/FragmentLinker.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070023#include <mcld/Support/MemoryRegion.h>
Shih-wei Liao22add6f2012-12-15 17:21:00 -080024#include <mcld/Support/MemoryArea.h>
Zonr Changaffc1502012-07-16 14:28:23 +080025#include <mcld/Support/MsgHandling.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070026#include <mcld/Support/TargetRegistry.h>
27#include <mcld/Target/OutputRelocSection.h>
Shih-wei Liao22add6f2012-12-15 17:21:00 -080028#include <mcld/Object/ObjectBuilder.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070029
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070030enum {
31 // The original o32 abi.
32 E_MIPS_ABI_O32 = 0x00001000,
33 // O32 extended to work on 64 bit architectures.
34 E_MIPS_ABI_O64 = 0x00002000,
35 // EABI in 32 bit mode.
36 E_MIPS_ABI_EABI32 = 0x00003000,
37 // EABI in 64 bit mode.
38 E_MIPS_ABI_EABI64 = 0x00004000
39};
40
Shih-wei Liao22add6f2012-12-15 17:21:00 -080041using namespace mcld;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070042
Shih-wei Liao22add6f2012-12-15 17:21:00 -080043//===----------------------------------------------------------------------===//
44// MipsGNULDBackend
45//===----------------------------------------------------------------------===//
46MipsGNULDBackend::MipsGNULDBackend(const LinkerConfig& pConfig)
47 : GNULDBackend(pConfig),
48 m_pRelocFactory(NULL),
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070049 m_pGOT(NULL),
50 m_pRelDyn(NULL),
51 m_pDynamic(NULL),
52 m_pGOTSymbol(NULL),
53 m_pGpDispSymbol(NULL)
54{
55}
56
57MipsGNULDBackend::~MipsGNULDBackend()
58{
Shih-wei Liao22add6f2012-12-15 17:21:00 -080059 delete m_pRelocFactory;
60 delete m_pGOT;
61 delete m_pRelDyn;
62 delete m_pDynamic;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070063}
64
Shih-wei Liao22add6f2012-12-15 17:21:00 -080065void MipsGNULDBackend::initTargetSections(Module& pModule, ObjectBuilder& pBuilder)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070066{
Shih-wei Liao22add6f2012-12-15 17:21:00 -080067 if (LinkerConfig::Object != config().codeGenType()) {
68 ELFFileFormat* file_format = getOutputFormat();
69
70 // initialize .got
71 LDSection& got = file_format->getGOT();
72 m_pGOT = new MipsGOT(got);
73
74 // initialize .rel.dyn
75 LDSection& reldyn = file_format->getRelDyn();
76 m_pRelDyn = new OutputRelocSection(pModule,
77 reldyn,
78 getRelEntrySize());
79 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070080}
81
Shih-wei Liao22add6f2012-12-15 17:21:00 -080082void MipsGNULDBackend::initTargetSymbols(FragmentLinker& pLinker)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070083{
84 // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
85 // same name in input
Shih-wei Liao22add6f2012-12-15 17:21:00 -080086 m_pGOTSymbol = pLinker.defineSymbol<FragmentLinker::AsRefered, FragmentLinker::Resolve>(
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070087 "_GLOBAL_OFFSET_TABLE_",
88 false,
89 ResolveInfo::Object,
90 ResolveInfo::Define,
91 ResolveInfo::Local,
92 0x0, // size
93 0x0, // value
Shih-wei Liao22add6f2012-12-15 17:21:00 -080094 FragmentRef::Null(), // FragRef
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070095 ResolveInfo::Hidden);
96
Shih-wei Liao22add6f2012-12-15 17:21:00 -080097 m_pGpDispSymbol = pLinker.defineSymbol<FragmentLinker::AsRefered, FragmentLinker::Resolve>(
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070098 "_gp_disp",
99 false,
100 ResolveInfo::Section,
101 ResolveInfo::Define,
102 ResolveInfo::Absolute,
103 0x0, // size
104 0x0, // value
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800105 FragmentRef::Null(), // FragRef
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700106 ResolveInfo::Default);
107
108 if (NULL != m_pGpDispSymbol) {
109 m_pGpDispSymbol->resolveInfo()->setReserved(ReserveGpDisp);
110 }
111}
112
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800113bool MipsGNULDBackend::initRelocFactory(const FragmentLinker& pLinker)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700114{
115 if (NULL == m_pRelocFactory) {
116 m_pRelocFactory = new MipsRelocationFactory(1024, *this);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800117 m_pRelocFactory->setFragmentLinker(pLinker);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700118 }
119 return true;
120}
121
122RelocationFactory* MipsGNULDBackend::getRelocFactory()
123{
124 assert(NULL != m_pRelocFactory);
125 return m_pRelocFactory;
126}
127
128void MipsGNULDBackend::scanRelocation(Relocation& pReloc,
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800129 FragmentLinker& pLinker,
130 Module& pModule,
Zonr Changaffc1502012-07-16 14:28:23 +0800131 const LDSection& pSection)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700132{
133 // rsym - The relocation target symbol
134 ResolveInfo* rsym = pReloc.symInfo();
135 assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation");
136
Zonr Changaffc1502012-07-16 14:28:23 +0800137 // Skip relocation against _gp_disp
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800138 if (NULL != m_pGpDispSymbol) {
139 if (pReloc.symInfo() == m_pGpDispSymbol->resolveInfo())
140 return;
141 }
142
143 pReloc.updateAddend();
144
145 if (0 == (pSection.flag() & llvm::ELF::SHF_ALLOC))
Zonr Changaffc1502012-07-16 14:28:23 +0800146 return;
147
148 // We test isLocal or if pInputSym is not a dynamic symbol
149 // We assume -Bsymbolic to bind all symbols internaly via !rsym->isDyn()
150 // Don't put undef symbols into local entries.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800151 if ((rsym->isLocal() || !isDynamicSymbol(*rsym) ||
Zonr Changaffc1502012-07-16 14:28:23 +0800152 !rsym->isDyn()) && !rsym->isUndef())
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800153 scanLocalReloc(pReloc, pLinker);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700154 else
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800155 scanGlobalReloc(pReloc, pLinker);
156
157 // check if we shoule issue undefined reference for the relocation target
158 // symbol
159 if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak())
160 fatal(diag::undefined_reference) << rsym->name();
161
162 if ((rsym->reserved() & ReserveRel) != 0x0) {
163 // set hasTextRelSection if needed
164 checkAndSetHasTextRel(pSection);
165 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700166}
167
168uint32_t MipsGNULDBackend::machine() const
169{
170 return llvm::ELF::EM_MIPS;
171}
172
173uint8_t MipsGNULDBackend::OSABI() const
174{
175 return llvm::ELF::ELFOSABI_NONE;
176}
177
178uint8_t MipsGNULDBackend::ABIVersion() const
179{
180 return 0;
181}
182
183uint64_t MipsGNULDBackend::flags() const
184{
185 // TODO: (simon) The correct flag's set depend on command line
186 // arguments and flags from input .o files.
187 return llvm::ELF::EF_MIPS_ARCH_32R2 |
188 llvm::ELF::EF_MIPS_NOREORDER |
189 llvm::ELF::EF_MIPS_PIC |
190 llvm::ELF::EF_MIPS_CPIC |
191 E_MIPS_ABI_O32;
192}
193
194bool MipsGNULDBackend::isLittleEndian() const
195{
196 // Now we support little endian (mipsel) target only.
197 return true;
198}
199
200unsigned int MipsGNULDBackend::bitclass() const
201{
202 return 32;
203}
204
Zonr Changaffc1502012-07-16 14:28:23 +0800205uint64_t MipsGNULDBackend::defaultTextSegmentAddr() const
206{
207 return 0x80000;
208}
209
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800210uint64_t MipsGNULDBackend::abiPageSize() const
Shih-wei Liaocedee4b2012-08-02 23:13:03 -0700211{
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800212 if (config().options().maxPageSize() > 0)
213 return config().options().maxPageSize();
Shih-wei Liaocedee4b2012-08-02 23:13:03 -0700214 else
215 return static_cast<uint64_t>(0x10000);
216}
217
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800218void MipsGNULDBackend::doPreLayout(FragmentLinker& pLinker)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700219{
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800220 // set .got size
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700221 // when building shared object, the .got section is must.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800222 if (LinkerConfig::Object != config().codeGenType()) {
223 if (LinkerConfig::DynObj == config().codeGenType() ||
224 m_pGOT->hasGOT1() ||
225 NULL != m_pGOTSymbol) {
226 m_pGOT->finalizeSectionSize();
227 defineGOTSymbol(pLinker);
228 }
229
230 // set .rel.dyn size
231 if (!m_pRelDyn->empty())
232 m_pRelDyn->finalizeSectionSize();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700233 }
234}
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800235void MipsGNULDBackend::doPostLayout(Module& pModule,
236 FragmentLinker& pLinker)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700237{
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700238}
239
240/// dynamic - the dynamic section of the target machine.
241/// Use co-variant return type to return its own dynamic section.
242MipsELFDynamic& MipsGNULDBackend::dynamic()
243{
244 if (NULL == m_pDynamic)
245 m_pDynamic = new MipsELFDynamic(*this);
246
247 return *m_pDynamic;
248}
249
250/// dynamic - the dynamic section of the target machine.
251/// Use co-variant return type to return its own dynamic section.
252const MipsELFDynamic& MipsGNULDBackend::dynamic() const
253{
254 assert( NULL != m_pDynamic);
255 return *m_pDynamic;
256}
257
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800258uint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700259 MemoryRegion& pRegion) const
260{
261 assert(pRegion.size() && "Size of MemoryRegion is zero!");
262
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800263 const ELFFileFormat* file_format = getOutputFormat();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700264
265 if (&pSection == &(file_format->getGOT())) {
266 assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
267 uint64_t result = m_pGOT->emit(pRegion);
268 return result;
269 }
270
Zonr Changaffc1502012-07-16 14:28:23 +0800271 fatal(diag::unrecognized_output_sectoin)
272 << pSection.name()
273 << "mclinker@googlegroups.com";
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700274 return 0;
275}
Zonr Changaffc1502012-07-16 14:28:23 +0800276/// isGlobalGOTSymbol - return true if the symbol is the global GOT entry.
277bool MipsGNULDBackend::isGlobalGOTSymbol(const LDSymbol& pSymbol) const
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700278{
Zonr Changaffc1502012-07-16 14:28:23 +0800279 return std::find(m_GlobalGOTSyms.begin(),
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700280 m_GlobalGOTSyms.end(), &pSymbol) != m_GlobalGOTSyms.end();
281}
282
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800283/// sizeNamePools - compute the size of regular name pools
284/// In ELF executable files, regular name pools are .symtab, .strtab,
285/// .dynsym, .dynstr, .hash and .shstrtab.
286void
287MipsGNULDBackend::sizeNamePools(const Module& pModule, bool pIsStaticLink)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700288{
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800289 // number of entries in symbol tables starts from 1 to hold the special entry
290 // at index 0 (STN_UNDEF). See ELF Spec Book I, p1-21.
291 size_t symtab = 1;
292 size_t dynsym = pIsStaticLink ? 0 : 1;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700293
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800294 // size of string tables starts from 1 to hold the null character in their
295 // first byte
296 size_t strtab = 1;
297 size_t dynstr = pIsStaticLink ? 0 : 1;
298 size_t shstrtab = 1;
299 size_t hash = 0;
300
301 /// compute the size of .symtab, .dynsym and .strtab
302 /// @{
303 Module::const_sym_iterator symbol;
304 const Module::SymbolTable& symbols = pModule.getSymbolTable();
305 size_t str_size = 0;
306 // compute the size of symbols in Local and File category
307 Module::const_sym_iterator symEnd = symbols.localEnd();
308 for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) {
309 str_size = (*symbol)->nameSize() + 1;
310 if (!pIsStaticLink && isDynamicSymbol(**symbol)) {
311 ++dynsym;
312 if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
313 dynstr += str_size;
314 }
315 ++symtab;
316 if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
317 strtab += str_size;
318 }
319 // compute the size of symbols in TLS category
320 symEnd = symbols.tlsEnd();
321 for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) {
322 str_size = (*symbol)->nameSize() + 1;
323 if (!pIsStaticLink) {
324 ++dynsym;
325 if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
326 dynstr += str_size;
327 }
328 ++symtab;
329 if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
330 strtab += str_size;
331 }
332 // compute the size of the reset of symbols
333 symEnd = pModule.sym_end();
334 for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) {
335 str_size = (*symbol)->nameSize() + 1;
336 if (!pIsStaticLink && isDynamicSymbol(**symbol)) {
337 ++dynsym;
338 if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
339 dynstr += str_size;
340 }
341 ++symtab;
342 if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
343 strtab += str_size;
344 }
345
346 ELFFileFormat* file_format = getOutputFormat();
347
348 switch(config().codeGenType()) {
349 // compute size of .dynstr and .hash
350 case LinkerConfig::DynObj: {
351 // soname
352 if (!pIsStaticLink)
353 dynstr += pModule.name().size() + 1;
354 }
355 /** fall through **/
356 case LinkerConfig::Exec: {
357 // add DT_NEED strings into .dynstr and .dynamic
358 // Rules:
359 // 1. ignore --no-add-needed
360 // 2. force count in --no-as-needed
361 // 3. judge --as-needed
362 if (!pIsStaticLink) {
363 Module::const_lib_iterator lib, libEnd = pModule.lib_end();
364 for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
365 // --add-needed
366 if ((*lib)->attribute()->isAddNeeded()) {
367 // --no-as-needed
368 if (!(*lib)->attribute()->isAsNeeded()) {
369 dynstr += (*lib)->name().size() + 1;
370 dynamic().reserveNeedEntry();
371 }
372 // --as-needed
373 else if ((*lib)->isNeeded()) {
374 dynstr += (*lib)->name().size() + 1;
375 dynamic().reserveNeedEntry();
376 }
377 }
378 }
379
380 // compute .hash
381 // Both Elf32_Word and Elf64_Word are 4 bytes
382 hash = (2 + getHashBucketCount(dynsym, false) + dynsym) *
383 sizeof(llvm::ELF::Elf32_Word);
384 }
385
386 // set size
387 if (32 == bitclass())
388 file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf32_Sym));
389 else
390 file_format->getDynSymTab().setSize(dynsym*sizeof(llvm::ELF::Elf64_Sym));
391 file_format->getDynStrTab().setSize(dynstr);
392 file_format->getHashTab().setSize(hash);
393
394 }
395 /* fall through */
396 case LinkerConfig::Object: {
397 if (32 == bitclass())
398 file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf32_Sym));
399 else
400 file_format->getSymTab().setSize(symtab*sizeof(llvm::ELF::Elf64_Sym));
401 file_format->getStrTab().setSize(strtab);
402 break;
403 }
404 default: {
405 fatal(diag::fatal_illegal_codegen_type) << pModule.name();
406 break;
407 }
408 } // end of switch
409 /// @}
410
411 /// reserve fixed entries in the .dynamic section.
412 /// @{
413 if (LinkerConfig::DynObj == config().codeGenType() ||
414 LinkerConfig::Exec == config().codeGenType()) {
415 // Because some entries in .dynamic section need information of .dynsym,
416 // .dynstr, .symtab, .strtab and .hash, we can not reserve non-DT_NEEDED
417 // entries until we get the size of the sections mentioned above
418 dynamic().reserveEntries(config(), *file_format);
419 file_format->getDynamic().setSize(dynamic().numOfBytes());
420 }
421 /// @}
422
423 /// compute the size of .shstrtab section.
424 /// @{
425 Module::const_iterator sect, sectEnd = pModule.end();
426 for (sect = pModule.begin(); sect != sectEnd; ++sect) {
427 // StackNote sections will always be in output!
428 if (0 != (*sect)->size() || LDFileFormat::StackNote == (*sect)->kind()) {
429 shstrtab += ((*sect)->name().size() + 1);
430 }
431 }
432 shstrtab += (strlen(".shstrtab") + 1);
433 file_format->getShStrTab().setSize(shstrtab);
434 /// @}
435}
436
437/// emitSymbol32 - emit an ELF32 symbol
438void MipsGNULDBackend::emitSymbol32(llvm::ELF::Elf32_Sym& pSym,
439 LDSymbol& pSymbol,
440 char* pStrtab,
441 size_t pStrtabsize,
442 size_t pSymtabIdx)
443{
444 // FIXME: check the endian between host and target
445 // write out symbol
446 if (ResolveInfo::Section != pSymbol.type() ||
447 &pSymbol == m_pGpDispSymbol) {
448 pSym.st_name = pStrtabsize;
449 strcpy((pStrtab + pStrtabsize), pSymbol.name());
450 }
451 else {
452 pSym.st_name = 0;
453 }
454 pSym.st_value = pSymbol.value();
455 pSym.st_size = getSymbolSize(pSymbol);
456 pSym.st_info = getSymbolInfo(pSymbol);
457 pSym.st_other = pSymbol.visibility();
458 pSym.st_shndx = getSymbolShndx(pSymbol);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700459}
460
461/// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
462///
463/// the size of these tables should be computed before layout
464/// layout should computes the start offset of these tables
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800465void MipsGNULDBackend::emitDynNamePools(const Module& pModule,
466 MemoryArea& pOutput)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700467{
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800468 ELFFileFormat* file_format = getOutputFormat();
469 if (!file_format->hasDynSymTab() ||
470 !file_format->hasDynStrTab() ||
471 !file_format->hasHashTab() ||
472 !file_format->hasDynamic())
473 return;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700474
475 LDSection& symtab_sect = file_format->getDynSymTab();
476 LDSection& strtab_sect = file_format->getDynStrTab();
477 LDSection& hash_sect = file_format->getHashTab();
478 LDSection& dyn_sect = file_format->getDynamic();
479
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800480 MemoryRegion* symtab_region = pOutput.request(symtab_sect.offset(),
481 symtab_sect.size());
482 MemoryRegion* strtab_region = pOutput.request(strtab_sect.offset(),
483 strtab_sect.size());
484 MemoryRegion* hash_region = pOutput.request(hash_sect.offset(),
485 hash_sect.size());
486 MemoryRegion* dyn_region = pOutput.request(dyn_sect.offset(),
487 dyn_sect.size());
488
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700489 // set up symtab_region
490 llvm::ELF::Elf32_Sym* symtab32 = NULL;
491 symtab32 = (llvm::ELF::Elf32_Sym*)symtab_region->start();
492
493 symtab32[0].st_name = 0;
494 symtab32[0].st_value = 0;
495 symtab32[0].st_size = 0;
496 symtab32[0].st_info = 0;
497 symtab32[0].st_other = 0;
498 symtab32[0].st_shndx = 0;
499
500 // set up strtab_region
501 char* strtab = (char*)strtab_region->start();
502 strtab[0] = '\0';
503
504 bool sym_exist = false;
505 HashTableType::entry_type* entry = 0;
506
507 // add index 0 symbol into SymIndexMap
508 entry = m_pSymIndexMap->insert(NULL, sym_exist);
509 entry->setValue(0);
510
511 size_t symtabIdx = 1;
512 size_t strtabsize = 1;
513
514 // emit of .dynsym, and .dynstr except GOT entries
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800515 Module::const_sym_iterator symbol;
516 const Module::SymbolTable& symbols = pModule.getSymbolTable();
517 // emit symbol in File and Local category if it's dynamic symbol
518 Module::const_sym_iterator symEnd = symbols.localEnd();
519 for (symbol = symbols.localBegin(); symbol != symEnd; ++symbol) {
520 if (!isDynamicSymbol(**symbol))
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700521 continue;
522
Zonr Changaffc1502012-07-16 14:28:23 +0800523 if (isGlobalGOTSymbol(**symbol))
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700524 continue;
525
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800526 emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
527 symtabIdx);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700528
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800529 // maintain output's symbol and index map
530 entry = m_pSymIndexMap->insert(*symbol, sym_exist);
531 entry->setValue(symtabIdx);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700532 // sum up counters
533 ++symtabIdx;
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800534 if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
535 strtabsize += (*symbol)->nameSize() + 1;
536 }
537
538 // emit symbols in TLS category, all symbols in TLS category shold be emitited
539 // directly, except GOT entries
540 symEnd = symbols.tlsEnd();
541 for (symbol = symbols.tlsBegin(); symbol != symEnd; ++symbol) {
542 if (isGlobalGOTSymbol(**symbol))
543 continue;
544
545 emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
546 symtabIdx);
547
548 // maintain output's symbol and index map
549 entry = m_pSymIndexMap->insert(*symbol, sym_exist);
550 entry->setValue(symtabIdx);
551 // sum up counters
552 ++symtabIdx;
553 if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
554 strtabsize += (*symbol)->nameSize() + 1;
555 }
556
557 // emit the reset of the symbols if the symbol is dynamic symbol
558 symEnd = pModule.sym_end();
559 for (symbol = symbols.tlsEnd(); symbol != symEnd; ++symbol) {
560 if (!isDynamicSymbol(**symbol))
561 continue;
562
563 if (isGlobalGOTSymbol(**symbol))
564 continue;
565
566 emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
567 symtabIdx);
568
569 // maintain output's symbol and index map
570 entry = m_pSymIndexMap->insert(*symbol, sym_exist);
571 entry->setValue(symtabIdx);
572 // sum up counters
573 ++symtabIdx;
574 if (ResolveInfo::Section != (*symbol)->type() || *symbol == m_pGpDispSymbol)
575 strtabsize += (*symbol)->nameSize() + 1;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700576 }
577
578 // emit global GOT
579 for (std::vector<LDSymbol*>::const_iterator symbol = m_GlobalGOTSyms.begin(),
580 symbol_end = m_GlobalGOTSyms.end();
581 symbol != symbol_end; ++symbol) {
582
Zonr Changaffc1502012-07-16 14:28:23 +0800583 // Make sure this golbal GOT entry is a dynamic symbol.
584 // If not, something is wrong earlier when putting this symbol into
585 // global GOT.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800586 if (!isDynamicSymbol(**symbol))
Zonr Changaffc1502012-07-16 14:28:23 +0800587 fatal(diag::mips_got_symbol) << (*symbol)->name();
588
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800589 emitSymbol32(symtab32[symtabIdx], **symbol, strtab, strtabsize,
590 symtabIdx);
591 // maintain output's symbol and index map
592 entry = m_pSymIndexMap->insert(*symbol, sym_exist);
593 entry->setValue(symtabIdx);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700594
595 // sum up counters
596 ++symtabIdx;
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800597 if (ResolveInfo::Section != (*symbol)->type())
598 strtabsize += (*symbol)->nameSize() + 1;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700599 }
600
601 // emit DT_NEED
602 // add DT_NEED strings into .dynstr
603 // Rules:
604 // 1. ignore --no-add-needed
605 // 2. force count in --no-as-needed
606 // 3. judge --as-needed
607 ELFDynamic::iterator dt_need = dynamic().needBegin();
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800608 Module::const_lib_iterator lib, libEnd = pModule.lib_end();
609 for (lib = pModule.lib_begin(); lib != libEnd; ++lib) {
610 // --add-needed
611 if ((*lib)->attribute()->isAddNeeded()) {
612 // --no-as-needed
613 if (!(*lib)->attribute()->isAsNeeded()) {
614 strcpy((strtab + strtabsize), (*lib)->name().c_str());
615 (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
616 strtabsize += (*lib)->name().size() + 1;
617 ++dt_need;
618 }
619 // --as-needed
620 else if ((*lib)->isNeeded()) {
621 strcpy((strtab + strtabsize), (*lib)->name().c_str());
622 (*dt_need)->setValue(llvm::ELF::DT_NEEDED, strtabsize);
623 strtabsize += (*lib)->name().size() + 1;
624 ++dt_need;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700625 }
626 }
627 } // for
628
629 // emit soname
630 // initialize value of ELF .dynamic section
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800631 if (LinkerConfig::DynObj == config().codeGenType())
Zonr Changaffc1502012-07-16 14:28:23 +0800632 dynamic().applySoname(strtabsize);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800633 dynamic().applyEntries(config(), *file_format);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700634 dynamic().emit(dyn_sect, *dyn_region);
635
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800636 strcpy((strtab + strtabsize), pModule.name().c_str());
637 strtabsize += pModule.name().size() + 1;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700638
639 // emit hash table
640 // FIXME: this verion only emit SVR4 hash section.
641 // Please add GNU new hash section
642
643 // both 32 and 64 bits hash table use 32-bit entry
644 // set up hash_region
645 uint32_t* word_array = (uint32_t*)hash_region->start();
646 uint32_t& nbucket = word_array[0];
647 uint32_t& nchain = word_array[1];
648
649 nbucket = getHashBucketCount(symtabIdx, false);
650 nchain = symtabIdx;
651
652 uint32_t* bucket = (word_array + 2);
653 uint32_t* chain = (bucket + nbucket);
654
655 // initialize bucket
656 bzero((void*)bucket, nbucket);
657
658 StringHash<ELF> hash_func;
659
660 for (size_t sym_idx=0; sym_idx < symtabIdx; ++sym_idx) {
661 llvm::StringRef name(strtab + symtab32[sym_idx].st_name);
662 size_t bucket_pos = hash_func(name) % nbucket;
663 chain[sym_idx] = bucket[bucket_pos];
664 bucket[bucket_pos] = sym_idx;
665 }
666
667}
668
669MipsGOT& MipsGNULDBackend::getGOT()
670{
671 assert(NULL != m_pGOT);
672 return *m_pGOT;
673}
674
675const MipsGOT& MipsGNULDBackend::getGOT() const
676{
677 assert(NULL != m_pGOT);
678 return *m_pGOT;
679}
680
681OutputRelocSection& MipsGNULDBackend::getRelDyn()
682{
683 assert(NULL != m_pRelDyn);
684 return *m_pRelDyn;
685}
686
687const OutputRelocSection& MipsGNULDBackend::getRelDyn() const
688{
689 assert(NULL != m_pRelDyn);
690 return *m_pRelDyn;
691}
692
693unsigned int
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800694MipsGNULDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700695{
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800696 const ELFFileFormat* file_format = getOutputFormat();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700697
698 if (&pSectHdr == &file_format->getGOT())
699 return SHO_DATA;
700
701 return SHO_UNDEFINED;
702}
703
704/// finalizeSymbol - finalize the symbol value
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800705bool MipsGNULDBackend::finalizeTargetSymbols(FragmentLinker& pLinker)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700706{
Shih-wei Liaocedee4b2012-08-02 23:13:03 -0700707 if (NULL != m_pGpDispSymbol)
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800708 m_pGpDispSymbol->setValue(m_pGOT->addr() + 0x7FF0);
Zonr Changaffc1502012-07-16 14:28:23 +0800709 return true;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700710}
711
712/// allocateCommonSymbols - allocate common symbols in the corresponding
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800713/// sections. This is called at pre-layout stage.
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700714/// @refer Google gold linker: common.cc: 214
715/// FIXME: Mips needs to allocate small common symbol
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800716bool MipsGNULDBackend::allocateCommonSymbols(Module& pModule)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700717{
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800718 SymbolCategory& symbol_list = pModule.getSymbolTable();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700719
720 if (symbol_list.emptyCommons() && symbol_list.emptyLocals())
721 return true;
722
Zonr Changaffc1502012-07-16 14:28:23 +0800723 SymbolCategory::iterator com_sym, com_end;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700724
725 // FIXME: If the order of common symbols is defined, then sort common symbols
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700726 // std::sort(com_sym, com_end, some kind of order);
727
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800728 // get corresponding BSS LDSection
729 ELFFileFormat* file_format = getOutputFormat();
730 LDSection& bss_sect = file_format->getBSS();
731 LDSection& tbss_sect = file_format->getTBSS();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700732
Shih-wei Liaocedee4b2012-08-02 23:13:03 -0700733 // get or create corresponding BSS SectionData
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800734 SectionData* bss_sect_data = NULL;
735 if (bss_sect.hasSectionData())
736 bss_sect_data = bss_sect.getSectionData();
737 else
738 bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
739
740 SectionData* tbss_sect_data = NULL;
741 if (tbss_sect.hasSectionData())
742 tbss_sect_data = tbss_sect.getSectionData();
743 else
744 tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700745
Zonr Changaffc1502012-07-16 14:28:23 +0800746 // remember original BSS size
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800747 uint64_t bss_offset = bss_sect.size();
748 uint64_t tbss_offset = tbss_sect.size();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700749
750 // allocate all local common symbols
751 com_end = symbol_list.localEnd();
Zonr Changaffc1502012-07-16 14:28:23 +0800752
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700753 for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
754 if (ResolveInfo::Common == (*com_sym)->desc()) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700755 // We have to reset the description of the symbol here. When doing
756 // incremental linking, the output relocatable object may have common
757 // symbols. Therefore, we can not treat common symbols as normal symbols
758 // when emitting the regular name pools. We must change the symbols'
759 // description here.
760 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
Shih-wei Liaocedee4b2012-08-02 23:13:03 -0700761 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800762 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
Zonr Changaffc1502012-07-16 14:28:23 +0800763
764 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
765 // allocate TLS common symbol in tbss section
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800766 tbss_offset += ObjectBuilder::AppendFragment(*frag,
767 *tbss_sect_data,
768 (*com_sym)->value());
Zonr Changaffc1502012-07-16 14:28:23 +0800769 }
770 // FIXME: how to identify small and large common symbols?
771 else {
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800772 bss_offset += ObjectBuilder::AppendFragment(*frag,
773 *bss_sect_data,
774 (*com_sym)->value());
Zonr Changaffc1502012-07-16 14:28:23 +0800775 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700776 }
777 }
778
779 // allocate all global common symbols
780 com_end = symbol_list.commonEnd();
781 for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700782 // We have to reset the description of the symbol here. When doing
783 // incremental linking, the output relocatable object may have common
784 // symbols. Therefore, we can not treat common symbols as normal symbols
785 // when emitting the regular name pools. We must change the symbols'
786 // description here.
787 (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
Shih-wei Liaocedee4b2012-08-02 23:13:03 -0700788 Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800789 (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
Zonr Changaffc1502012-07-16 14:28:23 +0800790
791 if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
792 // allocate TLS common symbol in tbss section
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800793 tbss_offset += ObjectBuilder::AppendFragment(*frag,
794 *tbss_sect_data,
795 (*com_sym)->value());
Zonr Changaffc1502012-07-16 14:28:23 +0800796 }
797 // FIXME: how to identify small and large common symbols?
798 else {
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800799 bss_offset += ObjectBuilder::AppendFragment(*frag,
800 *bss_sect_data,
801 (*com_sym)->value());
Zonr Changaffc1502012-07-16 14:28:23 +0800802 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700803 }
804
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800805 bss_sect.setSize(bss_offset);
806 tbss_sect.setSize(tbss_offset);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700807 symbol_list.changeCommonsToGlobal();
808 return true;
809}
810
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700811void MipsGNULDBackend::scanLocalReloc(Relocation& pReloc,
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800812 FragmentLinker& pLinker)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700813{
814 ResolveInfo* rsym = pReloc.symInfo();
815
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700816 switch (pReloc.type()){
817 case llvm::ELF::R_MIPS_NONE:
818 case llvm::ELF::R_MIPS_16:
819 break;
820 case llvm::ELF::R_MIPS_32:
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800821 if (LinkerConfig::DynObj == config().codeGenType()) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700822 // TODO: (simon) The gold linker does not create an entry in .rel.dyn
823 // section if the symbol section flags contains SHF_EXECINSTR.
824 // 1. Find the reason of this condition.
825 // 2. Check this condition here.
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700826 m_pRelDyn->reserveEntry(*m_pRelocFactory);
827 rsym->setReserved(rsym->reserved() | ReserveRel);
Zonr Changaffc1502012-07-16 14:28:23 +0800828
829 // Remeber this rsym is a local GOT entry (as if it needs an entry).
830 // Actually we don't allocate an GOT entry.
Zonr Changaffc1502012-07-16 14:28:23 +0800831 m_pGOT->setLocal(rsym);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700832 }
833 break;
834 case llvm::ELF::R_MIPS_REL32:
835 case llvm::ELF::R_MIPS_26:
836 case llvm::ELF::R_MIPS_HI16:
837 case llvm::ELF::R_MIPS_LO16:
838 case llvm::ELF::R_MIPS_PC16:
839 case llvm::ELF::R_MIPS_SHIFT5:
840 case llvm::ELF::R_MIPS_SHIFT6:
841 case llvm::ELF::R_MIPS_64:
842 case llvm::ELF::R_MIPS_GOT_PAGE:
843 case llvm::ELF::R_MIPS_GOT_OFST:
844 case llvm::ELF::R_MIPS_SUB:
845 case llvm::ELF::R_MIPS_INSERT_A:
846 case llvm::ELF::R_MIPS_INSERT_B:
847 case llvm::ELF::R_MIPS_DELETE:
848 case llvm::ELF::R_MIPS_HIGHER:
849 case llvm::ELF::R_MIPS_HIGHEST:
850 case llvm::ELF::R_MIPS_SCN_DISP:
851 case llvm::ELF::R_MIPS_REL16:
852 case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
853 case llvm::ELF::R_MIPS_PJUMP:
854 case llvm::ELF::R_MIPS_RELGOT:
855 case llvm::ELF::R_MIPS_JALR:
856 case llvm::ELF::R_MIPS_GLOB_DAT:
857 case llvm::ELF::R_MIPS_COPY:
858 case llvm::ELF::R_MIPS_JUMP_SLOT:
859 break;
860 case llvm::ELF::R_MIPS_GOT16:
861 case llvm::ELF::R_MIPS_CALL16:
Zonr Changaffc1502012-07-16 14:28:23 +0800862 // For got16 section based relocations, we need to reserve got entries.
863 if (rsym->type() == ResolveInfo::Section) {
864 m_pGOT->reserveLocalEntry();
865 // Remeber this rsym is a local GOT entry
866 m_pGOT->setLocal(rsym);
867 return;
868 }
869
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700870 if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
871 m_pGOT->reserveLocalEntry();
872 rsym->setReserved(rsym->reserved() | ReserveGot);
Zonr Changaffc1502012-07-16 14:28:23 +0800873 // Remeber this rsym is a local GOT entry
874 m_pGOT->setLocal(rsym);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700875 }
876 break;
877 case llvm::ELF::R_MIPS_GPREL32:
878 case llvm::ELF::R_MIPS_GPREL16:
879 case llvm::ELF::R_MIPS_LITERAL:
880 break;
881 case llvm::ELF::R_MIPS_GOT_DISP:
882 case llvm::ELF::R_MIPS_GOT_HI16:
883 case llvm::ELF::R_MIPS_CALL_HI16:
884 case llvm::ELF::R_MIPS_GOT_LO16:
885 case llvm::ELF::R_MIPS_CALL_LO16:
886 break;
887 case llvm::ELF::R_MIPS_TLS_DTPMOD32:
888 case llvm::ELF::R_MIPS_TLS_DTPREL32:
889 case llvm::ELF::R_MIPS_TLS_DTPMOD64:
890 case llvm::ELF::R_MIPS_TLS_DTPREL64:
891 case llvm::ELF::R_MIPS_TLS_GD:
892 case llvm::ELF::R_MIPS_TLS_LDM:
893 case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
894 case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
895 case llvm::ELF::R_MIPS_TLS_GOTTPREL:
896 case llvm::ELF::R_MIPS_TLS_TPREL32:
897 case llvm::ELF::R_MIPS_TLS_TPREL64:
898 case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
899 case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
900 break;
901 default:
Zonr Changaffc1502012-07-16 14:28:23 +0800902 fatal(diag::unknown_relocation) << (int)pReloc.type()
903 << pReloc.symInfo()->name();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700904 }
905}
906
907void MipsGNULDBackend::scanGlobalReloc(Relocation& pReloc,
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800908 FragmentLinker& pLinker)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700909{
910 ResolveInfo* rsym = pReloc.symInfo();
911
912 switch (pReloc.type()){
913 case llvm::ELF::R_MIPS_NONE:
914 case llvm::ELF::R_MIPS_INSERT_A:
915 case llvm::ELF::R_MIPS_INSERT_B:
916 case llvm::ELF::R_MIPS_DELETE:
917 case llvm::ELF::R_MIPS_TLS_DTPMOD64:
918 case llvm::ELF::R_MIPS_TLS_DTPREL64:
919 case llvm::ELF::R_MIPS_REL16:
920 case llvm::ELF::R_MIPS_ADD_IMMEDIATE:
921 case llvm::ELF::R_MIPS_PJUMP:
922 case llvm::ELF::R_MIPS_RELGOT:
923 case llvm::ELF::R_MIPS_TLS_TPREL64:
924 break;
925 case llvm::ELF::R_MIPS_32:
926 case llvm::ELF::R_MIPS_64:
927 case llvm::ELF::R_MIPS_HI16:
928 case llvm::ELF::R_MIPS_LO16:
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800929 if (symbolNeedsDynRel(pLinker, *rsym, false, true)) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700930 m_pRelDyn->reserveEntry(*m_pRelocFactory);
931 rsym->setReserved(rsym->reserved() | ReserveRel);
Zonr Changaffc1502012-07-16 14:28:23 +0800932
933 // Remeber this rsym is a global GOT entry (as if it needs an entry).
934 // Actually we don't allocate an GOT entry.
Zonr Changaffc1502012-07-16 14:28:23 +0800935 m_pGOT->setGlobal(rsym);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700936 }
937 break;
938 case llvm::ELF::R_MIPS_GOT16:
939 case llvm::ELF::R_MIPS_CALL16:
940 case llvm::ELF::R_MIPS_GOT_DISP:
941 case llvm::ELF::R_MIPS_GOT_HI16:
942 case llvm::ELF::R_MIPS_CALL_HI16:
943 case llvm::ELF::R_MIPS_GOT_LO16:
944 case llvm::ELF::R_MIPS_CALL_LO16:
945 case llvm::ELF::R_MIPS_GOT_PAGE:
946 case llvm::ELF::R_MIPS_GOT_OFST:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700947 if (!(rsym->reserved() & MipsGNULDBackend::ReserveGot)) {
948 m_pGOT->reserveGlobalEntry();
949 rsym->setReserved(rsym->reserved() | ReserveGot);
950 m_GlobalGOTSyms.push_back(rsym->outSymbol());
Zonr Changaffc1502012-07-16 14:28:23 +0800951 // Remeber this rsym is a global GOT entry
952 m_pGOT->setGlobal(rsym);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700953 }
954 break;
955 case llvm::ELF::R_MIPS_LITERAL:
956 case llvm::ELF::R_MIPS_GPREL32:
Zonr Changaffc1502012-07-16 14:28:23 +0800957 fatal(diag::invalid_global_relocation) << (int)pReloc.type()
958 << pReloc.symInfo()->name();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700959 break;
960 case llvm::ELF::R_MIPS_GPREL16:
961 break;
962 case llvm::ELF::R_MIPS_26:
963 case llvm::ELF::R_MIPS_PC16:
964 break;
965 case llvm::ELF::R_MIPS_16:
966 case llvm::ELF::R_MIPS_SHIFT5:
967 case llvm::ELF::R_MIPS_SHIFT6:
968 case llvm::ELF::R_MIPS_SUB:
969 case llvm::ELF::R_MIPS_HIGHER:
970 case llvm::ELF::R_MIPS_HIGHEST:
971 case llvm::ELF::R_MIPS_SCN_DISP:
972 break;
973 case llvm::ELF::R_MIPS_TLS_DTPREL32:
974 case llvm::ELF::R_MIPS_TLS_GD:
975 case llvm::ELF::R_MIPS_TLS_LDM:
976 case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
977 case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:
978 case llvm::ELF::R_MIPS_TLS_GOTTPREL:
979 case llvm::ELF::R_MIPS_TLS_TPREL32:
980 case llvm::ELF::R_MIPS_TLS_TPREL_HI16:
981 case llvm::ELF::R_MIPS_TLS_TPREL_LO16:
982 break;
983 case llvm::ELF::R_MIPS_REL32:
984 break;
985 case llvm::ELF::R_MIPS_JALR:
986 break;
987 case llvm::ELF::R_MIPS_COPY:
988 case llvm::ELF::R_MIPS_GLOB_DAT:
989 case llvm::ELF::R_MIPS_JUMP_SLOT:
Zonr Changaffc1502012-07-16 14:28:23 +0800990 fatal(diag::dynamic_relocation) << (int)pReloc.type();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700991 break;
992 default:
Zonr Changaffc1502012-07-16 14:28:23 +0800993 fatal(diag::unknown_relocation) << (int)pReloc.type()
994 << pReloc.symInfo()->name();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700995 }
996}
997
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800998void MipsGNULDBackend::defineGOTSymbol(FragmentLinker& pLinker)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700999{
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001000 // define symbol _GLOBAL_OFFSET_TABLE_
Zonr Changaffc1502012-07-16 14:28:23 +08001001 if ( m_pGOTSymbol != NULL ) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001002 pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Unresolve>(
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001003 "_GLOBAL_OFFSET_TABLE_",
1004 false,
1005 ResolveInfo::Object,
1006 ResolveInfo::Define,
1007 ResolveInfo::Local,
1008 0x0, // size
1009 0x0, // value
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001010 FragmentRef::Create(*(m_pGOT->begin()), 0x0),
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001011 ResolveInfo::Hidden);
1012 }
1013 else {
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001014 m_pGOTSymbol = pLinker.defineSymbol<FragmentLinker::Force, FragmentLinker::Resolve>(
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001015 "_GLOBAL_OFFSET_TABLE_",
1016 false,
1017 ResolveInfo::Object,
1018 ResolveInfo::Define,
1019 ResolveInfo::Local,
1020 0x0, // size
1021 0x0, // value
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001022 FragmentRef::Create(*(m_pGOT->begin()), 0x0),
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001023 ResolveInfo::Hidden);
1024 }
1025}
1026
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001027/// doCreateProgramHdrs - backend can implement this function to create the
1028/// target-dependent segments
1029void MipsGNULDBackend::doCreateProgramHdrs(Module& pModule,
1030 const FragmentLinker& pLinker)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001031{
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001032 // TODO
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001033}
1034
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001035//===----------------------------------------------------------------------===//
1036/// createMipsLDBackend - the help funtion to create corresponding MipsLDBackend
1037///
1038static TargetLDBackend* createMipsLDBackend(const llvm::Target& pTarget,
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001039 const LinkerConfig& pConfig)
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001040{
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001041 if (pConfig.triple().isOSDarwin()) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001042 assert(0 && "MachO linker is not supported yet");
1043 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001044 if (pConfig.triple().isOSWindows()) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001045 assert(0 && "COFF linker is not supported yet");
1046 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001047 return new MipsGNULDBackend(pConfig);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001048}
1049
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001050//===----------------------------------------------------------------------===//
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001051// Force static initialization.
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001052//===----------------------------------------------------------------------===//
1053extern "C" void MCLDInitializeMipsLDBackend() {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001054 // Register the linker backend
1055 mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheMipselTarget,
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001056 createMipsLDBackend);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001057}
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001058