diff options
author | emaste <emaste@FreeBSD.org> | 2015-02-06 21:38:51 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2015-02-06 21:38:51 +0000 |
commit | 0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531 (patch) | |
tree | 09bc83f73246ee3c7a779605cd0122093d2a8a19 /source/Symbol/DWARFCallFrameInfo.cpp | |
parent | 01ee1789d6aa7294e5966a97f8d29387f6f81699 (diff) | |
download | FreeBSD-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.cpp | 41 |
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; |