Subject: Re: MAP (and variants) vs LOOP - Popular opinion observation?
From: rpw3@rpw3.org (Rob Warnock)
Date: Sat, 05 Aug 2006 22:07:28 -0500
Newsgroups: comp.lang.lisp
Message-ID: <rNidnSSnH5RtwUjZnZ2dnUVZ_vKdnZ2d@speakeasy.net>
Jonathon McKitrick <j_mckitrick@bigfoot.com> wrote:
+---------------
| lispolos wrote:
| > (BTW, it's more or less the same with regular expressions: in Lisp you
| > can do surprisingly often without them, beeing able to also see exactly
| > how it is done, where in many other languages it would be very
| > difficult to code without, and how it is done is more or less hidden by
| > the regular expression...)
| 
| Any examples of this you can offer?
+---------------

The following hack [with some names obfuscated] parses ".objd" files
[output from "objdump"] to collect a map of places in the target
code being debugged where the function "foo_trace()" was called.
[The function "foo_trace()" sticks its return address into a trace
buffer along with its other args, which is why this is useful.]

    (defun load-trace-map (&key (file "home:build/test/foo/foo.objd")
                                (verbose nil))
      (with-open-file (s file)
        (setf *trace-map* (make-hash-table))    ; clear out old stuff
        (loop with labels = 0
              for line = (read-line s nil nil)
              while line
          when (and (> (length line) 10)
                    (not (mismatch line "0002" :end1 4))
                    (mismatch "foo_trace" line :start2 10 :end2 22)
                    (eql 0 (mismatch "<foo_trace>" line :from-end t)))
            do (let* ((addr (parse-integer line :start 4 :end 8 :radix 16))
                      (end (position #\> line))
                      (label (subseq line 10 end)))
                 (when verbose
                   (format t "~(0x~4,'0x~) ~a~%" addr label))
                 (incf labels)
                 (setf (gethash addr *trace-map*) label))
          finally (format t "~d labels extracted~%" labels)))
      (values))
       
That is, given ".objd" lines like these:

    ...
    000217d4 <gorp+0x34> e1a01002 mov     r1, r2
    000217d8 <gorp+0x38> ebfffbc0 bl      000206e0 <foo_trace>
    000217dc <gorp+0x3c> e5941000 ldr     r1, [r4]
    ...

it will do a (SETF (GETHASH #x17d8 *TRACE-MAP*) "gorp+0x38").
So when the buffer is printed out, whenever the return address
#x17dc is seen in the trace buffer [which only stores the 16 LSBs],
the trace entry will be annotated with "gorp+0x38".


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607