diff options
Diffstat (limited to 'ipl/progs/loadmap.icn')
-rw-r--r-- | ipl/progs/loadmap.icn | 144 |
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 |