git: cec2d0b1c7ac - main - readelf: fix -wR option, memory leaks, and -wf minor bug

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 06 Mar 2023 17:52:52 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=cec2d0b1c7ac3196613813c0b07a2387916a8ccd

commit cec2d0b1c7ac3196613813c0b07a2387916a8ccd
Author:     Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2023-03-06 17:50:13 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2023-03-06 17:51:23 +0000

    readelf: fix -wR option, memory leaks, and -wf minor bug
    
    Reviewed by:    markj
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D38419
---
 contrib/elftoolchain/readelf/readelf.c | 39 ++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c
index 77125b77ebef..daaa7bf62dff 100644
--- a/contrib/elftoolchain/readelf/readelf.c
+++ b/contrib/elftoolchain/readelf/readelf.c
@@ -4938,8 +4938,10 @@ dump_dwarf_line(struct readelf *re)
 			return;
 		}
 		if (dwarf_attrval_unsigned(die, DW_AT_stmt_list, &offset,
-		    &de) != DW_DLV_OK)
+		    &de) != DW_DLV_OK) {
+			dwarf_dealloc(re->dbg, die, DW_DLA_DIE);
 			continue;
+		}
 
 		length = re->dw_read(d, &offset, 4);
 		if (length == 0xffffffff) {
@@ -4950,6 +4952,7 @@ dump_dwarf_line(struct readelf *re)
 
 		if (length > d->d_size - offset) {
 			warnx("invalid .dwarf_line section");
+			dwarf_dealloc(re->dbg, die, DW_DLA_DIE);
 			continue;
 		}
 
@@ -5147,9 +5150,8 @@ dump_dwarf_line(struct readelf *re)
 				    (uintmax_t) line);
 				p++;
 			}
-
-
 		}
+		dwarf_dealloc(re->dbg, die, DW_DLA_DIE);
 	}
 	if (ret == DW_DLV_ERROR)
 		warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de));
@@ -5192,9 +5194,9 @@ dump_dwarf_line_decoded(struct readelf *re)
 		printf("%-37s %11s   %s\n", "Filename", "Line Number",
 		    "Starting Address");
 		if (dwarf_srclines(die, &linebuf, &linecount, &de) != DW_DLV_OK)
-			continue;
+			goto done;
 		if (dwarf_srcfiles(die, &srcfiles, &srccount, &de) != DW_DLV_OK)
-			continue;
+			goto done;
 		for (i = 0; i < linecount; i++) {
 			ln = linebuf[i];
 			if (dwarf_line_srcfileno(ln, &fn, &de) != DW_DLV_OK)
@@ -5208,6 +5210,8 @@ dump_dwarf_line_decoded(struct readelf *re)
 			    (uintmax_t) lineaddr);
 		}
 		putchar('\n');
+done:
+		dwarf_dealloc(re->dbg, die, DW_DLA_DIE);
 	}
 }
 
@@ -5840,7 +5844,8 @@ dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, Dwarf_Addr base)
 	Dwarf_Addr base0;
 	Dwarf_Half attr;
 	Dwarf_Signed attr_count, cnt;
-	Dwarf_Unsigned off, bytecnt;
+	Dwarf_Unsigned bytecnt;
+	Dwarf_Off off;
 	int i, j, ret;
 
 	if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) !=
@@ -5857,11 +5862,12 @@ dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, Dwarf_Addr base)
 		}
 		if (attr != DW_AT_ranges)
 			continue;
-		if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) {
-			warnx("dwarf_formudata failed: %s", dwarf_errmsg(de));
+		if (dwarf_global_formref(attr_list[i], &off, &de) != DW_DLV_OK) {
+			warnx("dwarf_global_formref failed: %s",
+			    dwarf_errmsg(de));
 			continue;
 		}
-		if (dwarf_get_ranges(re->dbg, (Dwarf_Off) off, &ranges, &cnt,
+		if (dwarf_get_ranges(re->dbg, off, &ranges, &cnt,
 		    &bytecnt, &de) != DW_DLV_OK)
 			continue;
 		base0 = base;
@@ -5900,6 +5906,8 @@ cont_search:
 		warnx("dwarf_siblingof: %s", dwarf_errmsg(de));
 	else if (ret == DW_DLV_OK)
 		dump_dwarf_ranges_foreach(re, ret_die, base);
+
+	dwarf_dealloc(re->dbg, die, DW_DLA_DIE);
 }
 
 static void
@@ -6204,7 +6212,7 @@ dump_dwarf_frame_section(struct readelf *re, struct section *s, int alt)
 	Dwarf_Small cie_version;
 	Dwarf_Ptr fde_addr, fde_inst, cie_inst;
 	char *cie_aug, c;
-	int i, eh_frame;
+	int i, ret, eh_frame;
 	Dwarf_Error de;
 
 	printf("\nThe section %s contains:\n\n", s->name);
@@ -6219,10 +6227,13 @@ dump_dwarf_frame_section(struct readelf *re, struct section *s, int alt)
 		}
 	} else if (!strcmp(s->name, ".eh_frame")) {
 		eh_frame = 1;
-		if (dwarf_get_fde_list_eh(re->dbg, &cie_list, &cie_count,
-		    &fde_list, &fde_count, &de) != DW_DLV_OK) {
-			warnx("dwarf_get_fde_list_eh failed: %s",
-			    dwarf_errmsg(de));
+		ret = dwarf_get_fde_list_eh(re->dbg, &cie_list, &cie_count,
+		    &fde_list, &fde_count, &de);
+		if (ret != DW_DLV_OK) {
+			if (ret == DW_DLV_ERROR) {
+				warnx("dwarf_get_fde_list_eh failed: %s",
+				    dwarf_errmsg(de));
+			}
 			return;
 		}
 	} else