From 9a220b68787dd6af8d4709fbbbda94cd90f355fe Mon Sep 17 00:00:00 2001
From: jaseg <git-bigdata-wsl-arch@jaseg.de>
Date: Fri, 13 Mar 2020 12:39:11 +0100
Subject: linkmem: Add subdir highlighting

---
 controller/fw/Makefile         | 15 +++++++++++----
 controller/fw/tools/linkmem.py | 30 +++++++++++++++++++++++++++---
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/controller/fw/Makefile b/controller/fw/Makefile
index db10868..58acf4c 100644
--- a/controller/fw/Makefile
+++ b/controller/fw/Makefile
@@ -104,6 +104,7 @@ HOST_OBJCOPY		?= $(HOST_PREFIX)objcopy
 HOST_OBJDUMP		?= $(HOST_PREFIX)objdump
 
 PYTHON3 ?= python3
+DOT		?= dot
 
 CMSIS_DIR_ABS 		:= $(abspath $(CMSIS_DIR))
 MSPDEBUG_DIR_ABS 	:= $(abspath $(MSPDEBUG_DIR))
@@ -160,6 +161,8 @@ LDFLAGS			+= $(ARCH_FLAGS) $(SYSTEM_FLAGS)
 LIBS		+= -lgcc
 LDFLAGS		+= -Wl,--gc-sections
 
+LINKMEM_FLAGS ?= --trim-stubs=startup_stm32f407xx.o --trace-sections .isr_vector --highlight-subdirs $(BUILDDIR)
+
 OBJS := $(addprefix $(BUILDDIR)/,$(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o))
 
 ALL_OBJS := $(OBJS)
@@ -179,7 +182,7 @@ ALL_OBJS += $(BUILDDIR)/generated/dsss_cwt_wavelet.o
 all: binsize
 
 .PHONY: binsize
-binsize: $(BUILDDIR)/$(BINARY)
+binsize: $(BUILDDIR)/$(BINARY) $(BUILDDIR)/$(BINARY:.elf=-symbol-sizes.pdf)
 	$(LD) -T$(LDSCRIPT) $(LDFLAGS) -Wl,--print-memory-usage -o /dev/null $(ALL_OBJS) $(LIBS)
 	@echo
 	@echo "▐▬▬▬▌ SyMbOL sIzE HiGhScORe LiSt ▐▬▬▬▌"
