From 010d102d9ec0fcf92401efc3868471baea03f12d Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Sat, 24 Jul 2021 15:53:15 +0300 Subject: [PATCH] Usage code for finding CFA --- eh_frame.c | 52 +++++++++++++++++++++++++++++++--------------------- elf_dwarf.h | 13 +++++++++---- main.c | 2 +- util.c | 17 +++++++++++------ 4 files changed, 52 insertions(+), 32 deletions(-) diff --git a/eh_frame.c b/eh_frame.c index dcb02aa..0a768cd 100644 --- a/eh_frame.c +++ b/eh_frame.c @@ -200,7 +200,7 @@ iterate_call_frame_instructions(u8 *data, u64 to_read) } 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->version = *data++; @@ -261,7 +261,7 @@ read_one_cie(struct dwarf_cie_header *header, u64 length, u8 *data, u8 *original } 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; 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) { case DW_EH_PE_pcrel: { *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; } - 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: { - 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 -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.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); 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; } - struct dwarf_cie_header hh = { 0 }; data += iterate_call_frame_instructions(data, header.length - (data - original_data - 4)); return(data - original_data); } 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; u64 length; @@ -460,7 +447,7 @@ static void parse_eh_frame(struct mi_process proc) { 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; @@ -471,4 +458,27 @@ parse_eh_frame(struct mi_process proc) 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) +{ } \ No newline at end of file diff --git a/elf_dwarf.h b/elf_dwarf.h index a9a411e..d0d560a 100644 --- a/elf_dwarf.h +++ b/elf_dwarf.h @@ -641,7 +641,7 @@ struct dwarf_line_number_state { u32 discriminator; }; -struct dwarf_cie_header { +struct dwarf_cie { u32 length; u8 version; u32 code_alignment; @@ -649,20 +649,25 @@ struct dwarf_cie_header { u32 return_address_register; u32 augmentation_data_length; u8 *augmentation_data; + u8 *instructions; int has_z; - enum dwarf_cie_pointer_format pointer_format; enum dwarf_cie_pointer_application pointer_application; u8 pointer_indirect; }; -struct dwarf_fde_header { +struct dwarf_fde { u32 length; u64 optional_length; - struct dwarf_cie_header *cie; + struct dwarf_cie *cie; u64 low_pc; u64 high_pc; u32 augmentation_data_length; u8 *augmentation_data; + u8 *instructions; +}; + +struct dwarf_regset { + s64 cfa; }; \ No newline at end of file diff --git a/main.c b/main.c index 3dd40c0..e3ac23c 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,8 @@ #include "common.h" -#include "util.c" #include "dwarf.c" #include "eh_frame.c" +#include "util.c" #include "command.c" int diff --git a/util.c b/util.c index e3c0a92..6affb8c 100644 --- a/util.c +++ b/util.c @@ -298,12 +298,17 @@ get_function_around_pc(struct mi_process proc, u64 pc) return(0); } -#if 0 static u64 get_cfa_at_pc(struct mi_process proc, u64 pc) { - u64 *at = eh_frame_find_fde(proc, pc); - struct dwarf_regset regs = eh_frame_init(at); - u64 result = eh_frame_find_pc(at, regs, pc); -} -#endif \ No newline at end of file + struct dwarf_fde *fde = eh_frame_find_fde(proc, pc); + if (!fde) { + DIE("could not find FDE for pc!\n"); + } + + struct dwarf_regset regs = eh_frame_init_registers(proc, fde->cie); + regs = eh_frame_find_pc(proc, fde, regs, pc); + u64 cfa = eh_frame_compute_cfa(proc, regs); + + return(cfa); +} \ No newline at end of file