Home | History | Annotate | Download | only in LD
      1 //===- ELFReader.tcc ------------------------------------------------------===//
      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 is the template implemenation of ELFReaders
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 //===----------------------------------------------------------------------===//
     15 // ELFReader<32, true>
     16 #include <cstring>
     17 #include <vector>
     18 
     19 /// constructor
     20 ELFReader<32, true>::ELFReader(GNULDBackend& pBackend)
     21   : ELFReaderIF(pBackend) {
     22 }
     23 
     24 /// destructor
     25 ELFReader<32, true>::~ELFReader()
     26 {
     27 }
     28 
     29 /// isELF - is this a ELF file
     30 bool ELFReader<32, true>::isELF(void* pELFHeader) const
     31 {
     32   llvm::ELF::Elf32_Ehdr* hdr =
     33                           reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
     34   if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4))
     35     return true;
     36   return false;
     37 }
     38 
     39 /// isMyEndian - is this ELF file in the same endian to me?
     40 bool ELFReader<32, true>::isMyEndian(void* pELFHeader) const
     41 {
     42   llvm::ELF::Elf32_Ehdr* hdr =
     43                           reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
     44 
     45   return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB);
     46 }
     47 
     48 /// isMyMachine - is this ELF file generated for the same machine.
     49 bool ELFReader<32, true>::isMyMachine(void* pELFHeader) const
     50 {
     51   llvm::ELF::Elf32_Ehdr* hdr =
     52                           reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
     53 
     54   if (llvm::sys::isLittleEndianHost())
     55     return (hdr->e_machine == target().machine());
     56   return (bswap16(hdr->e_machine) == target().machine());
     57 }
     58 
     59 /// fileType - return the file type
     60 MCLDFile::Type ELFReader<32, true>::fileType(void* pELFHeader) const
     61 {
     62   llvm::ELF::Elf32_Ehdr* hdr =
     63                           reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
     64   uint32_t type = 0x0;
     65   if (llvm::sys::isLittleEndianHost())
     66     type = hdr->e_type;
     67   else
     68     type = bswap16(hdr->e_type);
     69 
     70   switch(type) {
     71   case llvm::ELF::ET_REL:
     72     return MCLDFile::Object;
     73   case llvm::ELF::ET_EXEC:
     74     return MCLDFile::Exec;
     75   case llvm::ELF::ET_DYN:
     76     return MCLDFile::DynObj;
     77   case llvm::ELF::ET_CORE:
     78     return MCLDFile::CoreFile;
     79   case llvm::ELF::ET_NONE:
     80   default:
     81     return MCLDFile::Unknown;
     82   }
     83 }
     84 
     85 /// readSectionHeaders - read ELF section header table and create LDSections
     86 bool ELFReader<32, true>::readSectionHeaders(Input& pInput,
     87                                              MCLinker& pLinker,
     88                                              void* pELFHeader) const
     89 {
     90   llvm::ELF::Elf32_Ehdr* ehdr =
     91                           reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader);
     92 
     93   uint32_t shoff     = 0x0;
     94   uint16_t shentsize = 0x0;
     95   uint16_t shnum     = 0x0;
     96   uint16_t shstrtab  = 0x0;
     97 
     98   if (llvm::sys::isLittleEndianHost()) {
     99     shoff     = ehdr->e_shoff;
    100     shentsize = ehdr->e_shentsize;
    101     shnum     = ehdr->e_shnum;
    102     shstrtab  = ehdr->e_shstrndx;
    103   }
    104   else {
    105     shoff     = bswap32(ehdr->e_shoff);
    106     shentsize = bswap16(ehdr->e_shentsize);
    107     shnum     = bswap16(ehdr->e_shnum);
    108     shstrtab  = bswap16(ehdr->e_shstrndx);
    109   }
    110 
    111   // If the file has no section header table, e_shoff holds zero.
    112   if (0x0 == shoff)
    113     return true;
    114 
    115   MemoryRegion* shdr_region = pInput.memArea()->request(shoff, shnum*shentsize);
    116   llvm::ELF::Elf32_Shdr* shdrTab =
    117                 reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start());
    118 
    119   uint32_t sh_name      = 0x0;
    120   uint32_t sh_type      = 0x0;
    121   uint32_t sh_flags     = 0x0;
    122   uint32_t sh_offset    = 0x0;
    123   uint32_t sh_size      = 0x0;
    124   uint32_t sh_link      = 0x0;
    125   uint32_t sh_info      = 0x0;
    126   uint32_t sh_addralign = 0x0;
    127 
    128   // get .shstrtab first
    129   llvm::ELF::Elf32_Shdr* shdr = &shdrTab[shstrtab];
    130   if (llvm::sys::isLittleEndianHost()) {
    131     sh_offset = shdr->sh_offset;
    132     sh_size   = shdr->sh_size;
    133   }
    134   else {
    135     sh_offset = bswap32(shdr->sh_offset);
    136     sh_size   = bswap32(shdr->sh_size);
    137   }
    138 
    139   MemoryRegion* sect_name_region = pInput.memArea()->request(sh_offset, sh_size);
    140   const char* sect_name = reinterpret_cast<const char*>(sect_name_region->start());
    141 
    142   LinkInfoList link_info_list;
    143 
    144   // create all LDSections
    145   for (size_t idx = 0; idx < shnum; ++idx) {
    146     if (llvm::sys::isLittleEndianHost()) {
    147       sh_name      = shdrTab[idx].sh_name;
    148       sh_type      = shdrTab[idx].sh_type;
    149       sh_flags     = shdrTab[idx].sh_flags;
    150       sh_offset    = shdrTab[idx].sh_offset;
    151       sh_size      = shdrTab[idx].sh_size;
    152       sh_link      = shdrTab[idx].sh_link;
    153       sh_info      = shdrTab[idx].sh_info;
    154       sh_addralign = shdrTab[idx].sh_addralign;
    155     }
    156     else {
    157       sh_name      = bswap32(shdrTab[idx].sh_name);
    158       sh_type      = bswap32(shdrTab[idx].sh_type);
    159       sh_flags     = bswap32(shdrTab[idx].sh_flags);
    160       sh_offset    = bswap32(shdrTab[idx].sh_offset);
    161       sh_size      = bswap32(shdrTab[idx].sh_size);
    162       sh_link      = bswap32(shdrTab[idx].sh_link);
    163       sh_info      = bswap32(shdrTab[idx].sh_info);
    164       sh_addralign = bswap32(shdrTab[idx].sh_addralign);
    165     }
    166 
    167     LDFileFormat::Kind kind = getLDSectionKind(sh_type,
    168                                                sect_name+sh_name);
    169 
    170     LDSection& section = pLinker.createSectHdr(sect_name+sh_name,
    171                                                kind,
    172                                                sh_type,
    173                                                sh_flags);
    174 
    175     section.setSize(sh_size);
    176     section.setOffset(sh_offset);
    177     section.setIndex(pInput.context()->numOfSections());
    178     section.setInfo(sh_info);
    179     section.setAlign(sh_addralign);
    180 
    181     if (sh_link != 0x0 || sh_info != 0x0) {
    182       LinkInfo link_info = { &section, sh_link, sh_info };
    183       link_info_list.push_back(link_info);
    184     }
    185 
    186     pInput.context()->getSectionTable().push_back(&section);
    187   } // end of for
    188 
    189   // set up InfoLink
    190   LinkInfoList::iterator info, infoEnd = link_info_list.end();
    191   for (info = link_info_list.begin(); info != infoEnd; ++info) {
    192     if (LDFileFormat::NamePool == info->section->kind() ||
    193         LDFileFormat::Group == info->section->kind()) {
    194       info->section->setLink(pInput.context()->getSection(info->sh_link));
    195       continue;
    196     }
    197     if (LDFileFormat::Relocation == info->section->kind()) {
    198       info->section->setLink(pInput.context()->getSection(info->sh_info));
    199       continue;
    200     }
    201   }
    202 
    203   pInput.memArea()->release(shdr_region);
    204   pInput.memArea()->release(sect_name_region);
    205 
    206   return true;
    207 }
    208 
    209 /// readRegularSection - read a regular section and create fragments.
    210 bool ELFReader<32, true>::readRegularSection(Input& pInput,
    211                                              MCLinker& pLinker,
    212                                              LDSection& pInputSectHdr) const
    213 {
    214   LDSection& out_sect = pLinker.getOrCreateOutputSectHdr(pInputSectHdr.name(),
    215                                                          pInputSectHdr.kind(),
    216                                                          pInputSectHdr.type(),
    217                                                          pInputSectHdr.flag());
    218 
    219   MemoryRegion* region = pInput.memArea()->request(pInputSectHdr.offset(),
    220                                                    pInputSectHdr.size());
    221 
    222   llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);
    223 
    224   llvm::MCFragment* frag = NULL;
    225   if (NULL == region) {
    226     // If the input section's size is zero, we got a NULL region.
    227     // use a virtual fill fragment
    228     frag = new llvm::MCFillFragment(0x0, 0, 0);
    229   }
    230   else
    231     frag = new MCRegionFragment(*region);
    232 
    233   uint64_t size = pLinker.getLayout().appendFragment(*frag,
    234                                                      sect_data,
    235                                                      pInputSectHdr.align());
    236 
    237   out_sect.setSize(out_sect.size() + size);
    238   return true;
    239 }
    240 
    241 /// readRegularSection - read a target section and create fragments.
    242 bool ELFReader<32, true>::readTargetSection(Input& pInput,
    243                                             MCLinker& pLinker,
    244                                             LDSection& pInputSectHdr)
    245 {
    246   return target().readSection(pInput, pLinker, pInputSectHdr);
    247 }
    248 
    249 /// readSymbols - read ELF symbols and create LDSymbol
    250 bool ELFReader<32, true>::readSymbols(Input& pInput,
    251                                       MCLinker& pLinker,
    252                                       const MemoryRegion& pRegion,
    253                                       const char* pStrTab) const
    254 {
    255   // get number of symbols
    256   size_t entsize = pRegion.size()/sizeof(llvm::ELF::Elf32_Sym);
    257   llvm::ELF::Elf32_Sym* symtab =
    258                       reinterpret_cast<llvm::ELF::Elf32_Sym*>(pRegion.start());
    259 
    260   uint32_t st_name  = 0x0;
    261   uint32_t st_value = 0x0;
    262   uint32_t st_size  = 0x0;
    263   uint8_t  st_info  = 0x0;
    264   uint8_t  st_other = 0x0;
    265   uint16_t st_shndx = 0x0;
    266   // skip the first NULL symbol
    267   pInput.context()->addSymbol(NULL);
    268 
    269   for (size_t idx = 1; idx < entsize; ++idx) {
    270     st_info  = symtab[idx].st_info;
    271     st_other = symtab[idx].st_other;
    272 
    273     if (llvm::sys::isLittleEndianHost()) {
    274       st_name  = symtab[idx].st_name;
    275       st_value = symtab[idx].st_value;
    276       st_size  = symtab[idx].st_size;
    277       st_shndx = symtab[idx].st_shndx;
    278     }
    279     else {
    280       st_name  = bswap32(symtab[idx].st_name);
    281       st_value = bswap32(symtab[idx].st_value);
    282       st_size  = bswap32(symtab[idx].st_size);
    283       st_shndx = bswap16(symtab[idx].st_shndx);
    284     }
    285 
    286     // If the section should not be included, set the st_shndx SHN_UNDEF
    287     // - A section in interrelated groups are not included.
    288     if (pInput.type() == Input::Object &&
    289         st_shndx < llvm::ELF::SHN_LORESERVE &&
    290         st_shndx != llvm::ELF::SHN_UNDEF) {
    291       if (NULL == pInput.context()->getSection(st_shndx))
    292         st_shndx = llvm::ELF::SHN_UNDEF;
    293     }
    294 
    295     // get ld_name
    296     llvm::StringRef ld_name(pStrTab + st_name);
    297 
    298     // get ld_type
    299     ResolveInfo::Type ld_type = static_cast<ResolveInfo::Type>(st_info & 0xF);
    300 
    301     // get ld_desc
    302     ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput);
    303 
    304     // get ld_binding
    305     ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other);
    306 
    307     // get ld_value - ld_value must be section relative.
    308     uint64_t ld_value = getSymValue(st_value, st_shndx, pInput);
    309 
    310     // get the input fragment
    311     MCFragmentRef* ld_frag_ref = getSymFragmentRef(pInput,
    312                                                    pLinker,
    313                                                    st_shndx,
    314                                                    ld_value);
    315 
    316     // get ld_vis
    317     ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);
    318 
    319     // push into MCLinker
    320     LDSymbol* input_sym = NULL;
    321 
    322     if (pInput.type() == Input::Object) {
    323       input_sym = pLinker.addSymbol<Input::Object>(ld_name,
    324                                                    ld_type,
    325                                                    ld_desc,
    326                                                    ld_binding,
    327                                                    st_size,
    328                                                    ld_value,
    329                                                    ld_frag_ref,
    330                                                    ld_vis);
    331       // push into the input file
    332       pInput.context()->addSymbol(input_sym);
    333       continue;
    334     }
    335     else if (pInput.type() == Input::DynObj) {
    336       input_sym = pLinker.addSymbol<Input::DynObj>(ld_name,
    337                                                    ld_type,
    338                                                    ld_desc,
    339                                                    ld_binding,
    340                                                    st_size,
    341                                                    ld_value,
    342                                                    ld_frag_ref,
    343                                                    ld_vis);
    344       continue;
    345     }
    346 
    347   } // end of for loop
    348   return true;
    349 }
    350 
    351 /// readSymbol - read a symbol from the given Input and index in symtab
    352 ResolveInfo* ELFReader<32, true>::readSymbol(Input& pInput,
    353                                              LDSection& pSymTab,
    354                                              MCLDInfo& pLDInfo,
    355                                              uint32_t pSymIdx) const
    356 {
    357   LDSection* symtab = &pSymTab;
    358   LDSection* strtab = symtab->getLink();
    359   assert(NULL != symtab && NULL != strtab);
    360 
    361   uint32_t offset = symtab->offset() + sizeof(llvm::ELF::Elf32_Sym) * pSymIdx;
    362   MemoryRegion* symbol_region =
    363                 pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf32_Sym));
    364   llvm::ELF::Elf32_Sym* entry =
    365                 reinterpret_cast<llvm::ELF::Elf32_Sym*>(symbol_region->start());
    366 
    367   uint32_t st_name  = 0x0;
    368   uint32_t st_value = 0x0;
    369   uint32_t st_size  = 0x0;
    370   uint8_t  st_info  = 0x0;
    371   uint8_t  st_other = 0x0;
    372   uint16_t st_shndx = 0x0;
    373   st_info  = entry->st_info;
    374   st_other = entry->st_other;
    375   if (llvm::sys::isLittleEndianHost()) {
    376     st_name  = entry->st_name;
    377     st_value = entry->st_value;
    378     st_size  = entry->st_size;
    379     st_shndx = entry->st_shndx;
    380   }
    381   else {
    382     st_name  = bswap32(entry->st_name);
    383     st_value = bswap32(entry->st_value);
    384     st_size  = bswap32(entry->st_size);
    385     st_shndx = bswap16(entry->st_shndx);
    386   }
    387 
    388   MemoryRegion* strtab_region =
    389                     pInput.memArea()->request(strtab->offset(), strtab->size());
    390 
    391   // get ld_name
    392   llvm::StringRef ld_name(reinterpret_cast<char*>(strtab_region->start() + st_name));
    393 
    394   // get ld_type
    395   ResolveInfo::Type ld_type = static_cast<ResolveInfo::Type>(st_info & 0xF);
    396 
    397   // get ld_desc
    398   ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput);
    399 
    400   // get ld_binding
    401   ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other);
    402 
    403   // get ld_vis
    404   ResolveInfo::Visibility ld_vis = getSymVisibility(st_other);
    405 
    406   ResolveInfo* result =
    407          pLDInfo.getStrSymPool().createSymbol(ld_name,
    408                                               pInput.type() == Input::DynObj,
    409                                               ld_type,
    410                                               ld_desc,
    411                                               ld_binding,
    412                                               st_size,
    413                                               ld_vis);
    414   // release regions
    415   pInput.memArea()->release(symbol_region);
    416   pInput.memArea()->release(strtab_region);
    417 
    418   return result;
    419 }
    420 
    421 /// readRela - read ELF rela and create Relocation
    422 bool ELFReader<32, true>::readRela(Input& pInput,
    423                                    MCLinker& pLinker,
    424                                    LDSection& pSection,
    425                                    const MemoryRegion& pRegion) const
    426 {
    427   // get the number of rela
    428   size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rela);
    429   llvm::ELF::Elf32_Rela* relaTab =
    430                      reinterpret_cast<llvm::ELF::Elf32_Rela*>(pRegion.start());
    431 
    432   for (size_t idx=0; idx < entsize; ++idx) {
    433     uint32_t r_offset = 0x0;
    434     uint32_t r_info   = 0x0;
    435     int32_t  r_addend = 0;
    436     if (llvm::sys::isLittleEndianHost()) {
    437       r_offset = relaTab[idx].r_offset;
    438       r_info   = relaTab[idx].r_info;
    439       r_addend = relaTab[idx].r_addend;
    440     }
    441     else {
    442       r_offset = bswap32(relaTab[idx].r_offset);
    443       r_info   = bswap32(relaTab[idx].r_info);
    444       r_addend = bswap32(relaTab[idx].r_addend);
    445     }
    446 
    447     uint8_t  r_type = static_cast<unsigned char>(r_info);
    448     uint32_t r_sym  = (r_info >> 8);
    449     LDSymbol* symbol = pInput.context()->getSymbol(r_sym);
    450     if (NULL == symbol) {
    451       llvm::report_fatal_error(llvm::Twine("invalid symbol index :") +
    452                                llvm::Twine(r_sym) +
    453                                llvm::Twine(" in file `") +
    454                                pInput.path().native() +
    455                                llvm::Twine("'.\n"));
    456     }
    457 
    458     ResolveInfo* resolve_info = symbol->resolveInfo();
    459 
    460     MCFragmentRef* frag_ref =
    461          pLinker.getLayout().getFragmentRef(*pSection.getLink(), r_offset);
    462 
    463     if (NULL == frag_ref) {
    464       llvm::report_fatal_error(llvm::Twine("invalid sh_info: ") +
    465                                llvm::Twine(pSection.getLink()->index()) +
    466                                llvm::Twine(" of the relocation section `") +
    467                                pSection.name() +
    468                                llvm::Twine("' in file `") +
    469                                pInput.path().native() +
    470                                llvm::Twine(".\n"));
    471     }
    472 
    473     pLinker.addRelocation(r_type, *symbol,  *resolve_info, *frag_ref, r_addend);
    474   }
    475   return true;
    476 }
    477 
    478 /// readRel - read ELF rel and create Relocation
    479 bool ELFReader<32, true>::readRel(Input& pInput,
    480                                   MCLinker& pLinker,
    481                                   LDSection& pSection,
    482                                   const MemoryRegion& pRegion) const
    483 {
    484   // get the number of rel
    485   size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rel);
    486   llvm::ELF::Elf32_Rel* relTab =
    487                       reinterpret_cast<llvm::ELF::Elf32_Rel*>(pRegion.start());
    488 
    489   for (size_t idx=0; idx < entsize; ++idx) {
    490     uint32_t r_offset = 0x0;
    491     uint32_t r_info   = 0x0;
    492     if (llvm::sys::isLittleEndianHost()) {
    493       r_offset = relTab[idx].r_offset;
    494       r_info   = relTab[idx].r_info;
    495     }
    496     else {
    497       r_offset = bswap32(relTab[idx].r_offset);
    498       r_info   = bswap32(relTab[idx].r_info);
    499     }
    500 
    501     uint8_t  r_type = static_cast<unsigned char>(r_info);
    502     uint32_t r_sym  = (r_info >> 8);
    503 
    504     LDSymbol* symbol = pInput.context()->getSymbol(r_sym);
    505     if (NULL == symbol) {
    506       llvm::report_fatal_error(llvm::Twine("invalid symbol index :") +
    507                                llvm::Twine(r_sym) +
    508                                llvm::Twine(" in file `") +
    509                                pInput.path().native() +
    510                                llvm::Twine("'.\n"));
    511     }
    512 
    513     ResolveInfo* resolve_info = symbol->resolveInfo();
    514 
    515     MCFragmentRef* frag_ref =
    516          pLinker.getLayout().getFragmentRef(*pSection.getLink(), r_offset);
    517 
    518     if (NULL == frag_ref) {
    519       llvm::report_fatal_error(llvm::Twine("invalid sh_info: ") +
    520                                llvm::Twine(pSection.getLink()->index()) +
    521                                llvm::Twine(" of the relocation section `") +
    522                                pSection.name() +
    523                                llvm::Twine("' in file `") +
    524                                pInput.path().native() +
    525                                llvm::Twine(".\n"));
    526     }
    527 
    528     pLinker.addRelocation(r_type, *symbol, *resolve_info, *frag_ref);
    529   }
    530   return true;
    531 }
    532