1affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===- EhFrame.cpp --------------------------------------------------------===// 2affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 3affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// The MCLinker Project 4affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 5affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// This file is distributed under the University of Illinois Open Source 6affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// License. See LICENSE.TXT for details. 7affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 8affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrame.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Relocation.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocData.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ResolveInfo.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Input.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/GCFactory.h" 216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ManagedStatic.h> 23cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestypedef GCFactory<EhFrame, MCLD_SECTIONS_PER_INPUT> EhFrameFactory; 276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesstatic llvm::ManagedStatic<EhFrameFactory> g_EhFrameFactory; 296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// EhFrame::Record 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 3337b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame::Record::Record(llvm::StringRef pRegion) : RegionFragment(pRegion) { 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 35cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 3637b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame::Record::~Record() { 37f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // llvm::iplist will manage and delete the fragments 38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 39f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 40f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 41f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// EhFrame::CIE 42f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 43f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesEhFrame::CIE::CIE(llvm::StringRef pRegion) 4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines : EhFrame::Record(pRegion), 4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_FDEEncode(0u), 4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Mergeable(false), 4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pReloc(0), 4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_PersonalityOffset(0) { 49f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 50f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 5137b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame::CIE::~CIE() { 52f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// EhFrame::FDE 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 57f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesEhFrame::FDE::FDE(llvm::StringRef pRegion, EhFrame::CIE& pCIE) 5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines : EhFrame::Record(pRegion), m_pCIE(&pCIE) { 59f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 60f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 6137b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame::FDE::~FDE() { 62f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 63f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 6437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::FDE::setCIE(EhFrame::CIE& pCIE) { 65f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pCIE = &pCIE; 66f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pCIE->add(*this); 67f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 68f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// EhFrame::GeneratedCIE 71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesEhFrame::GeneratedCIE::GeneratedCIE(llvm::StringRef pRegion) 7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines : EhFrame::CIE(pRegion) { 74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 7637b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame::GeneratedCIE::~GeneratedCIE() { 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 80f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// EhFrame::GeneratedFDE 81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 8237b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame::GeneratedFDE::GeneratedFDE(llvm::StringRef pRegion, CIE& pCIE) 8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines : EhFrame::FDE(pRegion, pCIE) { 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 8637b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame::GeneratedFDE::~GeneratedFDE() { 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// EhFrame 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 9237b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame::EhFrame() : m_pSection(NULL), m_pSectionData(NULL) { 936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoEhFrame::EhFrame(LDSection& pSection) 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_pSection(&pSection), m_pSectionData(NULL) { 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pSectionData = SectionData::Create(pSection); 98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 10037b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame::~EhFrame() { 101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 10337b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame* EhFrame::Create(LDSection& pSection) { 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines EhFrame* result = g_EhFrameFactory->allocate(); 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines new (result) EhFrame(pSection); 1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::Destroy(EhFrame*& pSection) { 1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pSection->~EhFrame(); 1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines g_EhFrameFactory->deallocate(pSection); 1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pSection = NULL; 1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::Clear() { 1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines g_EhFrameFactory->clear(); 1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst LDSection& EhFrame::getSection() const { 12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pSection != NULL); 1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pSection; 1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12437b74a387bb3993387029859c2d9d051c41c724eStephen HinesLDSection& EhFrame::getSection() { 12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pSection != NULL); 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pSection; 1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 12937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::addFragment(Fragment& pFrag) { 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = 0; 13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!m_pSectionData->empty()) 13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset = m_pSectionData->back().getOffset() + m_pSectionData->back().size(); 133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_pSectionData->getFragmentList().push_back(&pFrag); 135f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pFrag.setParent(m_pSectionData); 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pFrag.setOffset(offset); 137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 13937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::addCIE(EhFrame::CIE& pCIE, bool pAlsoAddFragment) { 140f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_CIEs.push_back(&pCIE); 141f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pAlsoAddFragment) 142f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines addFragment(pCIE); 143f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 14537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::addFDE(EhFrame::FDE& pFDE, bool pAlsoAddFragment) { 146f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pFDE.getCIE().add(pFDE); 147f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pAlsoAddFragment) 148f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines addFragment(pFDE); 149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15137b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t EhFrame::numOfFDEs() const { 152f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // FDE number only used by .eh_frame_hdr computation, and the number of CIE 153f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // is usually not too many. It is worthy to compromise space by time 154f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines size_t size = 0u; 155f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (const_cie_iterator i = cie_begin(), e = cie_end(); i != e; ++i) 156f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines size += (*i)->numOfFDEs(); 157f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return size; 158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 16037b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame& EhFrame::merge(const Input& pInput, EhFrame& pFrame) { 16137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(this != &pFrame); 162f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pFrame.emptyCIEs()) { 163f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // May be a partial linking, or the eh_frame has no data. 164f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Just append the fragments. 165f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines moveInputFragments(pFrame); 166f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return *this; 167f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 169f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const LDContext& ctx = *pInput.context(); 170f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const LDSection* rel_sec = 0; 171f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (LDContext::const_sect_iterator ri = ctx.relocSectBegin(), 17237b74a387bb3993387029859c2d9d051c41c724eStephen Hines re = ctx.relocSectEnd(); 17337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ri != re; 17437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++ri) { 175f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if ((*ri)->getLink() == &pFrame.getSection()) { 176f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines rel_sec = *ri; 177f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 178f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 179f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 180f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pFrame.setupAttributes(rel_sec); 181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 182f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Most CIE will be merged, so we don't reserve space first. 183f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (cie_iterator i = pFrame.cie_begin(), e = pFrame.cie_end(); i != e; ++i) { 184f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines CIE& input_cie = **i; 185f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // CIE number is usually very few, so we just use vector sequential search. 186f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!input_cie.getMergeable()) { 187f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines moveInputFragments(pFrame, input_cie); 188f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines addCIE(input_cie, /*AlsoAddFragment=*/false); 189f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines continue; 190f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 192f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines cie_iterator out_i = cie_begin(); 193f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (cie_iterator out_e = cie_end(); out_i != out_e; ++out_i) { 194f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines CIE& output_cie = **out_i; 195f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (output_cie == input_cie) { 196f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // This input CIE can be merged 197f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines moveInputFragments(pFrame, input_cie, &output_cie); 198f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines removeAndUpdateCIEForFDE(pFrame, input_cie, output_cie, rel_sec); 199f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 200f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 201f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 202f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (out_i == cie_end()) { 203f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines moveInputFragments(pFrame, input_cie); 204f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines addCIE(input_cie, /*AlsoAddFragment=*/false); 205f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 206f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return *this; 208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 21037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::setupAttributes(const LDSection* rel_sec) { 211f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (cie_iterator i = cie_begin(), e = cie_end(); i != e; ++i) { 212f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines CIE* cie = *i; 213f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines removeDiscardedFDE(*cie, rel_sec); 214f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 215f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (cie->getPersonalityName().size() == 0) { 216f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // There's no personality data encoding inside augmentation string. 217f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines cie->setMergeable(); 218f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } else { 219f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!rel_sec) { 220f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // No relocation to eh_frame section 22137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(cie->getPersonalityName() != "" && 22237b74a387bb3993387029859c2d9d051c41c724eStephen Hines "PR name should be a symbol address or offset"); 223f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines continue; 224f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 225f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const RelocData* reloc_data = rel_sec->getRelocData(); 226f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (RelocData::const_iterator ri = reloc_data->begin(), 22737b74a387bb3993387029859c2d9d051c41c724eStephen Hines re = reloc_data->end(); 22837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ri != re; 22937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++ri) { 230f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const Relocation& rel = *ri; 23137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (rel.targetRef().getOutputOffset() == 23237b74a387bb3993387029859c2d9d051c41c724eStephen Hines cie->getOffset() + cie->getPersonalityOffset()) { 233f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines cie->setMergeable(); 234f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines cie->setPersonalityName(rel.symInfo()->outSymbol()->name()); 235f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines cie->setRelocation(rel); 236f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 237f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 238f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 239f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 24037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(cie->getPersonalityName() != "" && 24137b74a387bb3993387029859c2d9d051c41c724eStephen Hines "PR name should be a symbol address or offset"); 242f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 243f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 244f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 245f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 24637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::removeDiscardedFDE(CIE& pCIE, const LDSection* pRelocSect) { 247f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!pRelocSect) 248f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return; 249f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 250f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines typedef std::vector<FDE*> FDERemoveList; 251f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines FDERemoveList to_be_removed_fdes; 252f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const RelocData* reloc_data = pRelocSect->getRelocData(); 253f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (fde_iterator i = pCIE.begin(), e = pCIE.end(); i != e; ++i) { 254f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines FDE& fde = **i; 255f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (RelocData::const_iterator ri = reloc_data->begin(), 25637b74a387bb3993387029859c2d9d051c41c724eStephen Hines re = reloc_data->end(); 25737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ri != re; 25837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++ri) { 259f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const Relocation& rel = *ri; 26037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (rel.targetRef().getOutputOffset() == 26137b74a387bb3993387029859c2d9d051c41c724eStephen Hines fde.getOffset() + getDataStartOffset<32>()) { 262f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines bool has_section = rel.symInfo()->outSymbol()->hasFragRef(); 263f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!has_section) 264f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // The section was discarded, just ignore this FDE. 265f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // This may happen when redundant group section was read. 266f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines to_be_removed_fdes.push_back(&fde); 267f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 268f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 269f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 270f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 271f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 272f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (FDERemoveList::iterator i = to_be_removed_fdes.begin(), 27337b74a387bb3993387029859c2d9d051c41c724eStephen Hines e = to_be_removed_fdes.end(); 27437b74a387bb3993387029859c2d9d051c41c724eStephen Hines i != e; 27537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++i) { 276f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines FDE& fde = **i; 277f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines fde.getCIE().remove(fde); 278f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 279f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // FIXME: This traverses relocations from the beginning on each FDE, which 280f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // may cause performance degration. Actually relocations will be sequential 281f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // order, so we can bookkeep the previously found relocation for next use. 282f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Note: We must ensure FDE order is ordered. 283f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (RelocData::const_iterator ri = reloc_data->begin(), 28437b74a387bb3993387029859c2d9d051c41c724eStephen Hines re = reloc_data->end(); 28537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ri != re;) { 286f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation& rel = const_cast<Relocation&>(*ri++); 287f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (rel.targetRef().getOutputOffset() >= fde.getOffset() && 288f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines rel.targetRef().getOutputOffset() < fde.getOffset() + fde.size()) { 289f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const_cast<RelocData*>(reloc_data)->remove(rel); 290f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 291f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 292f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 293f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 294f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 29537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::removeAndUpdateCIEForFDE(EhFrame& pInFrame, 29637b74a387bb3993387029859c2d9d051c41c724eStephen Hines CIE& pInCIE, 29737b74a387bb3993387029859c2d9d051c41c724eStephen Hines CIE& pOutCIE, 29837b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSection* rel_sect) { 299f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Make this relocation to be ignored. 300f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation* rel = const_cast<Relocation*>(pInCIE.getRelocation()); 301f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (rel && rel_sect) 302f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const_cast<RelocData*>(rel_sect->getRelocData())->remove(*rel); 303f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 304f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Update the CIE-pointed FDEs 305f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (fde_iterator i = pInCIE.begin(), e = pInCIE.end(); i != e; ++i) 306f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines (*i)->setCIE(pOutCIE); 307f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 308f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // We cannot know whether there are references to this fragment, so just 309f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // keep it in input fragment list instead of memory deallocation 310f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInCIE.clearFDEs(); 311f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 312f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 31337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::moveInputFragments(EhFrame& pInFrame) { 314f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionData& in_sd = *pInFrame.getSectionData(); 315f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionData::FragmentListType& in_frag_list = in_sd.getFragmentList(); 316f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionData& out_sd = *getSectionData(); 317f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionData::FragmentListType& out_frag_list = out_sd.getFragmentList(); 318f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 319f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines while (!in_frag_list.empty()) { 320f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Fragment* frag = in_frag_list.remove(in_frag_list.begin()); 321f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines out_frag_list.push_back(frag); 322f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines frag->setParent(&out_sd); 323f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 324f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 325f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 32637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid EhFrame::moveInputFragments(EhFrame& pInFrame, CIE& pInCIE, CIE* pOutCIE) { 327f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionData& in_sd = *pInFrame.getSectionData(); 328f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionData::FragmentListType& in_frag_list = in_sd.getFragmentList(); 329f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionData& out_sd = *getSectionData(); 330f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionData::FragmentListType& out_frag_list = out_sd.getFragmentList(); 331f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 332f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!pOutCIE) { 333f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Newly inserted 334f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Fragment* frag = in_frag_list.remove(SectionData::iterator(pInCIE)); 335f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines out_frag_list.push_back(frag); 336f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines frag->setParent(&out_sd); 337f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (fde_iterator i = pInCIE.begin(), e = pInCIE.end(); i != e; ++i) { 338f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines frag = in_frag_list.remove(SectionData::iterator(**i)); 339f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines out_frag_list.push_back(frag); 340f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines frag->setParent(&out_sd); 341f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 342f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return; 343f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 344f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 345f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionData::iterator cur_iter(*pOutCIE); 34637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(cur_iter != out_frag_list.end()); 347f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (fde_iterator i = pInCIE.begin(), e = pInCIE.end(); i != e; ++i) { 348f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Fragment* frag = in_frag_list.remove(SectionData::iterator(**i)); 349f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines cur_iter = out_frag_list.insertAfter(cur_iter, frag); 350f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines frag->setParent(&out_sd); 351f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 352f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 353f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 35437b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t EhFrame::computeOffsetSize() { 355f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines size_t offset = 0u; 35637b74a387bb3993387029859c2d9d051c41c724eStephen Hines SectionData::FragmentListType& frag_list = 35737b74a387bb3993387029859c2d9d051c41c724eStephen Hines getSectionData()->getFragmentList(); 35837b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (SectionData::iterator i = frag_list.begin(), e = frag_list.end(); i != e; 35937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++i) { 360f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Fragment& frag = *i; 361f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines frag.setOffset(offset); 362f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines offset += frag.size(); 363f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 364f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines getSection().setSize(offset); 365f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return offset; 366f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 367f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 36837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool operator==(const EhFrame::CIE& p1, const EhFrame::CIE& p2) { 369f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return p1.getPersonalityName() == p2.getPersonalityName() && 370f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines p1.getAugmentationData() == p2.getAugmentationData(); 371f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 37237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 37337b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 374