summaryrefslogtreecommitdiff
path: root/source/ucli
diff options
context:
space:
mode:
authorzy <[email protected]>2023-12-07 03:46:57 -0500
committerzy <[email protected]>2023-12-07 03:46:57 -0500
commit8fdaeaeadc0d0c88c4e5b89bdce93f82e9e6bf32 (patch)
treeeabdfe498607542f091bcd5ff930b86ca6d195e0 /source/ucli
parent806356363cae90bd3602ecc3564ebcbcbdc1dbaf (diff)
dwarf
Diffstat (limited to 'source/ucli')
-rw-r--r--source/ucli/Makefile2
-rw-r--r--source/ucli/elf.cc50
2 files changed, 51 insertions, 1 deletions
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 <sys/utsname.h>
#include <unistd.h>
+#include <dwarf.h>
+#include <elfutils/libdw.h>
+
#define NS_NAME_LEN 128
struct sym_section_ctx {
@@ -224,6 +227,45 @@ static void get_all_symbols(std::set<symbol> &ss, symbol_sections_ctx *si,
__get_plt_symbol(ss, si, elf);
}
+static void get_debug_symbols(std::set<symbol>& 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<symbol> &ss, const char *path) {
static int first_init = 0;
@@ -331,6 +373,14 @@ bool get_symbol_from_elf(std::set<symbol> &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