@@ -221,9 +224,11 @@ $(BUILDDIR)/generated: ; mkdir -p $@
 $(BUILDDIR)/$(BINARY) $(BUILDDIR)/$(BINARY:.elf=.map) &: $(ALL_OBJS)
 	$(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ -Wl,-Map=$(BUILDDIR)/$(BINARY:.elf=.map) $^ $(LIBS)
 
-.PHONY: linktrace
-linktrace: $(ALL_OBJS)
-	$(PYTHON3) tools/linktracer.py $(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ $^ $(LIBS)
+build/$(BINARY:.elf=-symbol-sizes.dot): $(ALL_OBJS)
+	$(PYTHON3) tools/linkmem.py $(LINKMEM_FLAGS) $(LD) -T$(LDSCRIPT) $(LDFLAGS) $^ $(LIBS) > $@
+
+%.pdf: %.dot
+	$(DOT) -T pdf $< -o $@
 
 %.dot: %.elf
 	r2 -a arm -qc 'aa;agRd' $< 2>/dev/null >$@
@@ -282,6 +287,8 @@ clean:
 	rm -rf $(BUILDDIR)/src
 	rm -rf $(BUILDDIR)/generated
 	rm -f $(BUILDDIR)/$(BINARY)
+	rm -f $(BUILDDIR)/$(BINARY:.elf=-symbol-sizes.dot)
+	rm -f $(BUILDDIR)/$(BINARY:.elf=-symbol-sizes.pdf)
 	rm -f $(BUILDDIR)/tools/freq_meas_test
 
 mrproper: clean
diff --git a/controller/fw/tools/linkmem.py b/controller/fw/tools/linkmem.py
index 494217a..3d08d19 100644
--- a/controller/fw/tools/linkmem.py
+++ b/controller/fw/tools/linkmem.py
@@ -118,7 +118,7 @@ def wrap(leader='', print=print, left='{', right='}'):
 def mangle(name):
     return re.sub('[^a-zA-Z0-9_]', '_', name)
 
-hexcolor = lambda r, g, b: f'#{int(r*255):02x}{int(g*255):02x}{int(b*255):02x}'
+hexcolor = lambda r, g, b, *_a: f'#{int(r*255):02x}{int(g*255):02x}{int(b*255):02x}'
 def vhex(val):
     r,g,b,_a = matplotlib.cm.viridis(1.0-val)
     fc = hexcolor(r, g, b)  
@@ -131,6 +131,7 @@ if __name__ == '__main__':
     parser = argparse.ArgumentParser()
     parser.add_argument('--trace-sections', type=str, action='append', default=[])
     parser.add_argument('--trim-stubs', type=str, action='append', default=[])
+    parser.add_argument('--highlight-subdirs', type=str, default=None)
     parser.add_argument('linker_binary')
     parser.add_argument('linker_args', nargs=argparse.REMAINDER)
     args = parser.parse_args()
@@ -155,19 +156,42 @@ if __name__ == '__main__':
 
     max_osize = max(obj_size.values())
 
+    subdir_prefix = path.abspath(args.highlight_subdirs) + '/' if args.highlight_subdirs else '### NO HIGHLIGHT ###'
+    first_comp = lambda le_path: path.dirname(le_path).partition(os.sep)[0]
+    subdir_colors = sorted({ first_comp(obj[len(subdir_prefix):]) for obj in obj_size if obj.startswith(subdir_prefix) })
+    subdir_colors = { path: hexcolor(*matplotlib.cm.Paired(i/len(subdir_colors))) for i, path in enumerate(subdir_colors) }
+
+    def lookup_highlight(path):
+        if args.highlight_subdirs:
+            if obj.startswith(subdir_prefix):
+                highlight_head = first_comp(path[len(subdir_prefix):])
+                return subdir_colors[highlight_head], highlight_head
+            else:
+                return '#e0e0e0', None
+        else:
+            return '#ddf7f4', None
+
     with wrap('digraph G', print) as lvl1print:
         print('rankdir=LR;')
         print()
 
         for i, (obj, syms) in enumerate(clusters.items()):
             with wrap(f'subgraph cluster_{i}', lvl1print) as lvl2print:
+                print('style = "filled";')
+                highlight_color, highlight_head = lookup_highlight(obj)
+                print(f'bgcolor = "{highlight_color}";')
+                print('pencolor = none;')
                 fc, cc = vhex(obj_size[obj]/max_osize)
-                lvl2print(f'label = <<table border="0"><tr><td border="0" cellpadding="5" bgcolor="{fc}"><font face="carlito" color="{cc}"><b>{path.basename(obj)} ({obj_size[obj]}B)</b></font></td></tr></table>>;')
+                highlight_subdir_part = f'<font face="carlito" color="{cc}" point-size="12">{highlight_head} / </font>' if highlight_head else ''
+                lvl2print(f'label = <<table border="0"><tr><td border="0" cellpadding="5" bgcolor="{fc}">'
+                          f'{highlight_subdir_part}'
+                          f'<font face="carlito" color="{cc}"><b>{path.basename(obj)} ({obj_size[obj]}B)</b></font>'
+                          f'</td></tr></table>>;')
                 lvl2print()
                 for sym, size in syms:
                     if sym in syms_out:
                         fc, cc = vhex(size/max_size)
-                        lvl2print(f'{mangle(sym)}[label = "{sym} ({size}B)", style="rounded,filled", shape="box", fillcolor="{fc}", fontname="carlito", fontcolor="{cc}" color=None];')
+                        lvl2print(f'{mangle(sym)}[label = "{sym} ({size}B)", style="rounded,filled", shape="box", fillcolor="{fc}", fontname="carlito", fontcolor="{cc}" color=none];')
             lvl1print()
 
         for start, ends in refs.items():
-- 
cgit