Home | History | Annotate | Download | only in Object
      1 //===- ObjectBuilder.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/Object/ObjectBuilder.h>
     10 
     11 #include <mcld/Module.h>
     12 #include <mcld/LinkerConfig.h>
     13 #include <mcld/IRBuilder.h>
     14 #include <mcld/Object/SectionMap.h>
     15 #include <mcld/LD/LDSection.h>
     16 #include <mcld/LD/SectionData.h>
     17 #include <mcld/LD/RelocData.h>
     18 #include <mcld/LD/EhFrame.h>
     19 #include <mcld/Fragment/Relocation.h>
     20 #include <mcld/Fragment/AlignFragment.h>
     21 #include <mcld/Fragment/NullFragment.h>
     22 #include <mcld/Fragment/FillFragment.h>
     23 
     24 #include <llvm/Support/Casting.h>
     25 
     26 using namespace mcld;
     27 
     28 //===----------------------------------------------------------------------===//
     29 // ObjectBuilder
     30 //===----------------------------------------------------------------------===//
     31 ObjectBuilder::ObjectBuilder(const LinkerConfig& pConfig, Module& pTheModule)
     32   : m_Config(pConfig), m_Module(pTheModule) {
     33 }
     34 
     35 /// CreateSection - create an output section.
     36 LDSection* ObjectBuilder::CreateSection(const std::string& pName,
     37                                         LDFileFormat::Kind pKind,
     38                                         uint32_t pType,
     39                                         uint32_t pFlag,
     40                                         uint32_t pAlign)
     41 {
     42   // try to get one from output LDSection
     43   const SectionMap::NamePair& pair = m_Module.getScript().sectionMap().find(pName);
     44   std::string output_name = (pair.isNull())?pName:pair.to;
     45   LDSection* output_sect = LDSection::Create(output_name, pKind, pType, pFlag);
     46   output_sect->setAlign(pAlign);
     47   m_Module.getSectionTable().push_back(output_sect);
     48   return output_sect;
     49 }
     50 
     51 /// MergeSection - merge the pInput section to the pOutput section
     52 LDSection* ObjectBuilder::MergeSection(LDSection& pInputSection)
     53 {
     54   const SectionMap::NamePair& pair =
     55               m_Module.getScript().sectionMap().find(pInputSection.name());
     56   std::string output_name = (pair.isNull())?pInputSection.name():pair.to;
     57   LDSection* target = m_Module.getSection(output_name);
     58 
     59   if (NULL == target) {
     60     target = LDSection::Create(output_name,
     61                                pInputSection.kind(),
     62                                pInputSection.type(),
     63                                pInputSection.flag());
     64     target->setAlign(pInputSection.align());
     65     m_Module.getSectionTable().push_back(target);
     66   }
     67 
     68   switch (target->kind()) {
     69     // Some *OUTPUT sections should not be merged.
     70     case LDFileFormat::Relocation:
     71     case LDFileFormat::NamePool:
     72       /** do nothing **/
     73       return target;
     74     case LDFileFormat::EhFrame: {
     75       EhFrame* eh_frame = NULL;
     76       if (target->hasEhFrame())
     77         eh_frame = target->getEhFrame();
     78       else
     79         eh_frame = IRBuilder::CreateEhFrame(*target);
     80 
     81       eh_frame->merge(*pInputSection.getEhFrame());
     82 			UpdateSectionAlign(*target, pInputSection);
     83       return target;
     84     }
     85     default: {
     86       SectionData* data = NULL;
     87       if (target->hasSectionData())
     88         data = target->getSectionData();
     89       else
     90         data = IRBuilder::CreateSectionData(*target);
     91 
     92       if (MoveSectionData(*pInputSection.getSectionData(), *data)) {
     93         UpdateSectionAlign(*target, pInputSection);
     94         return target;
     95       }
     96       return NULL;
     97     }
     98   }
     99   return target;
    100 }
    101 
    102 /// MoveSectionData - move the fragments of pTO section data to pTo
    103 bool ObjectBuilder::MoveSectionData(SectionData& pFrom, SectionData& pTo)
    104 {
    105   assert(&pFrom != &pTo && "Cannot move section data to itself!");
    106 
    107   uint32_t offset = pTo.getSection().size();
    108   AlignFragment* align = NULL;
    109   if (pFrom.getSection().align() > 1) {
    110     // if the align constraint is larger than 1, append an alignment
    111     align = new AlignFragment(pFrom.getSection().align(), // alignment
    112                               0x0, // the filled value
    113                               1u,  // the size of filled value
    114                               pFrom.getSection().align() - 1 // max bytes to emit
    115                               );
    116     align->setOffset(offset);
    117     align->setParent(&pTo);
    118     pTo.getFragmentList().push_back(align);
    119     offset += align->size();
    120   }
    121 
    122   // move fragments from pFrom to pTO
    123   SectionData::FragmentListType& from_list = pFrom.getFragmentList();
    124   SectionData::FragmentListType& to_list = pTo.getFragmentList();
    125   SectionData::FragmentListType::iterator frag, fragEnd = from_list.end();
    126   for (frag = from_list.begin(); frag != fragEnd; ++frag) {
    127     frag->setParent(&pTo);
    128     frag->setOffset(offset);
    129     offset += frag->size();
    130   }
    131   to_list.splice(to_list.end(), from_list);
    132 
    133   // set up pTo's header
    134   pTo.getSection().setSize(offset);
    135 
    136   return true;
    137 }
    138 
    139 /// UpdateSectionFlags - update alignment for input section
    140 void ObjectBuilder::UpdateSectionAlign(LDSection& pTo, const LDSection& pFrom)
    141 {
    142   if (pFrom.align() > pTo.align())
    143     pTo.setAlign(pFrom.align());
    144 }
    145 
    146 /// AppendFragment - To append pFrag to the given SectionData pSD.
    147 uint64_t ObjectBuilder::AppendFragment(Fragment& pFrag,
    148                                        SectionData& pSD,
    149                                        uint32_t pAlignConstraint)
    150 {
    151   // get initial offset.
    152   uint32_t offset = 0;
    153   if (!pSD.empty())
    154     offset = pSD.back().getOffset() + pSD.back().size();
    155 
    156   AlignFragment* align = NULL;
    157   if (pAlignConstraint > 1) {
    158     // if the align constraint is larger than 1, append an alignment
    159     align = new AlignFragment(pAlignConstraint, // alignment
    160                               0x0, // the filled value
    161                               1u,  // the size of filled value
    162                               pAlignConstraint - 1 // max bytes to emit
    163                               );
    164     align->setOffset(offset);
    165     align->setParent(&pSD);
    166     pSD.getFragmentList().push_back(align);
    167     offset += align->size();
    168   }
    169 
    170   // append the fragment
    171   pFrag.setParent(&pSD);
    172   pFrag.setOffset(offset);
    173   pSD.getFragmentList().push_back(&pFrag);
    174 
    175   // append the null fragment
    176   offset += pFrag.size();
    177   NullFragment* null = new NullFragment(&pSD);
    178   null->setOffset(offset);
    179 
    180   if (NULL != align)
    181     return align->size() + pFrag.size();
    182   else
    183     return pFrag.size();
    184 }
    185 
    186