summaryrefslogtreecommitdiff
path: root/ipl/progs/loadmap.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/progs/loadmap.icn')
-rw-r--r--ipl/progs/loadmap.icn144
1 files changed, 144 insertions, 0 deletions
diff --git a/ipl/progs/loadmap.icn b/ipl/progs/loadmap.icn
new file mode 100644
index 0000000..dfdbd78
--- /dev/null
+++ b/ipl/progs/loadmap.icn
@@ -0,0 +1,144 @@
+############################################################################
+#
+# File: loadmap.icn
+#
+# Subject: Program to show load map of UNIX object file
+#
+# Author: Stephen B. Wampler
+#
+# Date: December 13, 1985
+#
+############################################################################
+#
+# This file is in the public domain.
+#
+############################################################################
+#
+# This program produces a formatted listing of selected symbol classes
+# from a compiled file. The listing is by class, and gives the
+# name, starting address, and length of the region associated with
+# each symbol.
+#
+# The options are:
+#
+# -a Display the absolute symbols.
+#
+# -b Display the BSS segment symbols.
+#
+# -c Display the common segment symbols.
+#
+# -d Display the data segment symbols.
+#
+# -t Display the text segment symbols.
+#
+# -u Display the undefined symbols.
+#
+# If no options are specified, -t is assumed.
+#
+# If the address of a symbol cannot be determined, ???? is given in
+# its place.
+#
+############################################################################
+#
+# Notes:
+#
+# The size of the last region in a symbol class is suspect and is
+# usually given as rem.
+#
+# Output is not particularly exciting on a stripped file.
+#
+############################################################################
+#
+# Requires: UNIX
+#
+############################################################################
+
+record entry(name,address)
+
+procedure main(args)
+ local maptype, arg, file, nm, ldmap, tname, line, text, data, bss
+ local SPACE, COLON, DIGITS, HEXDIGITS, usize, address, name, nmtype
+ initial {
+ if *args = 0 then stop("usage: loadmap [-t -d -b -u -a -c -l] file")
+ SPACE := '\t '
+ COLON := ':'
+ DIGITS := '0123456789'
+ HEXDIGITS := DIGITS ++ 'abcdef'
+ ldmap := table(6)
+ ldmap["u"] := []
+ ldmap["d"] := []
+ ldmap["a"] := []
+ ldmap["b"] := []
+ ldmap["t"] := []
+ ldmap["c"] := []
+ tname := table(6)
+ tname["u"] := "Undefined symbols"
+ tname["a"] := "Absolute locations"
+ tname["t"] := "Text segment symbols"
+ tname["d"] := "Data segment symbols"
+ tname["b"] := "BSS segment symbols"
+ tname["c"] := "Common symbols"
+ nmtype := "nm -gno "
+ }
+ maptype := ""
+ every arg := !args do
+ if arg[1] ~== "-" then file := arg
+ else if arg == "-l" then nmtype := "nm -no "
+ else if arg[1] == "-" then maptype ||:= (!"ltdbuac" == arg[2:0]) |
+ stop("usage: loadmap [-t -d -b -u -a -c -l] file")
+ maptype := if *maptype = 0 then "t" else string(cset(maptype))
+ write("\n",file,"\n")
+ usize := open("size " || file,"rp") | stop("loadmap: cannot execute size")
+ !usize ? {
+ writes("Text space: ",right(text := tab(many(DIGITS)),6)," ")
+ move(1)
+ writes("Initialized Data: ",right(data := tab(many(DIGITS)),6)," ")
+ move(1)
+ write("Uninitialized Data: ",right(bss := tab(many(DIGITS)),6))
+ }
+ close(usize)
+ nm := open(nmtype || file,"rp") | stop("loadmap: cannot execute nm")
+ every line := !nm do
+ line ? {
+ tab(upto(COLON)) & move(1)
+ address := integer("16r" || tab(many(HEXDIGITS))) | "????"
+ tab(many(SPACE))
+ type := map(move(1))
+ tab(many(SPACE))
+ name := tab(0)
+ if find(type,maptype) then put(ldmap[type],entry(name,address))
+ }
+ every type := !maptype do {
+ if *ldmap[type] > 0 then {
+ write("\n\n\n")
+ write(tname[type],":")
+ write()
+ show(ldmap[type],(type == "t" & text) |
+ (type == "d" & data) | (type == "b" & bss) | &null,
+ ldmap[type][1].address)
+ }
+ }
+end
+
+procedure show(l,ssize,base)
+ local i1, i2, nrows
+ static ncols
+ initial ncols := 3
+ write(repl(repl(" ",3) || left("name",9) || right("addr",7) ||
+ right("size",6),ncols))
+ write()
+ nrows := (*l + (ncols - 1)) / ncols
+ every i1 := 1 to nrows do {
+ every i2 := i1 to *l by nrows do
+ writes(repl(" ",3),left(l[i2].name,9),right(l[i2].address,7),
+ right(area(l[i2 + 1].address,l[i2].address) |
+ if /ssize then "rem" else base + ssize - l[i2].address,6))
+ write()
+ }
+ return
+end
+
+procedure area(high,low)
+ if integer(low) & integer(high) then return high - low
+ else return "????"
+end