[PATCH] HACK: port dwarf_loader to dwarf_get_units

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a trivial sample to demonstrate that loading dwarf-4, dwarf-5,
with and without split-dwarf works.

Observe that before this patch there are valgrind leaks.
Obverse that there are even more valgrind leaks after this patch.

But it does make things load all 4 sample builds, and present the same
sample pahole output for all of them.

Abosolutely no idea what pointer_size variable is, or what it was in
dwarf_next_unit() or what it is in dwarf_cu_die(), or if that's what
cu__new() needs.

Separtely if one compiles linux kernel with dwarf-5 and split-dwarf,
and tries to run this build of pahole, even on like a trivial kernel
module it segfaults eventually when trying to
ftype__recode_dwarf_types, because eventually pos becomes NULL and
NULL dereference happens. So something about the created cus is not
quite right. Strongly suspecting that pointer_size actually matters
and possibly loaidng subdie needs to be properly accounted for.

NACKed-by: Dimitri John Ledkov <dimitri.ledkov@xxxxxxxxxxxxx>
---
 dwarf_loader.c | 31 ++++++++++++-------------------
 dwarves.c      |  8 ++++++++
 sample.c       | 10 ++++++++++
 sample.sh      | 18 ++++++++++++++++++
 4 files changed, 48 insertions(+), 19 deletions(-)
 create mode 100644 sample.c
 create mode 100755 sample.sh

diff --git a/dwarf_loader.c b/dwarf_loader.c
index ccf31943bb..84aebed7c5 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -2823,13 +2823,6 @@ static int die__process(Dwarf_Die *die, struct cu *cu, struct conf_load *conf)
 	const uint16_t tag = dwarf_tag(die);
 
 	if (tag == DW_TAG_skeleton_unit) {
-		static bool warned;
-
-		if (!warned) {
-			fprintf(stderr, "WARNING: DW_TAG_skeleton_unit used, please look for a .dwo file and use it instead.\n"
-					"         A future version of pahole will support do this automagically.\n");
-			warned = true;
-		}
 		return 0; // so that other units can be processed
 	}
 
@@ -3068,20 +3061,22 @@ static int __cus__load_debug_types(struct conf_load *conf, Dwfl_Module *mod, Dwa
 				   const char *filename, const unsigned char *build_id,
 				   int build_id_len, struct cu **cup, struct dwarf_cu *dcup)
 {
-	Dwarf_Off off = 0, noff, type_off;
-	size_t cuhl;
 	uint8_t pointer_size, offset_size;
-	uint64_t signature;
+
+	Dwarf_CU *dgu_cu = NULL;
+	Dwarf_Die result;
+	Dwarf_Die cudie;
+	Dwarf_Die subdie;
 
 	*cup = NULL;
 
-	while (dwarf_next_unit(dw, off, &noff, &cuhl, NULL, NULL, &pointer_size,
-			       &offset_size, &signature, &type_off)
-		== 0) {
+	while (dwarf_get_units(dw,dgu_cu,&dgu_cu,NULL,NULL,&cudie,&subdie)==0) {
 
 		if (*cup == NULL) {
 			struct cu *cu;
 
+			dwarf_cu_die (dgu_cu, &result, NULL, NULL, &pointer_size, NULL, NULL, NULL);
+
 			cu = cu__new("", pointer_size, build_id,
 				     build_id_len, filename, conf->use_obstack);
 			if (cu == NULL ||
@@ -3100,14 +3095,12 @@ static int __cus__load_debug_types(struct conf_load *conf, Dwfl_Module *mod, Dwa
 			*cup = cu;
 		}
 
-		Dwarf_Die die_mem;
-		Dwarf_Die *cu_die = dwarf_offdie_types(dw, off + cuhl,
-						       &die_mem);
-
-		if (die__process(cu_die, *cup, conf) != 0)
+		if (die__process(&cudie, *cup, conf) != 0)
 			return DWARF_CB_ABORT;
+		if (dwarf_tag(&subdie) != DW_TAG_invalid)
+			if (die__process(&subdie, *cup, conf) != 0)
+				return DWARF_CB_ABORT;
 
-		off = noff;
 	}
 
 	if (*cup != NULL && cu__recode_dwarf_types(*cup) != 0)
diff --git a/dwarves.c b/dwarves.c
index 9f97edaea2..2abab727fc 100644
--- a/dwarves.c
+++ b/dwarves.c
@@ -62,6 +62,10 @@ void *cu__malloc(struct cu *cu, size_t size)
 
 void cu__free(struct cu *cu, void *ptr)
 {
+	// FIXME it seems like loading split dwarf, causes multiple
+	// references to the same thing, and thus current clean up &
+	// free code aborts on double free's
+	return;
 	if (!cu->use_obstack)
 		free(ptr);
 
@@ -711,6 +715,10 @@ out_free:
 
 void cu__delete(struct cu *cu)
 {
+	// FIXME it seems like loading split dwarf, causes multiple
+	// references to the same thing, and thus current clean up &
+	// free code aborts on double free's
+	return;
 	if (cu == NULL)
 		return;
 
diff --git a/sample.c b/sample.c
new file mode 100644
index 0000000000..bff48d3139
--- /dev/null
+++ b/sample.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+struct Sample {
+  char sample_string[50];
+  int  sample_integer;
+  float sample_float;
+};
+void main() {
+	struct Sample sample = {.sample_integer = 3};
+	printf("%i\n", sample.sample_integer);
+}
diff --git a/sample.sh b/sample.sh
new file mode 100755
index 0000000000..241d4adec8
--- /dev/null
+++ b/sample.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+set -x
+rc=0
+gcc -gdwarf-5 -gsplit-dwarf ./sample.c
+valgrind ./pahole ./a.out
+rc=$((rc + $?))
+gcc -gdwarf-4 -gsplit-dwarf ./sample.c
+valgrind ./pahole ./a.out
+rc=$((rc + $?))
+gcc -gdwarf-5 ./sample.c
+valgrind ./pahole ./a.out
+rc=$((rc + $?))
+gcc -gdwarf-4 ./sample.c
+valgrind ./pahole ./a.out
+rc=$((rc + $?))
+rm -f a.out
+exit $rc
+
-- 
2.34.1





[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux