4.3BSD/usr/contrib/icon/src/cmd/loadmap.icn

#	LOADMAP(1)
#
#	Produce load map of object file
#
#	Stephen B. Wampler
#
#	Last modified 7/10/83
#

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
   initial {
      if *args = 0 then stop("usage: loadmap -tdbuac 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"
      }
   maptype := ""
   every arg := !args do
      if arg[1] ~== "-" then file := arg
      else if arg[1] == "-" then maptype ||:= (!"tdbuac" == arg[2:0]) |
         stop("usage:  loadmap -tdbuac 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("nm -gno " || 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