[ngunwind] Don't use the last words of EH frame header as table
Both `dwarf_find_unwind_table` and `dwarf_as_find_unwind_table` have an offsetting bug that causes them to set di.u.rti.table_data to point into the EH frame header, rather than to the entries. This results in two different bugs: 1) Because the table is pointing to the eh_frame_ptr word in the header, a small value, basically any PC will always appear to be found. However, no FDE actually exists for that PC and so we fail to unwind PCs that aren't described by any FDEs instead of failing to find the PC and falling back to frame-pointer-based unwinding. 2) Because the table is pointing into eh_frame_ptr, but the table_len is correct, the final FDE cannot be resolved for PCs that are valid, but are described by the final FDE. Instead, the penultimate FDE will be chosen, leading to erroneous results. The calls to `dwarf_read_encoded_pointer` have the side-effect of advancing the `addr` argument, however this lives in a different address space. The table data is indeed located at the load_base + section offset + header length -- only, the dwarf_eh_frame_hdr struct doesn't include the `eh_frame_ptr` and `fde_count` fields. So we end up with the table_data pointing to `eh_frame_ptr` instead of the first table entry. This patch solves the problem by using the last read address (which should be at the end of the optional `eh_frame_ptr` and `fde_count`) minus the address of the header as the offset. Bug: TC-306 #done Test: manual Change-Id: Iaf4f0c45b02a2c7f4bacd9863887038401745c8e
Loading
Please register or sign in to comment