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

13
elf_dwarf.h

@ -641,7 +641,7 @@ struct dwarf_line_number_state { @@ -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 { @@ -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;
};

2
main.c

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

17
util.c

@ -298,12 +298,17 @@ get_function_around_pc(struct mi_process proc, u64 pc) @@ -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
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);
}
Loading…
Cancel
Save