Read DWARF type entries as TARGET2 values
Under the ARM EHABI, type information is encoded as a TARGET2 value,
rather than a DWARF pointer.
For the kernel ELF object, we have a ttype_encoding of DW_EH_PE_absptr,
which we combine with DW_EH_PE_pcrel when reading the type info.
For non-null pointers, this is equivalent to TARGET2 - we read a 32bit
value, and then use it as an offset from the current DWARF info. However,
null pointers should *not* apply an offset, and should instead return 0
directly.
An alternative fix here would be to change read_encoded_pointer_with_base
to skip adding base/original_ptr when reading 0. This is what GCC
does[^1], but feels a more dangerous change.
[^1]: 2a77afa0ee/libgcc/unwind-pe.h (L265)
This commit is contained in:
parent
63157588bb
commit
1be126606d
@ -75,17 +75,23 @@ unsafe fn get_ttype_entry(
|
|||||||
ttype_base: usize,
|
ttype_base: usize,
|
||||||
ttype: *const u8,
|
ttype: *const u8,
|
||||||
) -> Result<Option<*const u8>, ()> {
|
) -> Result<Option<*const u8>, ()> {
|
||||||
|
if encoding != DW_EH_PE_absptr {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
let i = (offset * size_of_encoded_value(encoding)) as isize;
|
let i = (offset * size_of_encoded_value(encoding)) as isize;
|
||||||
read_encoded_pointer_with_base(
|
|
||||||
&mut DwarfReader::new(ttype.offset(-i)),
|
// Read in a target2 value. See "Personality routine exception-handling table
|
||||||
// the DW_EH_PE_pcrel is a hack.
|
// entries" in the ehabi32 spec, and the ARM_EHABI version of `get_shim_type_info`
|
||||||
// It seems that the default encoding is absolute, but we have to take reallocation into
|
// in LLVM's libcxxabi/src/cxa_personality.cpp.
|
||||||
// account. Unsure if we can fix this in the compiler setting or if this would be affected
|
let mut reader = DwarfReader::new(ttype.offset(-i));
|
||||||
// by updating the compiler
|
let original_ptr = reader.ptr;
|
||||||
encoding | DW_EH_PE_pcrel,
|
let offset = reader.read::<usize>();
|
||||||
ttype_base,
|
if (offset == 0) {
|
||||||
)
|
Ok(None)
|
||||||
.map(|v| (v != ttype_base).then(|| v as *const u8))
|
} else {
|
||||||
|
Ok(Some(original_ptr.add(offset)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn find_eh_action(
|
pub unsafe fn find_eh_action(
|
||||||
|
Loading…
Reference in New Issue
Block a user