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/LinkerConfig.h>
     11 #include <mcld/Target/TargetLDBackend.h>
     12 #include <mcld/Support/MsgHandling.h>
     13 
     14 #include <llvm/Support/Host.h>
     15 
     16 #include <cstring>
     17 #include <cassert>
     18 
     19 using namespace mcld;
     20 
     21 //===----------------------------------------------------------------------===//
     22 // RelocationFactory
     23 //===----------------------------------------------------------------------===//
     24 RelocationFactory::RelocationFactory()
     25   : GCFactory<Relocation, MCLD_RELOCATIONS_PER_INPUT>(), m_pConfig(NULL) {
     26 }
     27 
     28 void RelocationFactory::setConfig(const LinkerConfig& pConfig)
     29 {
     30   m_pConfig = &pConfig;
     31 }
     32 
     33 Relocation* RelocationFactory::produce(RelocationFactory::Type pType,
     34                                        FragmentRef& pFragRef,
     35                                        Address pAddend)
     36 {
     37   if (NULL == m_pConfig) {
     38     fatal(diag::reloc_factory_has_not_config);
     39     return NULL;
     40   }
     41 
     42   // target_data is the place where the relocation applys to.
     43   // Use TargetDataFactory to generate temporary data, and copy the
     44   // content of the fragment into this data.
     45   DWord target_data = 0;
     46 
     47   // byte swapping if the host and target have different endian
     48   if (llvm::sys::IsLittleEndianHost != m_pConfig->targets().isLittleEndian()) {
     49     uint32_t tmp_data;
     50 
     51     switch (m_pConfig->targets().bitclass()) {
     52       case 32: {
     53         pFragRef.memcpy(&tmp_data, 4);
     54         tmp_data = mcld::bswap32(tmp_data);
     55         target_data = tmp_data;
     56         break;
     57       }
     58       case 64: {
     59         pFragRef.memcpy(&target_data, 8);
     60         target_data = mcld::bswap64(target_data);
     61         break;
     62       }
     63       default: {
     64         fatal(diag::unsupported_bitclass) << m_pConfig->targets().triple().str()
     65                                           << m_pConfig->targets().bitclass();
     66         return NULL;
     67       }
     68     } // end of switch
     69   }
     70   else {
     71     pFragRef.memcpy(&target_data, (m_pConfig->targets().bitclass()/8));
     72   }
     73 
     74   Relocation* result = allocate();
     75   new (result) Relocation(pType, &pFragRef, pAddend, target_data);
     76   return result;
     77 }
     78 
     79 Relocation* RelocationFactory::produceEmptyEntry()
     80 {
     81   Relocation* result = allocate();
     82   new (result) Relocation(0, 0, 0, 0);
     83   return result;
     84 }
     85 
     86 void RelocationFactory::destroy(Relocation* pRelocation)
     87 {
     88    /** GCFactory will recycle the relocation **/
     89 }
     90 
     91