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