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