ELFObjectReader.cpp revision a790f0a8f3175183bea088389b3e4ae41813e192
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 if (((*section)->flag() & llvm::ELF::SHF_EXECINSTR) != 0) 174 (*section)->setKind(LDFileFormat::TEXT); 175 else 176 (*section)->setKind(LDFileFormat::DATA); 177 SectionData* sd = IRBuilder::CreateSectionData(**section); 178 if (!m_pELFReader->readRegularSection(pInput, *sd)) 179 fatal(diag::err_cannot_read_section) << (*section)->name(); 180 } 181 } else { 182 (*section)->setKind(LDFileFormat::Ignore); 183 } 184 break; 185 } 186 /** relocation sections **/ 187 case LDFileFormat::Relocation: { 188 assert(NULL != (*section)->getLink()); 189 size_t link_index = (*section)->getLink()->index(); 190 LDSection* link_sect = pInput.context()->getSection(link_index); 191 if (NULL == link_sect || LDFileFormat::Ignore == link_sect->kind()) { 192 // Relocation sections of group members should also be part of the 193 // group. Thus, if the associated member sections are ignored, the 194 // related relocations should be also ignored. 195 (*section)->setKind(LDFileFormat::Ignore); 196 } 197 break; 198 } 199 /** normal sections **/ 200 // FIXME: support Version Kind 201 case LDFileFormat::Version: 202 // FIXME: support GCCExceptTable Kind 203 case LDFileFormat::GCCExceptTable: 204 /** Fall through **/ 205 case LDFileFormat::TEXT: 206 case LDFileFormat::DATA: 207 case LDFileFormat::Note: 208 case LDFileFormat::MetaData: { 209 SectionData* sd = IRBuilder::CreateSectionData(**section); 210 if (!m_pELFReader->readRegularSection(pInput, *sd)) 211 fatal(diag::err_cannot_read_section) << (*section)->name(); 212 break; 213 } 214 case LDFileFormat::Debug: { 215 if (m_Config.options().stripDebug()) { 216 (*section)->setKind(LDFileFormat::Ignore); 217 } 218 else { 219 SectionData* sd = IRBuilder::CreateSectionData(**section); 220 if (!m_pELFReader->readRegularSection(pInput, *sd)) { 221 fatal(diag::err_cannot_read_section) << (*section)->name(); 222 } 223 } 224 break; 225 } 226 case LDFileFormat::EhFrame: { 227 EhFrame* eh_frame = IRBuilder::CreateEhFrame(**section); 228 229 // We don't really parse EhFrame if this is a partial linking 230 if ((m_Config.codeGenType() != LinkerConfig::Object) && 231 (m_ReadFlag & ParseEhFrame)) { 232 if (!m_pEhFrameReader->read<32, true>(pInput, *eh_frame)) { 233 // if we failed to parse a .eh_frame, we should not parse the rest 234 // .eh_frame. 235 m_ReadFlag ^= ParseEhFrame; 236 } 237 } 238 else { 239 if (!m_pELFReader->readRegularSection(pInput, 240 *eh_frame->getSectionData())) { 241 fatal(diag::err_cannot_read_section) << (*section)->name(); 242 } 243 } 244 break; 245 } 246 /** target dependent sections **/ 247 case LDFileFormat::Target: { 248 SectionData* sd = IRBuilder::CreateSectionData(**section); 249 if (!m_Backend.readSection(pInput, *sd)) { 250 fatal(diag::err_cannot_read_target_section) << (*section)->name(); 251 } 252 break; 253 } 254 /** BSS sections **/ 255 case LDFileFormat::BSS: { 256 IRBuilder::CreateBSS(**section); 257 break; 258 } 259 // ignore 260 case LDFileFormat::Null: 261 case LDFileFormat::NamePool: 262 case LDFileFormat::Ignore: 263 case LDFileFormat::StackNote: 264 continue; 265 // warning 266 case LDFileFormat::EhFrameHdr: 267 default: { 268 warning(diag::warn_illegal_input_section) << (*section)->name() 269 << pInput.name() 270 << pInput.path(); 271 break; 272 } 273 } 274 } // end of for all sections 275 276 return true; 277} 278 279/// readSymbols - read symbols from the input relocatable object. 280bool ELFObjectReader::readSymbols(Input& pInput) 281{ 282 assert(pInput.hasMemArea()); 283 284 LDSection* symtab_shdr = pInput.context()->getSection(".symtab"); 285 if (NULL == symtab_shdr) { 286 note(diag::note_has_no_symtab) << pInput.name() 287 << pInput.path() 288 << ".symtab"; 289 return true; 290 } 291 292 LDSection* strtab_shdr = symtab_shdr->getLink(); 293 if (NULL == strtab_shdr) { 294 fatal(diag::fatal_cannot_read_strtab) << pInput.name() 295 << pInput.path() 296 << ".symtab"; 297 return false; 298 } 299 300 llvm::StringRef symtab_region = pInput.memArea()->request( 301 pInput.fileOffset() + symtab_shdr->offset(), symtab_shdr->size()); 302 llvm::StringRef strtab_region = pInput.memArea()->request( 303 pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size()); 304 const char* strtab = strtab_region.begin(); 305 bool result = m_pELFReader->readSymbols(pInput, 306 m_Builder, 307 symtab_region, 308 strtab); 309 return result; 310} 311 312bool ELFObjectReader::readRelocations(Input& pInput) 313{ 314 assert(pInput.hasMemArea()); 315 316 MemoryArea* mem = pInput.memArea(); 317 LDContext::sect_iterator rs, rsEnd = pInput.context()->relocSectEnd(); 318 for (rs = pInput.context()->relocSectBegin(); rs != rsEnd; ++rs) { 319 if (LDFileFormat::Ignore == (*rs)->kind()) 320 continue; 321 322 uint32_t offset = pInput.fileOffset() + (*rs)->offset(); 323 uint32_t size = (*rs)->size(); 324 llvm::StringRef region = mem->request(offset, size); 325 IRBuilder::CreateRelocData(**rs); ///< create relocation data for the header 326 switch ((*rs)->type()) { 327 case llvm::ELF::SHT_RELA: { 328 if (!m_pELFReader->readRela(pInput, **rs, region)) { 329 return false; 330 } 331 break; 332 } 333 case llvm::ELF::SHT_REL: { 334 if (!m_pELFReader->readRel(pInput, **rs, region)) { 335 return false; 336 } 337 break; 338 } 339 default: { ///< should not enter 340 return false; 341 } 342 } // end of switch 343 344 } // end of for all relocation data 345 346 return true; 347} 348 349