ELFObjectReader.cpp revision 67e37f1be98c926645219cfb47fab9e90d8c725c
1//===- ELFObjectReader.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 <llvm/Support/ELF.h>
10#include <llvm/ADT/Twine.h>
11#include <mcld/LD/ELFObjectReader.h>
12#include <mcld/LD/ELFReader.h>
13#include <mcld/MC/MCLDInput.h>
14#include <mcld/MC/MCLinker.h>
15#include <mcld/MC/MCRegionFragment.h>
16#include <mcld/Target/GNULDBackend.h>
17#include <mcld/Support/MsgHandling.h>
18
19#include <string>
20#include <cassert>
21
22using namespace llvm;
23using namespace mcld;
24
25//==========================
26// ELFObjectReader
27/// constructor
28ELFObjectReader::ELFObjectReader(GNULDBackend& pBackend, MCLinker& pLinker)
29  : ObjectReader(),
30    m_pELFReader(0),
31    m_Linker(pLinker)
32{
33  if (32 == pBackend.bitclass() && pBackend.isLittleEndian()) {
34    m_pELFReader = new ELFReader<32, true>(pBackend);
35  }
36}
37
38/// destructor
39ELFObjectReader::~ELFObjectReader()
40{
41  delete m_pELFReader;
42}
43
44/// isMyFormat
45bool ELFObjectReader::isMyFormat(Input &pInput) const
46{
47  assert(pInput.hasMemArea());
48
49  // Don't warning about the frequently requests.
50  // MemoryArea has a list of cache to handle this.
51  size_t hdr_size = m_pELFReader->getELFHeaderSize();
52  MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
53                                                     hdr_size);
54
55  uint8_t* ELF_hdr = region->start();
56  bool result = true;
57  if (!m_pELFReader->isELF(ELF_hdr))
58    result = false;
59  else if (!m_pELFReader->isMyEndian(ELF_hdr))
60    result = false;
61  else if (!m_pELFReader->isMyMachine(ELF_hdr))
62    result = false;
63  else if (MCLDFile::Object != m_pELFReader->fileType(ELF_hdr))
64    result = false;
65  pInput.memArea()->release(region);
66  return result;
67}
68
69/// readObject - read section header and create LDSections.
70bool ELFObjectReader::readObject(Input& pInput)
71{
72  assert(pInput.hasMemArea());
73
74  size_t hdr_size = m_pELFReader->getELFHeaderSize();
75  MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
76                                                     hdr_size);
77  uint8_t* ELF_hdr = region->start();
78  bool result = m_pELFReader->readSectionHeaders(pInput, m_Linker, ELF_hdr);
79  pInput.memArea()->release(region);
80  return result;
81}
82
83/// readSections - read all regular sections.
84bool ELFObjectReader::readSections(Input& pInput)
85{
86  // handle sections
87  LDContext::sect_iterator section, sectEnd = pInput.context()->sectEnd();
88  for (section = pInput.context()->sectBegin(); section != sectEnd; ++section) {
89    // ignore the section if the LDSection* in input context is NULL
90    if (NULL == *section)
91        continue;
92
93    switch((*section)->kind()) {
94      /** group sections **/
95      case LDFileFormat::Group: {
96        assert(NULL != (*section)->getLink());
97        ResolveInfo* signature =
98              m_pELFReader->readSymbol(pInput,
99                                       *(*section)->getLink(),
100                                       m_Linker.getLDInfo(),
101                                       (*section)->getInfo());
102
103        bool exist = false;
104        if (0 == std::strlen(signature->name()) &&
105            ResolveInfo::Section == signature->type()) {
106          // if the signature is a section symbol in input object, we use the
107          // section name as group signature.
108          signatures().insert((*section)->name(), exist);
109        } else {
110          signatures().insert(signature->name(), exist);
111        }
112
113        if (exist) {
114          // if this is not the first time we see this group signature, then
115          // ignore all the members in this group (set NULL)
116          MemoryRegion* region = pInput.memArea()->request(
117               pInput.fileOffset() + (*section)->offset(), (*section)->size());
118          llvm::ELF::Elf32_Word* value =
119                     reinterpret_cast<llvm::ELF::Elf32_Word*>(region->start());
120
121          size_t size = region->size() / sizeof(llvm::ELF::Elf32_Word);
122          if (llvm::ELF::GRP_COMDAT == *value) {
123            for (size_t index = 1; index < size; ++index)
124              pInput.context()->getSectionTable()[value[index]] = NULL;
125          }
126          pInput.memArea()->release(region);
127        }
128        break;
129      }
130      /** relocation sections **/
131      case LDFileFormat::Relocation: {
132        assert(NULL != (*section)->getLink());
133        size_t link_index = (*section)->getLink()->index();
134        if (NULL == pInput.context()->getSectionTable()[link_index]) {
135          // Relocation sections of group members should also be part of the
136          // group. Thus, if the associated member sections are ignored, the
137          // related relocations should be also ignored.
138          *section = NULL;
139        }
140        break;
141      }
142      /** normal sections **/
143      // FIXME: support Version Kinds
144      case LDFileFormat::Version:
145      /** Fall through **/
146      case LDFileFormat::Regular:
147      case LDFileFormat::Note:
148      case LDFileFormat::Debug:
149      case LDFileFormat::MetaData: {
150        if (!m_pELFReader->readRegularSection(pInput, m_Linker, **section))
151          fatal(diag::err_cannot_read_section) << (*section)->name();
152        break;
153      }
154      case LDFileFormat::EhFrame: {
155        if (!m_pELFReader->readEhFrame(pInput, m_Linker, **section))
156          fatal(diag::err_cannot_read_section) <<(*section)->name();
157        break;
158      }
159      case LDFileFormat::GCCExceptTable: {
160        //if (!m_pELFReader->readExceptionSection(pInput, m_Linker, **section))
161        if (!m_pELFReader->readRegularSection(pInput, m_Linker, **section))
162          fatal(diag::err_cannot_read_section) << (*section)->name();
163        break;
164      }
165      /** target dependent sections **/
166      case LDFileFormat::Target: {
167        if (!m_pELFReader->readTargetSection(pInput, m_Linker, **section))
168          fatal(diag::err_cannot_read_target_section) << (*section)->name();
169        break;
170      }
171      /** BSS sections **/
172      case LDFileFormat::BSS: {
173        LDSection& output_bss = m_Linker.getOrCreateOutputSectHdr(
174                                               (*section)->name(),
175                                               LDFileFormat::BSS,
176                                               llvm::ELF::SHT_NOBITS,
177                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE);
178
179        llvm::MCSectionData& sect_data = m_Linker.getOrCreateSectData(**section);
180                                         /*  value, valsize, size*/
181        llvm::MCFillFragment* frag =
182                    new llvm::MCFillFragment(0x0,   1,       (*section)->size());
183
184        uint64_t size = m_Linker.getLayout().appendFragment(*frag,
185                                                            sect_data,
186                                                            (*section)->align());
187        output_bss.setSize(output_bss.size() + size);
188        break;
189      }
190      // ignore
191      case LDFileFormat::Null:
192      case LDFileFormat::NamePool:
193        continue;
194      // warning
195      case LDFileFormat::EhFrameHdr:
196      default: {
197        warning(diag::warn_illegal_input_section) << (*section)->name()
198                                                  << pInput.name()
199                                                  << pInput.path();
200        break;
201      }
202    }
203  } // end of for all sections
204
205  return true;
206}
207
208/// readSymbols - read symbols into MCLinker from the input relocatable object.
209bool ELFObjectReader::readSymbols(Input& pInput)
210{
211  assert(pInput.hasMemArea());
212
213  LDSection* symtab_shdr = pInput.context()->getSection(".symtab");
214  if (NULL == symtab_shdr) {
215    note(diag::note_has_no_symtab) << pInput.name()
216                                   << pInput.path()
217                                   << ".symtab";
218    return true;
219  }
220
221  LDSection* strtab_shdr = symtab_shdr->getLink();
222  if (NULL == strtab_shdr) {
223    fatal(diag::fatal_cannot_read_strtab) << pInput.name()
224                                          << pInput.path()
225                                          << ".symtab";
226    return false;
227  }
228
229  MemoryRegion* symtab_region = pInput.memArea()->request(
230             pInput.fileOffset() + symtab_shdr->offset(), symtab_shdr->size());
231  MemoryRegion* strtab_region = pInput.memArea()->request(
232             pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size());
233  char* strtab = reinterpret_cast<char*>(strtab_region->start());
234  bool result = m_pELFReader->readSymbols(pInput,
235                                          m_Linker,
236                                          *symtab_region,
237                                          strtab);
238  pInput.memArea()->release(symtab_region);
239  pInput.memArea()->release(strtab_region);
240  return result;
241}
242
243bool ELFObjectReader::readRelocations(Input& pInput)
244{
245  assert(pInput.hasMemArea());
246
247  MemoryArea* mem = pInput.memArea();
248  LDContext::sect_iterator section, sectEnd = pInput.context()->sectEnd();
249  for (section = pInput.context()->sectBegin(); section != sectEnd; ++section) {
250    // ignore the section if the LDSection* in input context is NULL
251    if (NULL == *section)
252        continue;
253
254    if ((*section)->type() == llvm::ELF::SHT_RELA &&
255        (*section)->kind() == LDFileFormat::Relocation) {
256      MemoryRegion* region = mem->request(
257               pInput.fileOffset() + (*section)->offset(), (*section)->size());
258      bool result = m_pELFReader->readRela(pInput, m_Linker, **section,
259                                           *region);
260      mem->release(region);
261      if (!result)
262        return false;
263    }
264    else if ((*section)->type() == llvm::ELF::SHT_REL &&
265             (*section)->kind() == LDFileFormat::Relocation) {
266      MemoryRegion* region = mem->request(
267               pInput.fileOffset() + (*section)->offset(), (*section)->size());
268      bool result = m_pELFReader->readRel(pInput, m_Linker, **section, *region);
269      mem->release(region);
270      if (!result)
271        return false;
272    }
273  }
274  return true;
275}
276
277