Browse Source

Usage code for finding CFA

master
A.Olokhtonov 3 years ago
parent
commit
010d102d9e
  1. 52
      eh_frame.c
  2. 13
      elf_dwarf.h
  3. 2
      main.c
  4. 17
      util.c

52
eh_frame.c

@ -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)
{
} }

13
elf_dwarf.h

@ -641,7 +641,7 @@ struct dwarf_line_number_state {
u32 discriminator; u32 discriminator;
}; };
struct dwarf_cie_header { struct dwarf_cie {
u32 length; u32 length;
u8 version; u8 version;
u32 code_alignment; u32 code_alignment;
@ -649,20 +649,25 @@ struct dwarf_cie_header {
u32 return_address_register; u32 return_address_register;
u32 augmentation_data_length; u32 augmentation_data_length;
u8 *augmentation_data; u8 *augmentation_data;
u8 *instructions;
int has_z; int has_z;
enum dwarf_cie_pointer_format pointer_format; enum dwarf_cie_pointer_format pointer_format;
enum dwarf_cie_pointer_application pointer_application; enum dwarf_cie_pointer_application pointer_application;
u8 pointer_indirect; u8 pointer_indirect;
}; };
struct dwarf_fde_header { struct dwarf_fde {
u32 length; u32 length;
u64 optional_length; u64 optional_length;
struct dwarf_cie_header *cie; struct dwarf_cie *cie;
u64 low_pc; u64 low_pc;
u64 high_pc; u64 high_pc;
u32 augmentation_data_length; u32 augmentation_data_length;
u8 *augmentation_data; u8 *augmentation_data;
u8 *instructions;
};
struct dwarf_regset {
s64 cfa;
}; };

2
main.c

@ -1,8 +1,8 @@
#include "common.h" #include "common.h"
#include "util.c"
#include "dwarf.c" #include "dwarf.c"
#include "eh_frame.c" #include "eh_frame.c"
#include "util.c"
#include "command.c" #include "command.c"
int int

17
util.c

@ -298,12 +298,17 @@ get_function_around_pc(struct mi_process proc, u64 pc)
return(0); return(0);
} }
#if 0
static u64 static u64
get_cfa_at_pc(struct mi_process proc, u64 pc) get_cfa_at_pc(struct mi_process proc, u64 pc)
{ {
u64 *at = eh_frame_find_fde(proc, pc); struct dwarf_fde *fde = eh_frame_find_fde(proc, pc);
struct dwarf_regset regs = eh_frame_init(at); if (!fde) {
u64 result = eh_frame_find_pc(at, regs, pc); DIE("could not find FDE for pc!\n");
} }
#endif
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);
}
Loading…
Cancel
Save