From aa9277836377050126fc4e16bfca7c19a3ee23a3 Mon Sep 17 00:00:00 2001 From: David Mak Date: Fri, 20 Oct 2023 12:10:44 +0800 Subject: [PATCH] ld: Fix remapping of FDEs with multiple CFIs --- nac3ld/src/dwarf.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/nac3ld/src/dwarf.rs b/nac3ld/src/dwarf.rs index cbb45bcc..ee6d4b6e 100644 --- a/nac3ld/src/dwarf.rs +++ b/nac3ld/src/dwarf.rs @@ -304,13 +304,14 @@ impl<'a> EH_Frame<'a> { let mut next_fde_reader = DwarfReader::new(reader.slice, reader.virt_addr); next_fde_reader.offset(length as i32); - // Skip CIE pointer offset - reader.read_u32(); + // Only parse FDEs, indicated by its CIE pointer being non-zero + let cie_ptr = reader.read_u32(); + if cie_ptr != 0 { + // 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)?; - // 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)?; - - callback(pc_begin as u32, fde_virt_addr); + callback(pc_begin as u32, fde_virt_addr); + } reader = next_fde_reader; } @@ -382,11 +383,17 @@ impl<'a> EH_Frame_Hdr<'a> { if entry_length == 0 || entry_length == 0xFFFFFFFF { 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; } + reader.offset(entry_length as i32 - mem::size_of::() as i32) } + 12 + fde_count * 8 } }