1 //===- MCLinker.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 //
10 // This file implements the MCLinker class
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include <mcld/MC/MCLinker.h>
15 #include <mcld/MC/MCLDInput.h>
16 #include <mcld/MC/MCLDInfo.h>
17 #include <mcld/LD/Resolver.h>
18 #include <mcld/LD/LDContext.h>
19 #include <mcld/LD/LDSymbol.h>
20 #include <mcld/LD/LDSectionFactory.h>
21 #include <mcld/LD/SectionMap.h>
22 #include <mcld/LD/RelocationFactory.h>
23 #include <mcld/Support/MemoryRegion.h>
24 #include <mcld/Target/TargetLDBackend.h>
25 #include <llvm/Support/Host.h>
26 #include <llvm/Support/raw_ostream.h>
27
28 using namespace mcld;
29
30 /// Constructor
MCLinker(TargetLDBackend & pBackend,MCLDInfo & pInfo,LDContext & pContext,SectionMap & pSectionMap,const Resolver & pResolver)31 MCLinker::MCLinker(TargetLDBackend& pBackend,
32 MCLDInfo& pInfo,
33 LDContext& pContext,
34 SectionMap& pSectionMap,
35 const Resolver& pResolver)
36 : m_Backend(pBackend),
37 m_Info(pInfo),
38 m_Output(pContext),
39 m_SectionMap(pSectionMap),
40 m_LDSymbolFactory(128),
41 m_LDSectHdrFactory(10), // the average number of sections. (assuming 10.)
42 m_LDSectDataFactory(10),
43 m_SectionMerger(pSectionMap, pContext),
44 m_StrSymPool(pResolver, 128)
45 {
46 m_Info.setNamePool(m_StrSymPool);
47 }
48
49 /// Destructor
~MCLinker()50 MCLinker::~MCLinker()
51 {
52 }
53
54 /// addSymbolFromObject - add a symbol from object file and resolve it
55 /// immediately
addSymbolFromObject(const llvm::StringRef & pName,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,MCFragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)56 LDSymbol* MCLinker::addSymbolFromObject(const llvm::StringRef& pName,
57 ResolveInfo::Type pType,
58 ResolveInfo::Desc pDesc,
59 ResolveInfo::Binding pBinding,
60 ResolveInfo::SizeType pSize,
61 LDSymbol::ValueType pValue,
62 MCFragmentRef* pFragmentRef,
63 ResolveInfo::Visibility pVisibility)
64 {
65
66 // resolved_result is a triple <resolved_info, existent, override>
67 Resolver::Result resolved_result;
68 ResolveInfo old_info; // used for arrange output symbols
69
70 if (pBinding == ResolveInfo::Local) {
71 // if the symbol is a local symbol, create a LDSymbol for input, but do not
72 // resolve them.
73 resolved_result.info = m_StrSymPool.createSymbol(pName,
74 false,
75 pType,
76 pDesc,
77 pBinding,
78 pSize,
79 pVisibility);
80
81 // No matter if there is a symbol with the same name, insert the symbol
82 // into output symbol table. So, we let the existent false.
83 resolved_result.existent = false;
84 resolved_result.overriden = true;
85 }
86 else {
87 // if the symbol is not local, insert and resolve it immediately
88 m_StrSymPool.insertSymbol(pName, false, pType, pDesc, pBinding, pSize,
89 pVisibility, &old_info, resolved_result);
90 }
91
92 // the return ResolveInfo should not NULL
93 assert(NULL != resolved_result.info);
94
95 // create a LDSymbol for the input file.
96 LDSymbol* input_sym = m_LDSymbolFactory.allocate();
97 new (input_sym) LDSymbol();
98
99 // set the relation between input LDSymbol and its ResolveInfo
100 input_sym->setResolveInfo(*resolved_result.info);
101
102 // set up input LDSymbol
103 input_sym->setFragmentRef(pFragmentRef);
104 input_sym->setValue(pValue);
105
106 LDSymbol* output_sym = resolved_result.info->outSymbol();
107 bool has_output_sym = (NULL != output_sym);
108 if (!resolved_result.existent || !has_output_sym) {
109 // it is a new symbol, the output_sym should be NULL.
110 assert(NULL == output_sym);
111
112 // if it is a new symbol, create a LDSymbol for the output
113 output_sym = m_LDSymbolFactory.allocate();
114 new (output_sym) LDSymbol();
115
116 // set up the relation between output LDSymbol and its ResolveInfo
117 output_sym->setResolveInfo(*resolved_result.info);
118 resolved_result.info->setSymPtr(output_sym);
119 }
120
121 if (resolved_result.overriden || !has_output_sym) {
122 // symbol can be overriden only if it exists.
123 assert(output_sym != NULL);
124
125 // should override output LDSymbol
126 output_sym->setFragmentRef(pFragmentRef);
127 output_sym->setValue(pValue);
128 }
129
130 // After symbol resolution, visibility is changed to the most restrict one.
131 // we need to arrange its position in the output symbol .
132 if (pType != ResolveInfo::Section) {
133 if (!has_output_sym) {
134 // We merge sections when reading them. So we do not need to output symbols
135 // with section type
136
137 // No matter the symbol is already in the output or not, add it if it
138 // should be forcefully set local.
139 if (shouldForceLocal(*resolved_result.info))
140 m_OutputSymbols.forceLocal(*output_sym);
141 else {
142 // the symbol should not be forcefully local.
143 m_OutputSymbols.add(*output_sym);
144 }
145 }
146 else if (resolved_result.overriden) {
147 if (!shouldForceLocal(old_info) ||
148 !shouldForceLocal(*resolved_result.info)) {
149 // If the old info and the new info are both forcefully local, then
150 // we should keep the output_sym in forcefully local category. Else,
151 // we should re-sort the output_sym
152 m_OutputSymbols.arrange(*output_sym, old_info);
153 }
154 }
155 }
156
157 return input_sym;
158 }
159
160 /// addSymbolFromDynObj - add a symbol from object file and resolve it
161 /// immediately
addSymbolFromDynObj(const llvm::StringRef & pName,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,MCFragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)162 LDSymbol* MCLinker::addSymbolFromDynObj(const llvm::StringRef& pName,
163 ResolveInfo::Type pType,
164 ResolveInfo::Desc pDesc,
165 ResolveInfo::Binding pBinding,
166 ResolveInfo::SizeType pSize,
167 LDSymbol::ValueType pValue,
168 MCFragmentRef* pFragmentRef,
169 ResolveInfo::Visibility pVisibility)
170 {
171 // We merge sections when reading them. So we do not need symbols with
172 // section type
173 if (pType == ResolveInfo::Section)
174 return NULL;
175
176 // ignore symbols with local binding or that have internal or hidden
177 // visibility
178 if (pBinding == ResolveInfo::Local ||
179 pVisibility == ResolveInfo::Internal ||
180 pVisibility == ResolveInfo::Hidden)
181 return NULL;
182
183 // A protected symbol in a shared library must be treated as a
184 // normal symbol when viewed from outside the shared library.
185 if (pVisibility == ResolveInfo::Protected)
186 pVisibility = ResolveInfo::Default;
187
188 // insert symbol and resolve it immediately
189 // resolved_result is a triple <resolved_info, existent, override>
190 Resolver::Result resolved_result;
191 m_StrSymPool.insertSymbol(pName, true, pType, pDesc, pBinding, pSize, pVisibility,
192 NULL, resolved_result);
193
194 // the return ResolveInfo should not NULL
195 assert(NULL != resolved_result.info);
196
197 // create a LDSymbol for the input file.
198 LDSymbol* input_sym = m_LDSymbolFactory.allocate();
199 new (input_sym) LDSymbol();
200
201 // set up the relation between input LDSymbol and its ResolveInfo
202 input_sym->setResolveInfo(*resolved_result.info);
203
204 // set up input LDSymbol
205 input_sym->setFragmentRef(pFragmentRef);
206 input_sym->setValue(pValue);
207
208 LDSymbol* output_sym = NULL;
209 if (!resolved_result.existent) {
210 // we get a new symbol, leave it as NULL
211 resolved_result.info->setSymPtr(NULL);
212 }
213 else {
214 // we saw the symbol before, but the output_sym still may be NULL.
215 output_sym = resolved_result.info->outSymbol();
216 }
217
218 if (output_sym != NULL) {
219 // After symbol resolution, visibility is changed to the most restrict one.
220 // If we are not doing incremental linking, then any symbol with hidden
221 // or internal visibility is forcefully set as a local symbol.
222 if (shouldForceLocal(*resolved_result.info)) {
223 m_OutputSymbols.forceLocal(*output_sym);
224 }
225 }
226
227 return input_sym;
228 }
229
230 /// defineSymbolForcefully - define an output symbol and override it immediately
defineSymbolForcefully(const llvm::StringRef & pName,bool pIsDyn,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,MCFragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)231 LDSymbol* MCLinker::defineSymbolForcefully(const llvm::StringRef& pName,
232 bool pIsDyn,
233 ResolveInfo::Type pType,
234 ResolveInfo::Desc pDesc,
235 ResolveInfo::Binding pBinding,
236 ResolveInfo::SizeType pSize,
237 LDSymbol::ValueType pValue,
238 MCFragmentRef* pFragmentRef,
239 ResolveInfo::Visibility pVisibility)
240 {
241 ResolveInfo* info = m_StrSymPool.findInfo(pName);
242 LDSymbol* output_sym = NULL;
243 if (NULL == info) {
244 // the symbol is not in the pool, create a new one.
245 // create a ResolveInfo
246 Resolver::Result result;
247 m_StrSymPool.insertSymbol(pName, pIsDyn, pType, pDesc, pBinding, pSize, pVisibility,
248 NULL, result);
249 assert(!result.existent);
250
251 // create a output LDSymbol
252 output_sym = m_LDSymbolFactory.allocate();
253 new (output_sym) LDSymbol();
254
255 output_sym->setResolveInfo(*result.info);
256 result.info->setSymPtr(output_sym);
257
258 if (shouldForceLocal(*result.info))
259 m_OutputSymbols.forceLocal(*output_sym);
260 else
261 m_OutputSymbols.add(*output_sym);
262 }
263 else {
264 // the symbol is already in the pool, override it
265 ResolveInfo old_info;
266 old_info.override(*info);
267
268 info->setSource(pIsDyn);
269 info->setType(pType);
270 info->setDesc(pDesc);
271 info->setBinding(pBinding);
272 info->setVisibility(pVisibility);
273 info->setIsSymbol(true);
274 info->setSize(pSize);
275
276 output_sym = info->outSymbol();
277 if (NULL != output_sym)
278 m_OutputSymbols.arrange(*output_sym, old_info);
279 else {
280 // create a output LDSymbol
281 output_sym = m_LDSymbolFactory.allocate();
282 new (output_sym) LDSymbol();
283
284 output_sym->setResolveInfo(*info);
285 info->setSymPtr(output_sym);
286
287 m_OutputSymbols.add(*output_sym);
288 }
289 }
290
291 if (NULL != output_sym) {
292 output_sym->setFragmentRef(pFragmentRef);
293 output_sym->setValue(pValue);
294 }
295
296 return output_sym;
297 }
298
299 /// defineSymbolAsRefered - define an output symbol and override it immediately
defineSymbolAsRefered(const llvm::StringRef & pName,bool pIsDyn,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,MCFragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)300 LDSymbol* MCLinker::defineSymbolAsRefered(const llvm::StringRef& pName,
301 bool pIsDyn,
302 ResolveInfo::Type pType,
303 ResolveInfo::Desc pDesc,
304 ResolveInfo::Binding pBinding,
305 ResolveInfo::SizeType pSize,
306 LDSymbol::ValueType pValue,
307 MCFragmentRef* pFragmentRef,
308 ResolveInfo::Visibility pVisibility)
309 {
310 ResolveInfo* info = m_StrSymPool.findInfo(pName);
311
312 if (NULL == info || !info->isUndef()) {
313 // only undefined symbol can make a reference.
314 return NULL;
315 }
316
317 // the symbol is already in the pool, override it
318 ResolveInfo old_info;
319 old_info.override(*info);
320
321 info->setSource(pIsDyn);
322 info->setType(pType);
323 info->setDesc(pDesc);
324 info->setBinding(pBinding);
325 info->setVisibility(pVisibility);
326 info->setIsSymbol(true);
327 info->setSize(pSize);
328
329 LDSymbol* output_sym = info->outSymbol();
330 if (NULL != output_sym) {
331 output_sym->setFragmentRef(pFragmentRef);
332 output_sym->setValue(pValue);
333 m_OutputSymbols.arrange(*output_sym, old_info);
334 }
335 else {
336 // create a output LDSymbol
337 output_sym = m_LDSymbolFactory.allocate();
338 new (output_sym) LDSymbol();
339
340 output_sym->setResolveInfo(*info);
341 info->setSymPtr(output_sym);
342
343 m_OutputSymbols.add(*output_sym);
344 }
345
346 return output_sym;
347 }
348
349 /// defineAndResolveSymbolForcefully - define an output symbol and resolve it
350 /// immediately
defineAndResolveSymbolForcefully(const llvm::StringRef & pName,bool pIsDyn,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,MCFragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)351 LDSymbol* MCLinker::defineAndResolveSymbolForcefully(const llvm::StringRef& pName,
352 bool pIsDyn,
353 ResolveInfo::Type pType,
354 ResolveInfo::Desc pDesc,
355 ResolveInfo::Binding pBinding,
356 ResolveInfo::SizeType pSize,
357 LDSymbol::ValueType pValue,
358 MCFragmentRef* pFragmentRef,
359 ResolveInfo::Visibility pVisibility)
360 {
361 // Result is <info, existent, override>
362 Resolver::Result result;
363 ResolveInfo old_info;
364 m_StrSymPool.insertSymbol(pName, pIsDyn, pType, pDesc, pBinding, pSize, pVisibility,
365 &old_info, result);
366
367 LDSymbol* output_sym = result.info->outSymbol();
368 bool has_output_sym = (NULL != output_sym);
369
370 if (!result.existent || !has_output_sym) {
371 output_sym = m_LDSymbolFactory.allocate();
372 new (output_sym) LDSymbol();
373 output_sym->setResolveInfo(*result.info);
374 result.info->setSymPtr(output_sym);
375 }
376
377 if (result.overriden || !has_output_sym) {
378 output_sym->setFragmentRef(pFragmentRef);
379 output_sym->setValue(pValue);
380 }
381
382 // After symbol resolution, the visibility is changed to the most restrict.
383 // arrange the output position
384 if (shouldForceLocal(*result.info))
385 m_OutputSymbols.forceLocal(*output_sym);
386 else if (has_output_sym)
387 m_OutputSymbols.arrange(*output_sym, old_info);
388 else
389 m_OutputSymbols.add(*output_sym);
390
391 return output_sym;
392 }
393
394 /// defineAndResolveSymbolAsRefered - define an output symbol and resolve it
395 /// immediately.
defineAndResolveSymbolAsRefered(const llvm::StringRef & pName,bool pIsDyn,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,MCFragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)396 LDSymbol* MCLinker::defineAndResolveSymbolAsRefered(const llvm::StringRef& pName,
397 bool pIsDyn,
398 ResolveInfo::Type pType,
399 ResolveInfo::Desc pDesc,
400 ResolveInfo::Binding pBinding,
401 ResolveInfo::SizeType pSize,
402 LDSymbol::ValueType pValue,
403 MCFragmentRef* pFragmentRef,
404 ResolveInfo::Visibility pVisibility)
405 {
406 ResolveInfo* info = m_StrSymPool.findInfo(pName);
407
408 if (NULL == info || !info->isUndef()) {
409 // only undefined symbol can make a reference
410 return NULL;
411 }
412
413 return defineAndResolveSymbolForcefully(pName,
414 pIsDyn,
415 pType,
416 pDesc,
417 pBinding,
418 pSize,
419 pValue,
420 pFragmentRef,
421 pVisibility);
422 }
423
424 /// createSectHdr - create the input section header
createSectHdr(const std::string & pName,LDFileFormat::Kind pKind,uint32_t pType,uint32_t pFlag)425 LDSection& MCLinker::createSectHdr(const std::string& pName,
426 LDFileFormat::Kind pKind,
427 uint32_t pType,
428 uint32_t pFlag)
429 {
430 // for user such as reader, standard/target fromat
431 LDSection* result =
432 m_LDSectHdrFactory.produce(pName, pKind, pType, pFlag);
433
434 // check if we need to create a output section for output LDContext
435 std::string sect_name = m_SectionMap.getOutputSectName(pName);
436 LDSection* output_sect = m_Output.getSection(sect_name);
437
438 if (NULL == output_sect) {
439 // create a output section and push it into output LDContext
440 output_sect =
441 m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag);
442 m_Output.getSectionTable().push_back(output_sect);
443 m_SectionMerger.addMapping(pName, output_sect);
444 }
445 return *result;
446 }
447
448 /// getOrCreateOutputSectHdr - for reader and standard/target format to get
449 /// or create the output's section header
getOrCreateOutputSectHdr(const std::string & pName,LDFileFormat::Kind pKind,uint32_t pType,uint32_t pFlag,uint32_t pAlign)450 LDSection& MCLinker::getOrCreateOutputSectHdr(const std::string& pName,
451 LDFileFormat::Kind pKind,
452 uint32_t pType,
453 uint32_t pFlag,
454 uint32_t pAlign)
455 {
456 // check if we need to create a output section for output LDContext
457 std::string sect_name = m_SectionMap.getOutputSectName(pName);
458 LDSection* output_sect = m_Output.getSection(sect_name);
459
460 if (NULL == output_sect) {
461 // create a output section and push it into output LDContext
462 output_sect =
463 m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag);
464 output_sect->setAlign(pAlign);
465 m_Output.getSectionTable().push_back(output_sect);
466 m_SectionMerger.addMapping(pName, output_sect);
467 }
468 return *output_sect;
469 }
470
471 /// getOrCreateSectData - get or create MCSectionData
472 /// pSection is input LDSection
getOrCreateSectData(LDSection & pSection)473 llvm::MCSectionData& MCLinker::getOrCreateSectData(LDSection& pSection)
474 {
475 // if there is already a section data pointed by section, return it.
476 llvm::MCSectionData* sect_data = pSection.getSectionData();
477 if (NULL != sect_data) {
478 m_Layout.addInputRange(*sect_data, pSection);
479 return *sect_data;
480 }
481
482 // try to get one from output LDSection
483 LDSection* output_sect =
484 m_SectionMerger.getOutputSectHdr(pSection.name());
485
486 assert(NULL != output_sect);
487
488 sect_data = output_sect->getSectionData();
489
490 if (NULL != sect_data) {
491 pSection.setSectionData(sect_data);
492 m_Layout.addInputRange(*sect_data, pSection);
493 return *sect_data;
494 }
495
496 // if the output LDSection also has no MCSectionData, then create one.
497 sect_data = m_LDSectDataFactory.allocate();
498 new (sect_data) llvm::MCSectionData(*output_sect);
499 pSection.setSectionData(sect_data);
500 output_sect->setSectionData(sect_data);
501 m_Layout.addInputRange(*sect_data, pSection);
502 return *sect_data;
503 }
504
505 /// addRelocation - add a relocation entry in MCLinker (only for object file)
506 ///
507 /// All symbols should be read and resolved before calling this function.
addRelocation(Relocation::Type pType,const LDSymbol & pSym,ResolveInfo & pResolveInfo,MCFragmentRef & pFragmentRef,Relocation::Address pAddend)508 Relocation* MCLinker::addRelocation(Relocation::Type pType,
509 const LDSymbol& pSym,
510 ResolveInfo& pResolveInfo,
511 MCFragmentRef& pFragmentRef,
512 Relocation::Address pAddend)
513 {
514 Relocation* relocation = m_Backend.getRelocFactory()->produce(pType,
515 pFragmentRef,
516 pAddend);
517
518 relocation->setSymInfo(&pResolveInfo);
519
520 m_RelocationList.push_back(relocation);
521
522 m_Backend.scanRelocation(*relocation, pSym, *this, m_Info,
523 m_Info.output());
524
525 return relocation;
526 }
527
applyRelocations()528 bool MCLinker::applyRelocations()
529 {
530 RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end();
531
532 for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) {
533 llvm::MCFragment* frag = (llvm::MCFragment*)relocIter;
534 static_cast<Relocation*>(frag)->apply(*m_Backend.getRelocFactory(), m_Info);
535 }
536 return true;
537 }
538
syncRelocationResult()539 void MCLinker::syncRelocationResult()
540 {
541
542 m_Info.output().memArea()->clean();
543 MemoryRegion* region = m_Info.output().memArea()->request(0,
544 m_Info.output().memArea()->size());
545
546 uint8_t* data = region->getBuffer();
547
548 RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end();
549 for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) {
550
551 llvm::MCFragment* frag = (llvm::MCFragment*)relocIter;
552 Relocation* reloc = static_cast<Relocation*>(frag);
553
554 // get output file offset
555 size_t out_offset = m_Layout.getOutputLDSection(*reloc->targetRef().frag())->offset() +
556 m_Layout.getOutputOffset(reloc->targetRef());
557
558 uint8_t* target_addr = data + out_offset;
559 // byte swapping if target and host has different endian, and then write back
560 if(llvm::sys::isLittleEndianHost() != m_Backend.isLittleEndian()) {
561 uint64_t tmp_data = 0;
562
563 switch(m_Backend.bitclass()) {
564 case 32u:
565 tmp_data = bswap32(reloc->target());
566 std::memcpy(target_addr, &tmp_data, 4);
567 break;
568
569 case 64u:
570 tmp_data = bswap64(reloc->target());
571 std::memcpy(target_addr, &tmp_data, 8);
572 break;
573
574 default:
575 break;
576 }
577 }
578 else {
579 std::memcpy(target_addr, &reloc->target(), m_Backend.bitclass()/8);
580 }
581 } // end of for
582
583 m_Info.output().memArea()->sync();
584 }
585
586
layout()587 bool MCLinker::layout()
588 {
589 return m_Layout.layout(m_Info.output(), m_Backend);
590 }
591
finalizeSymbols()592 bool MCLinker::finalizeSymbols()
593 {
594 SymbolCategory::iterator symbol, symEnd = m_OutputSymbols.end();
595 for (symbol = m_OutputSymbols.begin(); symbol != symEnd; ++symbol) {
596
597 if (0x0 != (*symbol)->resolveInfo()->reserved()) {
598 // if the symbol is target reserved, target backend is responsible
599 // for finalizing the value.
600 // if target backend does not know this symbol, it will return false
601 // and we have to take over the symbol.
602 if (m_Backend.finalizeSymbol(**symbol))
603 continue;
604 }
605
606 if ((*symbol)->resolveInfo()->isAbsolute() ||
607 (*symbol)->resolveInfo()->type() == ResolveInfo::File) {
608 // absolute symbols and symbols with function type should have
609 // zero value
610 (*symbol)->setValue(0x0);
611 continue;
612 }
613
614 if ((*symbol)->hasFragRef()) {
615 // set the virtual address of the symbol. If the output file is
616 // relocatable object file, the section's virtual address becomes zero.
617 // And the symbol's value become section relative offset.
618 uint64_t value = getLayout().getOutputOffset(*(*symbol)->fragRef());
619 assert(NULL != (*symbol)->fragRef()->frag());
620 uint64_t addr = getLayout().getOutputLDSection(*(*symbol)->fragRef()->frag())->addr();
621 (*symbol)->setValue(value + addr);
622 continue;
623 }
624 }
625
626 return true;
627 }
628
shouldForceLocal(const ResolveInfo & pInfo) const629 bool MCLinker::shouldForceLocal(const ResolveInfo& pInfo) const
630 {
631 // forced local symbol matches all rules:
632 // 1. We are not doing incremental linking.
633 // 2. The symbol is with Hidden or Internal visibility.
634 // 3. The symbol should be global or weak. Otherwise, local symbol is local.
635 // 4. The symbol is defined or common
636 if (m_Info.output().type() != Output::Object &&
637 (pInfo.visibility() == ResolveInfo::Hidden ||
638 pInfo.visibility() == ResolveInfo::Internal) &&
639 (pInfo.isGlobal() || pInfo.isWeak()) &&
640 (pInfo.isDefine() || pInfo.isCommon()))
641 return true;
642 return false;
643 }
644
645