TEST_F( ELFReaderTest, read_symbol_and_rela ) { ASSERT_TRUE(m_pInput->hasMemArea()); ASSERT_TRUE(m_pInput->hasContext()); m_pInput->setType(Input::Object); // -- read symbols LDSection* symtab_shdr = m_pInput->context()->getSection(".symtab"); ASSERT_TRUE(NULL!=symtab_shdr); LDSection* strtab_shdr = symtab_shdr->getLink(); ASSERT_TRUE(NULL!=strtab_shdr); MemoryRegion* symtab_region = m_pInput->memArea()->request( m_pInput->fileOffset() + symtab_shdr->offset(), symtab_shdr->size()); MemoryRegion* strtab_region = m_pInput->memArea()->request( m_pInput->fileOffset() + strtab_shdr->offset(), strtab_shdr->size()); char* strtab = reinterpret_cast<char*>(strtab_region->start()); bool result = m_pELFReader->readSymbols(*m_pInput, *m_pIRBuilder, *symtab_region, strtab); ASSERT_TRUE(result); ASSERT_EQ("hello.c", std::string(m_pInput->context()->getSymbol(1)->name())); ASSERT_EQ("puts", std::string(m_pInput->context()->getSymbol(10)->name())); ASSERT_TRUE(NULL==m_pInput->context()->getSymbol(11)); m_pInput->memArea()->release(symtab_region); m_pInput->memArea()->release(strtab_region); // -- read relocations MemoryArea* mem = m_pInput->memArea(); LDContext::sect_iterator rs = m_pInput->context()->relocSectBegin(); ASSERT_TRUE(rs!=m_pInput->context()->relocSectEnd()); ASSERT_EQ(".rela.text", (*rs)->name()); uint64_t offset = m_pInput->fileOffset() + (*rs)->offset(); uint64_t size = (*rs)->size(); MemoryRegion* region = mem->request(offset, size); IRBuilder::CreateRelocData(**rs); /// create relocation data for the header ASSERT_EQ(llvm::ELF::SHT_RELA, (*rs)->type()); ASSERT_TRUE(m_pELFReader->readRela(*m_pInput, **rs, *region)); mem->release(region); const RelocData::RelocationListType &rRelocs = (*rs)->getRelocData()->getRelocationList(); RelocData::const_iterator rReloc = rRelocs.begin(); ASSERT_EQ(2, rRelocs.size()); ASSERT_TRUE(rRelocs.end()!=rReloc); ++rReloc; /// test rRelocs[1] ASSERT_EQ("puts", std::string(rReloc->symInfo()->name())); ASSERT_EQ(llvm::ELF::R_X86_64_PC32, rReloc->type()); ASSERT_EQ(0x0, rReloc->symValue()); ASSERT_EQ(-0x4, rReloc->addend()); }
void EhFrameHdr::emitOutput<32>(MemoryArea& pOutput) { MemoryRegion* ehframehdr_region = pOutput.request(m_EhFrameHdr.offset(), m_EhFrameHdr.size()); MemoryRegion* ehframe_region = pOutput.request(m_EhFrame.offset(), m_EhFrame.size()); uint8_t* data = (uint8_t*)ehframehdr_region->start(); // version data[0] = 1; // eh_frame_ptr_enc data[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; // eh_frame_ptr uint32_t* eh_frame_ptr = (uint32_t*)(data + 4); *eh_frame_ptr = m_EhFrame.addr() - (m_EhFrameHdr.addr() + 4); // fde_count uint32_t* fde_count = (uint32_t*)(data + 8); if (m_EhFrame.hasEhFrame()) *fde_count = 0; else *fde_count = m_EhFrame.getEhFrame()->numOfFDEs(); if (0 != *fde_count) { // fde_count_enc data[2] = DW_EH_PE_udata4; // table_enc data[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; } else { // fde_count_enc data[2] = DW_EH_PE_omit; // table_enc data[3] = DW_EH_PE_omit; } if (0 != *fde_count) { // prepare the binary search table typedef std::vector<bit32::Entry> SearchTableType; SearchTableType search_table; MemoryRegion* ehframe_region = pOutput.request(m_EhFrame.offset(), m_EhFrame.size()); EhFrame::const_fde_iterator fde, fde_end = m_EhFrame.getEhFrame()->fde_end(); for(fde = m_EhFrame.getEhFrame()->fde_begin(); fde != fde_end; ++fde) { assert(*fde != NULL); SizeTraits<32>::Offset offset; SizeTraits<32>::Address fde_pc; SizeTraits<32>::Address fde_addr; offset = (*fde)->getOffset(); fde_pc = computePCBegin(**fde, *ehframe_region); fde_addr = m_EhFrame.addr() + offset; search_table.push_back(std::make_pair(fde_pc, fde_addr)); } pOutput.release(ehframe_region); std::sort(search_table.begin(), search_table.end(), bit32::EntryCompare); // write out the binary search table uint32_t* bst = (uint32_t*)(data + 12); SearchTableType::const_iterator entry, entry_end = search_table.end(); size_t id = 0; for (entry = search_table.begin(); entry != entry_end; ++entry) { bst[id++] = (*entry).first - m_EhFrameHdr.addr(); bst[id++] = (*entry).second - m_EhFrameHdr.addr(); } } pOutput.release(ehframehdr_region); pOutput.release(ehframe_region); }