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