Skip to content

Commit 7e2a813

Browse files
committed
Show demangled linkage name if avaiable
Use c++filt program to demangle the linkage name.
1 parent f610555 commit 7e2a813

File tree

3 files changed

+104
-5
lines changed

3 files changed

+104
-5
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ CFLAGS += -g -Wno-deprecated-declarations
66

77
all: dwarview
88

9-
dwarview: main.c dwarview.c
9+
dwarview: main.c dwarview.c demangle.c
1010
gcc -o $@ $(CFLAGS) $^ $(LDFLAGS)
1111

1212
clean:

demangle.c

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Simple demangler interface using the external `c++filt` program.
3+
*/
4+
#include <stdio.h>
5+
#include <unistd.h>
6+
#include <string.h>
7+
#include <stdbool.h>
8+
9+
struct demangler {
10+
int in;
11+
int out;
12+
bool ok;
13+
};
14+
15+
static struct demangler d;
16+
17+
/* popen() doesn't provide bidirectional streams, do it manually */
18+
void setup_demangler(void)
19+
{
20+
int p1[2], p2[2];
21+
22+
d.ok = false;
23+
24+
if (pipe(p1) < 0 || pipe(p2) < 0)
25+
return;
26+
27+
switch (fork()) {
28+
case -1: /* error */
29+
return;
30+
31+
case 0: /* child */
32+
dup2(p1[0], STDIN_FILENO);
33+
dup2(p2[1], STDOUT_FILENO);
34+
35+
close(p1[0]);
36+
close(p1[1]);
37+
close(p2[0]);
38+
close(p2[1]);
39+
40+
execlp("c++filt", NULL);
41+
break;
42+
43+
default: /* parent */
44+
d.in = p1[1];
45+
d.out = p2[0];
46+
47+
close(p1[0]);
48+
close(p2[1]);
49+
50+
d.ok = true;
51+
break;
52+
}
53+
}
54+
55+
void finish_demangler(void)
56+
{
57+
if (d.ok) {
58+
close(d.in);
59+
close(d.out);
60+
}
61+
62+
d.ok = false;
63+
}
64+
65+
bool demangler_enabled(void)
66+
{
67+
return d.ok;
68+
}
69+
70+
int demangle(const char *input, char *output, int outlen)
71+
{
72+
int ret;
73+
int len = strlen(input);
74+
char flush = '\n';
75+
76+
if (!d.ok) {
77+
memcpy(output, input, len+1);
78+
return 0;
79+
}
80+
81+
write(d.in, input, len);
82+
write(d.in, &flush, 1);
83+
84+
ret = read(d.out, output, outlen);
85+
output[ret - 1] = '\0';
86+
87+
return ret;
88+
}

main.c

+15-4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ struct search_item {
9393
static void add_contents(GtkBuilder *builder, char *filename);
9494
static void destroy_item(gpointer data);
9595

96+
extern void setup_demangler(void);
97+
extern void finish_demangler(void);
98+
extern bool demangler_enabled(void);
99+
extern int demangle(const char *input, char *output, int outlen);
100+
96101
/* Get a Dwarf from offline image */
97102
static int open_dwarf_file(char *path)
98103
{
@@ -836,14 +841,16 @@ static const char *die_name(Dwarf_Die *die)
836841
Dwarf_Die origin;
837842
Dwarf_Attribute attr;
838843
const char *name;
839-
840-
name = dwarf_diename(&pos);
841-
if (name)
842-
return name;
844+
static char buf[4096];
843845

844846
while (true) {
845847
if (dwarf_attr(&pos, DW_AT_name, &attr))
846848
return dwarf_formstring(&attr);
849+
/* use linkage name only if it can demangle the name */
850+
if (dwarf_attr(&pos, DW_AT_linkage_name, &attr) && demangler_enabled()) {
851+
demangle(dwarf_formstring(&attr), buf, sizeof(buf));
852+
return buf;
853+
}
847854

848855
if (dwarf_attr(&pos, DW_AT_abstract_origin, &attr) == NULL &&
849856
dwarf_attr(&pos, DW_AT_specification, &attr) == NULL &&
@@ -1080,6 +1087,8 @@ int main(int argc, char *argv[])
10801087
return 1;
10811088
}
10821089

1090+
setup_demangler();
1091+
10831092
window = GTK_WIDGET(gtk_builder_get_object(builder, "root_window"));
10841093
gtk_widget_show(window);
10851094

@@ -1099,5 +1108,7 @@ int main(int argc, char *argv[])
10991108

11001109
gtk_main();
11011110

1111+
finish_demangler();
1112+
11021113
return 0;
11031114
}

0 commit comments

Comments
 (0)