197eecb1834431b39d4d58257f8ccfdea1db7f1deGreg Clayton//===-- UnwindTable.cpp -----------------------------------------*- C++ -*-===// 23a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// 33a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// The LLVM Compiler Infrastructure 43a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// 53a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// This file is distributed under the University of Illinois Open Source 63a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// License. See LICENSE.TXT for details. 73a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// 83a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//===----------------------------------------------------------------------===// 93a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 10412440aa3a110e4068ee99729f7883c828fb3dceGreg Clayton#include "lldb/Symbol/UnwindTable.h" 113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 12412440aa3a110e4068ee99729f7883c828fb3dceGreg Clayton#include <stdio.h> 13412440aa3a110e4068ee99729f7883c828fb3dceGreg Clayton 14412440aa3a110e4068ee99729f7883c828fb3dceGreg Clayton#include "lldb/Core/Module.h" 15412440aa3a110e4068ee99729f7883c828fb3dceGreg Clayton#include "lldb/Core/Section.h" 16412440aa3a110e4068ee99729f7883c828fb3dceGreg Clayton#include "lldb/Symbol/ObjectFile.h" 173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Symbol/FuncUnwinders.h" 183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Symbol/SymbolContext.h" 193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Symbol/DWARFCallFrameInfo.h" 208badcb2503ed2e2884a48f66099c1d48494817f4Greg Clayton#include "lldb/Target/UnwindAssembly.h" 213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// There is one UnwindTable object per ObjectFile. 233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// It contains a list of Unwind objects -- one per function, populated lazily -- for the ObjectFile. 243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// Each Unwind object has multiple UnwindPlans for different scenarios. 253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendausing namespace lldb; 273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendausing namespace lldb_private; 283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 29e2f90647b93b0f44c0222da8d995dfe267499f9cGreg ClaytonUnwindTable::UnwindTable (ObjectFile& objfile) : 30e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton m_object_file (objfile), 31e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton m_unwinds (), 32e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton m_initialized (false), 33dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson m_assembly_profiler (NULL), 34dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson m_eh_frame (NULL) 353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// We can't do some of this initialization when the ObjectFile is running its ctor; delay doing it 393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// until needed for something. 403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid 42e2f90647b93b0f44c0222da8d995dfe267499f9cGreg ClaytonUnwindTable::Initialize () 433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_initialized) 453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return; 463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda SectionList* sl = m_object_file.GetSectionList (); 483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (sl) 493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda SectionSP sect = sl->FindSectionByType (eSectionTypeEHFrame, true); 513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (sect.get()) 523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda m_eh_frame = new DWARFCallFrameInfo(m_object_file, sect, eRegisterKindGCC, true); 543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda ArchSpec arch; 58395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton if (m_object_file.GetArchitecture (arch)) 59395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton { 608badcb2503ed2e2884a48f66099c1d48494817f4Greg Clayton m_assembly_profiler = UnwindAssembly::FindPlugin (arch); 61395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton m_initialized = true; 62395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton } 633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 653a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaUnwindTable::~UnwindTable () 663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda if (m_eh_frame) 683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda delete m_eh_frame; 693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 713a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaFuncUnwindersSP 723a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaUnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc) 733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda FuncUnwindersSP no_unwind_found; 753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 76e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton Initialize(); 773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 78e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton // There is an UnwindTable per object file, so we can safely use file handles 79e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton addr_t file_addr = addr.GetFileAddress(); 80e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton iterator end = m_unwinds.end (); 81e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton iterator insert_pos = end; 82e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton if (!m_unwinds.empty()) 833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 84e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton insert_pos = m_unwinds.lower_bound (file_addr); 85e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton iterator pos = insert_pos; 86e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton if ((pos == m_unwinds.end ()) || (pos != m_unwinds.begin() && pos->second->GetFunctionStartAddress() != addr)) 87e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton --pos; 88e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton 89e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton if (pos->second->ContainsAddress (addr)) 90e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton return pos->second; 913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda AddressRange range; 94ff44ab42e9f5d8e4d550e11d1b69413e0bc75b71Greg Clayton if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, false, range) || !range.GetBaseAddress().IsValid()) 953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 96800d11d87769e1a7083f7a5545613625396deb3eJason Molenda // Does the eh_frame unwind info has a function bounds for this addr? 97d6ef16aab825a1319179d1445f35538f535e9bf1Jason Molenda if (m_eh_frame == NULL || !m_eh_frame->GetAddressRange (addr, range)) 983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda { 99800d11d87769e1a7083f7a5545613625396deb3eJason Molenda return no_unwind_found; 1003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 1013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda } 102800d11d87769e1a7083f7a5545613625396deb3eJason Molenda 103e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, m_assembly_profiler, range)); 104e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton m_unwinds.insert (insert_pos, std::make_pair(range.GetBaseAddress().GetFileAddress(), func_unwinder_sp)); 105e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton// StreamFile s(stdout); 106e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton// Dump (s); 107e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton return func_unwinder_sp; 108e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton} 109e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton 1105b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda// Ignore any existing FuncUnwinders for this function, create a new one and don't add it to the 1115b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda// UnwindTable. This is intended for use by target modules show-unwind where we want to create 1125b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda// new UnwindPlans, not re-use existing ones. 1135b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda 1145b0afcceea3807fa8f518e0138f0a8043dfc3315Jason MolendaFuncUnwindersSP 1155b0afcceea3807fa8f518e0138f0a8043dfc3315Jason MolendaUnwindTable::GetUncachedFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc) 1165b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda{ 1175b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda FuncUnwindersSP no_unwind_found; 1185b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda Initialize(); 1195b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda 1205b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda AddressRange range; 1215b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, false, range) || !range.GetBaseAddress().IsValid()) 1225b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda { 1235b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda // Does the eh_frame unwind info has a function bounds for this addr? 1245b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda if (m_eh_frame == NULL || !m_eh_frame->GetAddressRange (addr, range)) 1255b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda { 1265b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda return no_unwind_found; 1275b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda } 1285b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda } 1295b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda 1305b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, m_assembly_profiler, range)); 1315b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda return func_unwinder_sp; 1325b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda} 1335b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda 1345b0afcceea3807fa8f518e0138f0a8043dfc3315Jason Molenda 135e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Claytonvoid 136e2f90647b93b0f44c0222da8d995dfe267499f9cGreg ClaytonUnwindTable::Dump (Stream &s) 137e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton{ 13897a19b21dacd9063bb5475812df7781777262198Greg Clayton s.Printf("UnwindTable for '%s':\n", m_object_file.GetFileSpec().GetPath().c_str()); 139e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton const_iterator begin = m_unwinds.begin(); 140e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton const_iterator end = m_unwinds.end(); 141e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton for (const_iterator pos = begin; pos != end; ++pos) 142e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton { 1435f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea s.Printf ("[%u] 0x%16.16" PRIx64 "\n", (unsigned)std::distance (begin, pos), pos->first); 144e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton } 145e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton s.EOL(); 1463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 1473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda 1483a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaDWARFCallFrameInfo * 1493a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaUnwindTable::GetEHFrameInfo () 1503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{ 151e2f90647b93b0f44c0222da8d995dfe267499f9cGreg Clayton Initialize(); 1523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda return m_eh_frame; 1533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda} 154