ld: Fix remapping of FDEs with multiple CFIs

This commit is contained in:
David Mak 2023-10-20 12:10:44 +08:00
parent e1487ed335
commit aa92778363
1 changed files with 14 additions and 7 deletions

View File

@ -304,13 +304,14 @@ impl<'a> EH_Frame<'a> {
let mut next_fde_reader = DwarfReader::new(reader.slice, reader.virt_addr); let mut next_fde_reader = DwarfReader::new(reader.slice, reader.virt_addr);
next_fde_reader.offset(length as i32); next_fde_reader.offset(length as i32);
// Skip CIE pointer offset // Only parse FDEs, indicated by its CIE pointer being non-zero
reader.read_u32(); let cie_ptr = reader.read_u32();
if cie_ptr != 0 {
// Parse PC Begin using the encoding scheme mentioned in the CIE // Parse PC Begin using the encoding scheme mentioned in the CIE
let pc_begin = read_encoded_pointer_with_pc(&mut reader, self.fde_pointer_encoding)?; let pc_begin = read_encoded_pointer_with_pc(&mut reader, self.fde_pointer_encoding)?;
callback(pc_begin as u32, fde_virt_addr); callback(pc_begin as u32, fde_virt_addr);
}
reader = next_fde_reader; reader = next_fde_reader;
} }
@ -382,11 +383,17 @@ impl<'a> EH_Frame_Hdr<'a> {
if entry_length == 0 || entry_length == 0xFFFFFFFF { if entry_length == 0 || entry_length == 0xFFFFFFFF {
unimplemented!() unimplemented!()
} }
if reader.read_u32() != 0 {
// This slot stores the CIE ID (for CIE)/CIE Pointer (for FDE).
// This value must be non-zero for FDEs.
let cie_ptr = reader.read_u32();
if cie_ptr != 0 {
fde_count += 1; fde_count += 1;
} }
reader.offset(entry_length as i32 - mem::size_of::<u32>() as i32) reader.offset(entry_length as i32 - mem::size_of::<u32>() as i32)
} }
12 + fde_count * 8 12 + fde_count * 8
} }
} }