|
|
@ -200,7 +200,7 @@ iterate_call_frame_instructions(u8 *data, u64 to_read) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static u64 |
|
|
|
static u64 |
|
|
|
read_one_cie(struct dwarf_cie_header *header, u64 length, u8 *data, u8 *original_data) |
|
|
|
read_one_cie(struct dwarf_cie *header, u64 length, u8 *data, u8 *original_data) |
|
|
|
{ |
|
|
|
{ |
|
|
|
header->length = length; |
|
|
|
header->length = length; |
|
|
|
header->version = *data++; |
|
|
|
header->version = *data++; |
|
|
@ -261,7 +261,7 @@ read_one_cie(struct dwarf_cie_header *header, u64 length, u8 *data, u8 *original |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static u64 |
|
|
|
static u64 |
|
|
|
read_encoded_pointer(struct mi_process proc, struct dwarf_cie_header *cie, u8 *data, u64 *dest) |
|
|
|
read_encoded_pointer(struct mi_process proc, struct dwarf_cie *cie, u8 *data, u64 *dest) |
|
|
|
{ |
|
|
|
{ |
|
|
|
u64 offset = 0; |
|
|
|
u64 offset = 0; |
|
|
|
s64 final_value; |
|
|
|
s64 final_value; |
|
|
@ -338,9 +338,6 @@ read_encoded_pointer(struct mi_process proc, struct dwarf_cie_header *cie, u8 *d |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct mi_registers regs = get_process_registers(proc); |
|
|
|
|
|
|
|
struct mi_function *func = get_function_around_pc(proc, regs.rip - proc.base_address); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (cie->pointer_application) { |
|
|
|
switch (cie->pointer_application) { |
|
|
|
case DW_EH_PE_pcrel: { |
|
|
|
case DW_EH_PE_pcrel: { |
|
|
|
*dest = data - proc.elf + final_value; |
|
|
|
*dest = data - proc.elf + final_value; |
|
|
@ -366,17 +363,8 @@ read_encoded_pointer(struct mi_process proc, struct dwarf_cie_header *cie, u8 *d |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case DW_EH_PE_funcrel: { |
|
|
|
|
|
|
|
if (func) { |
|
|
|
|
|
|
|
*dest = func->low_pc + final_value; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
DIE("could not find function around pc while decoding address!\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: { |
|
|
|
default: { |
|
|
|
DIE("unsupported pointer application: DW_EH_PE_aligned, DW_EH_PE_indirect, or DW_EH_PE_omit\n"); |
|
|
|
DIE("unsupported pointer application: DW_EH_PE_funcrel, DW_EH_PE_aligned, DW_EH_PE_indirect, or DW_EH_PE_omit\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -384,12 +372,12 @@ read_encoded_pointer(struct mi_process proc, struct dwarf_cie_header *cie, u8 *d |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static u64 |
|
|
|
static u64 |
|
|
|
read_one_fde(struct mi_process proc, struct dwarf_cie_header *cie, u64 length, u32 cie_offset, u8 *data, u8 *original_data) |
|
|
|
read_one_fde(struct mi_process proc, struct dwarf_cie *cie, u64 length, u32 cie_offset, u8 *data, u8 *original_data) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct dwarf_fde_header header = { 0 }; |
|
|
|
struct dwarf_fde header = { 0 }; |
|
|
|
|
|
|
|
|
|
|
|
header.length = length; |
|
|
|
header.length = length; |
|
|
|
header.cie = (struct dwarf_cie_header *) (data - 4 - cie_offset); |
|
|
|
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; |
|
|
@ -414,14 +402,13 @@ read_one_fde(struct mi_process proc, struct dwarf_cie_header *cie, u64 length, u |
|
|
|
data += header.augmentation_data_length; |
|
|
|
data += header.augmentation_data_length; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct dwarf_cie_header hh = { 0 }; |
|
|
|
|
|
|
|
data += iterate_call_frame_instructions(data, header.length - (data - original_data - 4)); |
|
|
|
data += iterate_call_frame_instructions(data, header.length - (data - original_data - 4)); |
|
|
|
|
|
|
|
|
|
|
|
return(data - original_data); |
|
|
|
return(data - original_data); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static u64 |
|
|
|
static u64 |
|
|
|
read_one_call_frame_record(struct mi_process proc, struct dwarf_cie_header *last_cie, u8 *data) |
|
|
|
read_one_call_frame_record(struct mi_process proc, struct dwarf_cie *last_cie, u8 *data) |
|
|
|
{ |
|
|
|
{ |
|
|
|
u8 *original_data = data; |
|
|
|
u8 *original_data = data; |
|
|
|
u64 length; |
|
|
|
u64 length; |
|
|
@ -460,7 +447,7 @@ static void |
|
|
|
parse_eh_frame(struct mi_process proc) |
|
|
|
parse_eh_frame(struct mi_process proc) |
|
|
|
{ |
|
|
|
{ |
|
|
|
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_header last_cie = { 0 }; |
|
|
|
struct dwarf_cie last_cie = { 0 }; |
|
|
|
|
|
|
|
|
|
|
|
u64 read = 0; |
|
|
|
u64 read = 0; |
|
|
|
|
|
|
|
|
|
|
@ -471,4 +458,27 @@ parse_eh_frame(struct mi_process proc) |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct dwarf_fde * |
|
|
|
|
|
|
|
eh_frame_find_fde(struct mi_process proc, u64 pc) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct dwarf_regset |
|
|
|
|
|
|
|
eh_frame_init_registers(struct mi_process proc, struct dwarf_cie *cie) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct dwarf_regset |
|
|
|
|
|
|
|
eh_frame_find_pc(struct mi_process proc, struct dwarf_fde *fde, struct dwarf_regset regs, u64 pc) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static u64 |
|
|
|
|
|
|
|
eh_frame_compute_cfa(struct mi_process proc, struct dwarf_regset regs) |
|
|
|
|
|
|
|
{ |
|
|
|
} |
|
|
|
} |