|  |  | @ -1,5 +1,6 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | static u64 |  |  |  | static u64 | 
			
		
	
		
		
			
				
					
					|  |  |  | iterate_call_frame_instructions(u8 *data, u64 to_read) |  |  |  | iterate_call_frame_instructions(struct dwarf_cie *cie, u8 *data, u64 to_read,  | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                 struct mi_registers *regs, struct dwarf_regset *regset, u64 location) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     u64 read = 0; |  |  |  |     u64 read = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
	
		
		
			
				
					|  |  | @ -12,13 +13,15 @@ iterate_call_frame_instructions(u8 *data, u64 to_read) | 
			
		
	
		
		
			
				
					
					|  |  |  |          |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (high_two == DW_CFA_advance_loc) { |  |  |  |         if (high_two == DW_CFA_advance_loc) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             u8 delta = low_six; |  |  |  |             u8 delta = low_six; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (regset) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 regset->loc += delta * cie->code_alignment; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } else if (high_two == DW_CFA_offset) { |  |  |  |         } else if (high_two == DW_CFA_offset) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             u8 reg = low_six; |  |  |  |             u8 reg = low_six; | 
			
		
	
		
		
			
				
					
					|  |  |  |             u32 factored_offset; |  |  |  |             u32 factored_offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |             increment += decode_leb128(data, &factored_offset); |  |  |  |             increment += decode_leb128(data, &factored_offset); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } else if (high_two == DW_CFA_restore) { |  |  |  |         } else if (high_two == DW_CFA_restore) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             u8 reg = low_six; |  |  |  |             u8 reg = low_six; | 
			
		
	
		
		
			
				
					
					|  |  |  |              |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } else if (high_two == 0) { |  |  |  |         } else if (high_two == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             switch (low_six) { |  |  |  |             switch (low_six) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 case DW_CFA_nop: { |  |  |  |                 case DW_CFA_nop: { | 
			
		
	
	
		
		
			
				
					|  |  | @ -29,6 +32,9 @@ iterate_call_frame_instructions(u8 *data, u64 to_read) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     u64 address; |  |  |  |                     u64 address; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     memcpy(&address, data, 8); |  |  |  |                     memcpy(&address, data, 8); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     increment = 8; |  |  |  |                     increment = 8; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if (regset) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         regset->loc = address; // TODO: encoding??
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |                  | 
			
		
	
	
		
		
			
				
					|  |  | @ -36,6 +42,9 @@ iterate_call_frame_instructions(u8 *data, u64 to_read) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     u8 advance; |  |  |  |                     u8 advance; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     memcpy(&advance, data, 1); |  |  |  |                     memcpy(&advance, data, 1); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     increment = 1; |  |  |  |                     increment = 1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if (regset) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         regset->loc += advance * cie->code_alignment; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |                  | 
			
		
	
	
		
		
			
				
					|  |  | @ -43,6 +52,9 @@ iterate_call_frame_instructions(u8 *data, u64 to_read) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     u16 advance; |  |  |  |                     u16 advance; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     memcpy(&advance, data, 2); |  |  |  |                     memcpy(&advance, data, 2); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     increment = 2; |  |  |  |                     increment = 2; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if (regset) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         regset->loc += advance * cie->code_alignment; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |                  | 
			
		
	
	
		
		
			
				
					|  |  | @ -50,6 +62,9 @@ iterate_call_frame_instructions(u8 *data, u64 to_read) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     u32 advance; |  |  |  |                     u32 advance; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     memcpy(&advance, data, 4); |  |  |  |                     memcpy(&advance, data, 4); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     increment = 4; |  |  |  |                     increment = 4; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if (regset) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         regset->loc += advance * cie->code_alignment; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |                  | 
			
		
	
	
		
		
			
				
					|  |  | @ -98,20 +113,35 @@ iterate_call_frame_instructions(u8 *data, u64 to_read) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 case DW_CFA_def_cfa: { |  |  |  |                 case DW_CFA_def_cfa: { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     u32 reg; |  |  |  |                     u32 reg; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     u32 nonfactored_offset; |  |  |  |                     u32 nonfactored_offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                      | 
			
		
	
		
		
			
				
					
					|  |  |  |                     increment += decode_leb128(data, ®); |  |  |  |                     increment += decode_leb128(data, ®); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     increment += decode_leb128(data, &nonfactored_offset); |  |  |  |                     increment += decode_leb128(data + increment, &nonfactored_offset); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if (regset) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         regset->cfa_offset = nonfactored_offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         regset->cfa_register = reg; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                      | 
			
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |                  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 case DW_CFA_def_cfa_register: { |  |  |  |                 case DW_CFA_def_cfa_register: { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     u32 reg; |  |  |  |                     u32 reg; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     increment += decode_leb128(data, ®); |  |  |  |                     increment += decode_leb128(data, ®); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if (regset) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         regset->cfa_register = reg; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                      | 
			
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |                  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 case DW_CFA_def_cfa_offset: { |  |  |  |                 case DW_CFA_def_cfa_offset: { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     u32 offset; |  |  |  |                     u32 offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     increment += decode_leb128(data, &offset); |  |  |  |                     increment += decode_leb128(data, &offset); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if (regset) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         regset->cfa_offset = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |                  | 
			
		
	
	
		
		
			
				
					|  |  | @ -188,6 +218,11 @@ iterate_call_frame_instructions(u8 *data, u64 to_read) | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |          |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (location && regset->loc > location) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             regset->cfa = regset->system[regset->cfa_register] + regset->cfa_offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |         data += increment; |  |  |  |         data += increment; | 
			
		
	
		
		
			
				
					
					|  |  |  |         read += increment + 1; |  |  |  |         read += increment + 1; | 
			
		
	
		
		
			
				
					
					|  |  |  |          |  |  |  |          | 
			
		
	
	
		
		
			
				
					|  |  | @ -236,8 +271,10 @@ read_one_cie(struct dwarf_cie *header, u64 length, u8 *data, u8 *original_data) | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     header->has_z = has_z; |  |  |  |     header->has_z = has_z; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     header->instructions = data; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     header->instructions_length = header->length - (data - original_data - 4); | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     data += iterate_call_frame_instructions(data, header->length - (data - original_data - 4)); |  |  |  |     data += iterate_call_frame_instructions(header, data, header->instructions_length, 0, 0, 0); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (has_R) { |  |  |  |     if (has_R) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         // NOTE(aolo2): this shit is undocumented. Best sources I could find:
 |  |  |  |         // NOTE(aolo2): this shit is undocumented. Best sources I could find:
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -372,14 +409,13 @@ read_encoded_pointer(struct mi_process proc, struct dwarf_cie *cie, u8 *data, u6 | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static u64 |  |  |  | static u64 | 
			
		
	
		
		
			
				
					
					|  |  |  | read_one_fde(struct mi_process proc, struct dwarf_cie *cie, u64 length, u32 cie_offset, u8 *data, u8 *original_data) |  |  |  | read_one_fde(struct mi_process proc, struct dwarf_cie *cie, u64 length, u8 *data, u8 *original_data, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |              struct dwarf_fde *header) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     struct dwarf_fde header = { 0 }; |  |  |  |     header->length = length; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |     header->cie = *cie; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     header.length = length; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     header.cie = (struct dwarf_cie *) (data - 4 - cie_offset); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     u32 pointer_size = read_encoded_pointer(proc, cie, data, &header.low_pc); |  |  |  |     u32 pointer_size = read_encoded_pointer(proc, cie, data, &header->low_pc); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     data += pointer_size; |  |  |  |     data += pointer_size; | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     u64 fde_length = 0; |  |  |  |     u64 fde_length = 0; | 
			
		
	
	
		
		
			
				
					|  |  | @ -394,21 +430,24 @@ read_one_fde(struct mi_process proc, struct dwarf_cie *cie, u64 length, u32 cie_ | 
			
		
	
		
		
			
				
					
					|  |  |  |         data += 8; |  |  |  |         data += 8; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     header.high_pc = header.low_pc + fde_length; |  |  |  |     header->high_pc = header->low_pc + fde_length; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (cie->has_z) { |  |  |  |     if (cie->has_z) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         data += decode_leb128(data, &header.augmentation_data_length); |  |  |  |         data += decode_leb128(data, &header->augmentation_data_length); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         header.augmentation_data = data; |  |  |  |         header->augmentation_data = data; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         data += header.augmentation_data_length; |  |  |  |         data += header->augmentation_data_length; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     data += iterate_call_frame_instructions(data, header.length - (data - original_data - 4)); |  |  |  |     header->instructions = data; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     header->instructions_length = header->length - (data - original_data - 4); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     data += iterate_call_frame_instructions(cie, data, header->instructions_length, 0, 0, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     return(data - original_data); |  |  |  |     return(data - original_data); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static u64 |  |  |  | static u64 | 
			
		
	
		
		
			
				
					
					|  |  |  | read_one_call_frame_record(struct mi_process proc, struct dwarf_cie *last_cie, u8 *data) |  |  |  | read_one_call_frame_record(struct mi_process proc, struct dwarf_cie *last_cie, struct dwarf_fde *last_fde, int *is_cie, u8 *data) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     u8 *original_data = data; |  |  |  |     u8 *original_data = data; | 
			
		
	
		
		
			
				
					
					|  |  |  |     u64 length; |  |  |  |     u64 length; | 
			
		
	
	
		
		
			
				
					|  |  | @ -436,49 +475,76 @@ read_one_call_frame_record(struct mi_process proc, struct dwarf_cie *last_cie, u | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (cie_id == 0) { |  |  |  |     if (cie_id == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         result = read_one_cie(last_cie, length, data, original_data); |  |  |  |         result = read_one_cie(last_cie, length, data, original_data); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         *is_cie = 1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } else { |  |  |  |     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |         result = read_one_fde(proc, last_cie, length, cie_id, data, original_data); |  |  |  |         result = read_one_fde(proc, last_cie, length, data, original_data, last_fde); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         *is_cie = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     return(result); |  |  |  |     return(result); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void |  |  |  | static struct dwarf_fde | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | parse_eh_frame(struct mi_process proc) |  |  |  | eh_frame_find_fde(struct mi_process proc, u64 pc) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     struct elf_section_table_entry_x64 eh_frame = get_section_entry(proc.elf, ".eh_frame"); |  |  |  |     struct elf_section_table_entry_x64 eh_frame = get_section_entry(proc.elf, ".eh_frame"); | 
			
		
	
		
		
			
				
					
					|  |  |  |     struct dwarf_cie last_cie = { 0 }; |  |  |  |     struct dwarf_cie last_cie = { 0 }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     struct dwarf_fde last_fde = { 0 }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     int is_cie = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     u64 read = 0; |  |  |  |     u64 read = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (;;) { |  |  |  |     for (;;) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         u64 size = read_one_call_frame_record(proc, &last_cie, proc.elf + eh_frame.offset_in_file + read); |  |  |  |         u64 size = read_one_call_frame_record(proc, &last_cie, &last_fde, &is_cie, proc.elf + eh_frame.offset_in_file + read); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (!is_cie) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (last_fde.low_pc <= pc && pc < last_fde.high_pc) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 return(last_fde); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |         read += size; |  |  |  |         read += size; | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (read >= eh_frame.size) { |  |  |  |         if (read >= eh_frame.size) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             break; |  |  |  |             break; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  | static struct dwarf_fde * |  |  |  |     last_fde.length = 0; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | eh_frame_find_fde(struct mi_process proc, u64 pc) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return(last_fde); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static struct dwarf_regset |  |  |  | static struct dwarf_regset | 
			
		
	
		
		
			
				
					
					|  |  |  | eh_frame_init_registers(struct mi_process proc, struct dwarf_cie *cie) |  |  |  | eh_frame_init_registers(struct mi_process proc, struct mi_registers regs, struct dwarf_cie cie) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |     struct dwarf_regset regset = { 0 }; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[0]  = regs._sys.rax; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[1]  = regs._sys.rdx; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[2]  = regs._sys.rcx; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[3]  = regs._sys.rbx; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[4]  = regs._sys.rsi; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[5]  = regs._sys.rdi; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[6]  = regs._sys.rbp; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[7]  = regs._sys.rsp; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[8]  = regs._sys.r8; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[9]  = regs._sys.r9; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[10] = regs._sys.r10; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[11] = regs._sys.r11; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[12] = regs._sys.r12; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[13] = regs._sys.r13; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[14] = regs._sys.r14; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.system[15] = regs._sys.r15; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     iterate_call_frame_instructions(&cie, cie.instructions, cie.instructions_length, ®s, ®set, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return(regset); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static struct dwarf_regset |  |  |  | static struct dwarf_regset | 
			
		
	
		
		
			
				
					
					|  |  |  | eh_frame_find_pc(struct mi_process proc, struct dwarf_fde *fde, struct dwarf_regset regs, u64 pc) |  |  |  | eh_frame_find_pc(struct mi_process proc, struct dwarf_fde fde, struct mi_registers regs, struct dwarf_regset regset, u64 pc) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static u64 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | eh_frame_compute_cfa(struct mi_process proc, struct dwarf_regset regs) |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     regset.loc = fde.low_pc; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     iterate_call_frame_instructions(&fde.cie, fde.instructions, fde.instructions_length, ®s, ®set, pc); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return(regset); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } |