PCDebug.Mod 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. (* Paco, Copyright 2000 - 2002, Patrik Reali, ETH Zurich *)
  2. MODULE PCDebug; (** AUTHOR "prk"; PURPOSE "Parallel Compiler: low-level trace functions"; *)
  3. IMPORT
  4. SYSTEM, Machine, KernelLog, Modules;
  5. CONST
  6. (*ToDo classes*)
  7. NotImplemented* = 0;
  8. NotOptimized* = 1;
  9. TYPE
  10. List = POINTER TO RECORD (* list of PC positions *)
  11. pc: ADDRESS;
  12. next: List
  13. END;
  14. VAR
  15. pclist: List; (* todo list *)
  16. Hex: ARRAY 17 OF CHAR;
  17. (* Read a compressed integer from memory *)
  18. PROCEDURE ReadNum (VAR pos: ADDRESS; VAR i: LONGINT);
  19. VAR n: LONGINT; s: SHORTINT; x: CHAR;
  20. BEGIN
  21. s := 0; n := 0; SYSTEM.GET(pos, x); INC(pos);
  22. WHILE ORD(x) >= 128 DO INC(n, ASH(ORD(x) - 128, s)); INC(s, 7); SYSTEM.GET(pos, x); INC(pos) END;
  23. i := n + ASH(ORD(x) MOD 64 - ORD(x) DIV 64 * 64, s)
  24. END ReadNum;
  25. PROCEDURE WriteString*(str: ARRAY OF CHAR; VAR name: ARRAY OF CHAR; VAR pos: LONGINT);
  26. VAR i: LONGINT;
  27. BEGIN
  28. i := 0;
  29. WHILE (str[i] # 0X) & (pos < LEN(name)-1) DO
  30. name[pos] := str[i]; INC(i); INC(pos)
  31. END;
  32. name[pos] := 0X
  33. END WriteString;
  34. PROCEDURE WriteHex*(val: ADDRESS; VAR name: ARRAY OF CHAR; VAR pos: LONGINT);
  35. VAR i: LONGINT;
  36. BEGIN
  37. INC(pos, 8); i := 1;
  38. WHILE i <= 8 DO
  39. IF (pos-i < LEN(name)-1) THEN name[pos-i] := Hex[val MOD 16] END;
  40. val := val DIV 16; INC(i)
  41. END;
  42. name[pos] := 0X
  43. END WriteHex;
  44. PROCEDURE GetProcedure*(pc: ADDRESS; VAR name: ARRAY OF CHAR);
  45. VAR mod: Modules.Module; refpos, limit, refstart: ADDRESS; ch, ch0: CHAR; i, procstart: LONGINT;
  46. BEGIN
  47. i := 0;
  48. mod := Modules.ThisModuleByAdr(pc);
  49. IF mod = NIL THEN
  50. WriteString("NIL PC = ", name, i); WriteHex(pc, name, i)
  51. ELSE
  52. WriteString(mod.name, name, i); WriteString(".", name, i);
  53. IF (SYSTEM.VAL(LONGINT, mod.refs) # 0) & (LEN(mod.refs) # 0) THEN
  54. refstart := 0; refpos := ADDRESSOF(mod.refs[0]);
  55. limit := refpos + LEN(mod.refs);
  56. LOOP
  57. SYSTEM.GET(refpos, ch); INC(refpos);
  58. IF refpos >= limit THEN EXIT END;
  59. IF ch = 0F8X THEN (* start proc *)
  60. ReadNum(refpos, procstart);
  61. IF pc < ADDRESSOF(mod.code[0]) + procstart THEN EXIT END;
  62. refstart := refpos;
  63. REPEAT SYSTEM.GET(refpos, ch); INC(refpos) UNTIL ch = 0X; (*skip name*)
  64. ELSIF ch = 0F9X THEN (*proc, new format*)
  65. ReadNum(refpos, procstart);
  66. IF pc < ADDRESSOF(mod.code[0]) + procstart THEN EXIT END;
  67. INC(refpos, 1+1+1+1);
  68. refstart := refpos;
  69. REPEAT SYSTEM.GET(refpos, ch); INC(refpos) UNTIL ch = 0X; (*skip name*)
  70. ELSIF ch < 0F8X THEN (* skip object *)
  71. INC(refpos); (* skip typeform *)
  72. ReadNum(refpos, procstart); (* skip offset *)
  73. REPEAT SYSTEM.GET(refpos, ch); INC(refpos) UNTIL ch = 0X; (*skip name*)
  74. END
  75. END;
  76. refpos := refstart;
  77. IF refpos # 0 THEN
  78. SYSTEM.GET(refpos, ch); INC(refpos); ch0 := ch;
  79. WHILE ch # 0X DO name[i] := ch; INC(i); SYSTEM.GET(refpos, ch); INC(refpos) END;
  80. name[i] := 0X
  81. END
  82. END;
  83. WriteString(" PC = ", name, i); WriteHex(pc-ADDRESSOF(mod.code[0]), name, i); WriteString("H", name, i)
  84. END
  85. END GetProcedure;
  86. PROCEDURE GetTypeName*(p: ANY; VAR name: ARRAY OF CHAR);
  87. VAR ch: CHAR; i, tag: LONGINT;
  88. BEGIN
  89. IF p = NIL THEN COPY("NIL", name)
  90. ELSE
  91. SYSTEM.GET(SYSTEM.VAL(LONGINT, p)-4, tag);
  92. IF (tag # 0) & (tag MOD 16 = 8) THEN
  93. SYSTEM.GET(tag-4, tag);
  94. INC(tag, 16);
  95. SYSTEM.GET(tag, ch); i := 0;
  96. WHILE (ch # 0X) & (i < LEN(name)-1) DO
  97. name[i] := ch; INC(i); SYSTEM.GET(tag+i, ch)
  98. END;
  99. name[i] := 0X
  100. ELSE
  101. COPY("wrong tag", name)
  102. END
  103. END
  104. END GetTypeName;
  105. PROCEDURE ToDo*(class: LONGINT);
  106. VAR pc, bp: ADDRESS; p, q: List; name: ARRAY 64 OF CHAR;
  107. BEGIN {EXCLUSIVE}
  108. bp := SYSTEM.GetFramePointer ();
  109. SYSTEM.GET (bp + SIZEOF(ADDRESS), pc);
  110. p := pclist;
  111. WHILE (p.next # NIL) & (p.next.pc < pc) DO p := p.next END;
  112. IF (p.next = NIL) OR (p.next.pc # pc) THEN
  113. NEW(q); q.pc := pc; q.next := p.next; p.next := q;
  114. KernelLog.Ln;
  115. CASE class OF
  116. | NotImplemented: KernelLog.String(" unimplemented at ")
  117. | NotOptimized: KernelLog.String(" not optimized at ")
  118. END;
  119. GetProcedure(pc, name); KernelLog.String(name);
  120. END;
  121. IF class = NotImplemented THEN
  122. HALT(MAX(INTEGER))
  123. END
  124. END ToDo;
  125. PROCEDURE ResetToDo*;
  126. BEGIN
  127. NEW(pclist); pclist.next := NIL;
  128. END ResetToDo;
  129. BEGIN
  130. Hex := "0123456789ABCDEF"
  131. END PCDebug.
  132. (*
  133. 08.02.02 prk use Aos instead of Oberon modules
  134. 22.01.02 prk ToDo list moved to PCDebug
  135. 25.03.01 prk renamed, was Debug.Mod
  136. *)