From 8fdaeaeadc0d0c88c4e5b89bdce93f82e9e6bf32 Mon Sep 17 00:00:00 2001 From: zy Date: Thu, 7 Dec 2023 03:46:57 -0500 Subject: [PATCH] dwarf --- source/ucli/Makefile | 2 +- source/ucli/elf.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/source/ucli/Makefile b/source/ucli/Makefile index b94ef76..7b5fd9a 100644 --- a/source/ucli/Makefile +++ b/source/ucli/Makefile @@ -5,7 +5,7 @@ OBJECTS=$(SOURCES:.cc=.o) CFLAGS=-g -O0 INCLUDES=-I/usr/include/elf -LIBS=-lunwind-x86_64 -lunwind -lelf +LIBS=-lunwind-x86_64 -lunwind -lelf -ldwarf -ldw %.o: %.cc $(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@ diff --git a/source/ucli/elf.cc b/source/ucli/elf.cc index 7be03f1..b0c1d70 100644 --- a/source/ucli/elf.cc +++ b/source/ucli/elf.cc @@ -8,6 +8,9 @@ #include #include +#include +#include + #define NS_NAME_LEN 128 struct sym_section_ctx { @@ -224,6 +227,45 @@ static void get_all_symbols(std::set &ss, symbol_sections_ctx *si, __get_plt_symbol(ss, si, elf); } +static void get_debug_symbols(std::set& ss, Dwarf* dw) { + Dwarf_Off die_offset = 0, next_offset; + size_t header_size; + while (dwarf_nextcu(dw, die_offset, &next_offset, &header_size, NULL, NULL, NULL) == 0) { + Dwarf_Die cudie; + if (dwarf_offdie(dw, die_offset + header_size, &cudie) == NULL) { + continue; + } + + Dwarf_Die die; + if (dwarf_child(&cudie, &die) != 0) { + continue; + } + + do { + const char* die_name = dwarf_diename(&die); + if (!die_name) { + continue; + } + + Dwarf_Attribute attr_mem; + Dwarf_Attribute* attr = dwarf_attr(&die, DW_AT_low_pc, &attr_mem); + if (attr) { + Dwarf_Addr low_pc; + if (dwarf_formaddr(attr, &low_pc) == 0) { + symbol s; + s.name = die_name; + s.start = low_pc; + s.end = s.start; // You need to find the high_pc to set the end. + + ss.insert(s); + } + } + } while (dwarf_siblingof(&die, &die) == 0); + + die_offset = next_offset; + } +} + bool get_symbol_from_elf(std::set &ss, const char *path) { static int first_init = 0; @@ -331,6 +373,14 @@ bool get_symbol_from_elf(std::set &ss, const char *path) { get_all_symbols(ss, &si, elf); elf_end(elf); + + // After getting all symbols from .symtab and .dynsym + Dwarf *dw = dwarf_begin(fd, DWARF_C_READ); + if (dw) { + get_debug_symbols(ss, dw); + dwarf_end(dw); + } + close(fd); return true; } \ No newline at end of file