• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
10 #include <string>
11 #include <cassert>
12 
13 #include <llvm/Support/ELF.h>
14 #include <llvm/ADT/Twine.h>
15 
16 #include <mcld/MC/MCLDInput.h>
17 #include <mcld/MC/MCLinker.h>
18 #include <mcld/LD/RegionFragment.h>
19 #include <mcld/LD/ELFReader.h>
20 #include <mcld/LD/ELFObjectReader.h>
21 #include <mcld/Target/GNULDBackend.h>
22 #include <mcld/Support/MsgHandling.h>
23 
24 using namespace mcld;
25 
26 //==========================
27 // ELFObjectReader
28 /// constructor
ELFObjectReader(GNULDBackend & pBackend,MCLinker & pLinker)29 ELFObjectReader::ELFObjectReader(GNULDBackend& pBackend, MCLinker& pLinker)
30   : ObjectReader(),
31     m_pELFReader(0),
32     m_Linker(pLinker)
33 {
34   if (32 == pBackend.bitclass() && pBackend.isLittleEndian()) {
35     m_pELFReader = new ELFReader<32, true>(pBackend);
36   }
37 }
38 
39 /// destructor
~ELFObjectReader()40 ELFObjectReader::~ELFObjectReader()
41 {
42   delete m_pELFReader;
43 }
44 
45 /// isMyFormat
isMyFormat(Input & pInput) const46 bool ELFObjectReader::isMyFormat(Input &pInput) const
47 {
48   assert(pInput.hasMemArea());
49 
50   // Don't warning about the frequently requests.
51   // MemoryArea has a list of cache to handle this.
52   size_t hdr_size = m_pELFReader->getELFHeaderSize();
53   MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
54                                                      hdr_size);
55 
56   uint8_t* ELF_hdr = region->start();
57   bool result = true;
58   if (!m_pELFReader->isELF(ELF_hdr))
59     result = false;
60   else if (!m_pELFReader->isMyEndian(ELF_hdr))
61     result = false;
62   else if (!m_pELFReader->isMyMachine(ELF_hdr))
63     result = false;
64   else if (MCLDFile::Object != m_pELFReader->fileType(ELF_hdr))
65     result = false;
66   pInput.memArea()->release(region);
67   return result;
68 }
69 
70 /// readObject - read section header and create LDSections.
readObject(Input & pInput)71 bool ELFObjectReader::readObject(Input& pInput)
72 {
73   assert(pInput.hasMemArea());
74 
75   size_t hdr_size = m_pELFReader->getELFHeaderSize();
76   MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
77                                                      hdr_size);
78   uint8_t* ELF_hdr = region->start();
79   bool result = m_pELFReader->readSectionHeaders(pInput, m_Linker, ELF_hdr);
80   pInput.memArea()->release(region);
81   return result;
82 }
83 
84 /// readSections - read all regular sections.
readSections(Input & pInput)85 bool ELFObjectReader::readSections(Input& pInput)
86 {
87   // handle sections
88   LDContext::sect_iterator section, sectEnd = pInput.context()->sectEnd();
89   for (section = pInput.context()->sectBegin(); section != sectEnd; ++section) {
90     // ignore the section if the LDSection* in input context is NULL
91     if (NULL == *section)
92         continue;
93 
94     switch((*section)->kind()) {
95       /** group sections **/
96       case LDFileFormat::Group: {
97         assert(NULL != (*section)->getLink());
98         ResolveInfo* signature =
99               m_pELFReader->readSymbol(pInput,
100                                        *(*section)->getLink(),
101                                        m_Linker.getLDInfo(),
102                                        (*section)->getInfo());
103 
104         bool exist = false;
105         if (0 == std::strlen(signature->name()) &&
106             ResolveInfo::Section == signature->type()) {
107           // if the signature is a section symbol in input object, we use the
108           // section name as group signature.
109           signatures().insert((*section)->name(), exist);
110         } else {
111           signatures().insert(signature->name(), exist);
112         }
113 
114         if (exist) {
115           // if this is not the first time we see this group signature, then
116           // ignore all the members in this group (set NULL)
117           MemoryRegion* region = pInput.memArea()->request(
118                pInput.fileOffset() + (*section)->offset(), (*section)->size());
119           llvm::ELF::Elf32_Word* value =
120                      reinterpret_cast<llvm::ELF::Elf32_Word*>(region->start());
121 
122           size_t size = region->size() / sizeof(llvm::ELF::Elf32_Word);
123           if (llvm::ELF::GRP_COMDAT == *value) {
124             for (size_t index = 1; index < size; ++index)
125               pInput.context()->getSectionTable()[value[index]] = NULL;
126           }
127           pInput.memArea()->release(region);
128         }
129         break;
130       }
131       /** relocation sections **/
132       case LDFileFormat::Relocation: {
133         assert(NULL != (*section)->getLink());
134         size_t link_index = (*section)->getLink()->index();
135         if (NULL == pInput.context()->getSectionTable()[link_index]) {
136           // Relocation sections of group members should also be part of the
137           // group. Thus, if the associated member sections are ignored, the
138           // related relocations should be also ignored.
139           *section = NULL;
140         }
141         break;
142       }
143       /** normal sections **/
144       // FIXME: support Version Kinds
145       case LDFileFormat::Version:
146       /** Fall through **/
147       case LDFileFormat::Regular:
148       case LDFileFormat::Note:
149       case LDFileFormat::Debug:
150       case LDFileFormat::MetaData: {
151         if (!m_pELFReader->readRegularSection(pInput, m_Linker, **section))
152           fatal(diag::err_cannot_read_section) << (*section)->name();
153         break;
154       }
155       case LDFileFormat::EhFrame: {
156         if (!m_pELFReader->readEhFrame(pInput, m_Linker, **section))
157           fatal(diag::err_cannot_read_section) <<(*section)->name();
158         break;
159       }
160       case LDFileFormat::GCCExceptTable: {
161         //if (!m_pELFReader->readExceptionSection(pInput, m_Linker, **section))
162         if (!m_pELFReader->readRegularSection(pInput, m_Linker, **section))
163           fatal(diag::err_cannot_read_section) << (*section)->name();
164         break;
165       }
166       /** target dependent sections **/
167       case LDFileFormat::Target: {
168         if (!m_pELFReader->readTargetSection(pInput, m_Linker, **section))
169           fatal(diag::err_cannot_read_target_section) << (*section)->name();
170         break;
171       }
172       /** BSS sections **/
173       case LDFileFormat::BSS: {
174         LDSection& output_bss = m_Linker.getOrCreateOutputSectHdr(
175                                                (*section)->name(),
176                                                LDFileFormat::BSS,
177                                                llvm::ELF::SHT_NOBITS,
178                                                llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE);
179 
180         SectionData& sect_data = m_Linker.getOrCreateSectData(**section);
181                                             /*  value, valsize, size*/
182         FillFragment* frag = new FillFragment(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.
readSymbols(Input & pInput)209 bool 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 
readRelocations(Input & pInput)243 bool 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