summaryrefslogtreecommitdiffstats
path: root/source/Symbol/DWARFCallFrameInfo.cpp
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
committeremaste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
commit0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531 (patch)
tree09bc83f73246ee3c7a779605cd0122093d2a8a19 /source/Symbol/DWARFCallFrameInfo.cpp
parent01ee1789d6aa7294e5966a97f8d29387f6f81699 (diff)
downloadFreeBSD-src-0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531.zip
FreeBSD-src-0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531.tar.gz
Import LLDB as of upstream SVN r225923 (git 2b588ecd)
This corresponds with the branchpoint for the 3.6 release. A number of files not required for the FreeBSD build have been removed. Sponsored by: DARPA, AFRL
Diffstat (limited to 'source/Symbol/DWARFCallFrameInfo.cpp')
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp41
1 files changed, 38 insertions, 3 deletions
diff --git a/source/Symbol/DWARFCallFrameInfo.cpp b/source/Symbol/DWARFCallFrameInfo.cpp
index a9da631..78d2623 100644
--- a/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/source/Symbol/DWARFCallFrameInfo.cpp
@@ -218,20 +218,27 @@ DWARFCallFrameInfo::ParseCIE (const dw_offset_t cie_offset)
// FDE, which is the address of a language-specific
// data area (LSDA). The size of the LSDA pointer is
// specified by the pointer encoding used.
- m_cfi_data.GetU8(&offset);
+ cie_sp->lsda_addr_encoding = m_cfi_data.GetU8(&offset);
break;
case 'P':
// Indicates the presence of two arguments in the
- // Augmentation Data of the cie_sp-> The first argument
+ // Augmentation Data of the CIE. The first argument
// is 1-byte and represents the pointer encoding
// used for the second argument, which is the
// address of a personality routine handler. The
// size of the personality routine pointer is
// specified by the pointer encoding used.
+ //
+ // The address of the personality function will
+ // be stored at this location. Pre-execution, it
+ // will be all zero's so don't read it until we're
+ // trying to do an unwind & the reloc has been
+ // resolved.
{
uint8_t arg_ptr_encoding = m_cfi_data.GetU8(&offset);
- m_cfi_data.GetGNUEHPointer(&offset, arg_ptr_encoding, LLDB_INVALID_ADDRESS, LLDB_INVALID_ADDRESS, LLDB_INVALID_ADDRESS);
+ const lldb::addr_t pc_rel_addr = m_section_sp->GetFileAddress();
+ cie_sp->personality_loc = m_cfi_data.GetGNUEHPointer(&offset, arg_ptr_encoding, pc_rel_addr, LLDB_INVALID_ADDRESS, LLDB_INVALID_ADDRESS);
}
break;
@@ -449,11 +456,39 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr
AddressRange range (range_base, m_objfile.GetAddressByteSize(), m_objfile.GetSectionList());
range.SetByteSize (range_len);
+ addr_t lsda_data_file_address = LLDB_INVALID_ADDRESS;
+
if (cie->augmentation[0] == 'z')
{
uint32_t aug_data_len = (uint32_t)m_cfi_data.GetULEB128(&offset);
+ if (aug_data_len != 0 && cie->lsda_addr_encoding != DW_EH_PE_omit)
+ {
+ offset_t saved_offset = offset;
+ lsda_data_file_address = m_cfi_data.GetGNUEHPointer(&offset, cie->lsda_addr_encoding, pc_rel_addr, text_addr, data_addr);
+ if (offset - saved_offset != aug_data_len)
+ {
+ // There is more in the augmentation region than we know how to process;
+ // don't read anything.
+ lsda_data_file_address = LLDB_INVALID_ADDRESS;
+ }
+ offset = saved_offset;
+ }
offset += aug_data_len;
}
+ Address lsda_data;
+ Address personality_function_ptr;
+
+ if (lsda_data_file_address != LLDB_INVALID_ADDRESS && cie->personality_loc != LLDB_INVALID_ADDRESS)
+ {
+ m_objfile.GetModule()->ResolveFileAddress (lsda_data_file_address, lsda_data);
+ m_objfile.GetModule()->ResolveFileAddress (cie->personality_loc, personality_function_ptr);
+ }
+
+ if (lsda_data.IsValid() && personality_function_ptr.IsValid())
+ {
+ unwind_plan.SetLSDAAddress (lsda_data);
+ unwind_plan.SetPersonalityFunctionPtr (personality_function_ptr);
+ }
uint32_t reg_num = 0;
int32_t op_offset = 0;
OpenPOWER on IntegriCloud