Home | History | Annotate | Download | only in LD
      1 //===- RelocationFactory.cpp ----------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #include <mcld/LD/RelocationFactory.h>
     10 #include <mcld/Target/GOT.h>
     11 #include <mcld/Target/TargetLDBackend.h>
     12 #include <llvm/Support/Host.h>
     13 #include <cstring>
     14 #include <cassert>
     15 
     16 using namespace mcld;
     17 
     18 //==========================
     19 // RelocationFactory
     20 RelocationFactory::RelocationFactory(size_t pNum)
     21   : GCFactory<Relocation, 0>(pNum),
     22     m_pLayout(NULL) {
     23 }
     24 
     25 RelocationFactory::~RelocationFactory()
     26 {
     27 }
     28 
     29 Relocation* RelocationFactory::produce(RelocationFactory::Type pType,
     30                                        MCFragmentRef& pFragRef,
     31                                        Address pAddend)
     32 {
     33   // target_data is the place where the relocation applys to.
     34   // Use TargetDataFactory to generate temporary data, and copy the
     35   // content of the fragment into this data.
     36   DWord target_data = 0;
     37 
     38   // byte swapping if the host and target have different endian
     39   if(llvm::sys::isLittleEndianHost() != getTarget().isLittleEndian()) {
     40      uint32_t tmp_data;
     41 
     42      switch(getTarget().bitclass()) {
     43       case 32u:
     44         pFragRef.memcpy(&tmp_data, 4);
     45         tmp_data = bswap32(tmp_data);
     46         target_data = tmp_data;
     47         break;
     48 
     49       case 64u:
     50         pFragRef.memcpy(&target_data, 8);
     51         target_data = bswap64(target_data);
     52         break;
     53 
     54       default:
     55         break;
     56     }
     57   }
     58   else {
     59     pFragRef.memcpy(&target_data, (getTarget().bitclass()/8));
     60   }
     61 
     62   Relocation *result = allocate();
     63   new (result) Relocation(pType, &pFragRef, pAddend, target_data);
     64   return result;
     65 }
     66 
     67 Relocation* RelocationFactory::produceEmptyEntry()
     68 {
     69   // FIXME: To prevent relocations from double free by both iplist and
     70   // GCFactory, currently we new relocations directly and let iplist
     71   // delete them.
     72 
     73   return new Relocation(0, 0, 0, 0);
     74 }
     75 
     76 void RelocationFactory::destroy(Relocation* pRelocation)
     77 {
     78    /** GCFactory will recycle the relocation **/
     79 }
     80 
     81 void RelocationFactory::setLayout(const Layout& pLayout)
     82 {
     83   m_pLayout = &pLayout;
     84 }
     85 
     86 const Layout& RelocationFactory::getLayout() const
     87 {
     88   assert(0 != m_pLayout);
     89   return *m_pLayout;
     90 }
     91 
     92