pool 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. include("/sys/src/libc/port/pool.acid");
  2. aggr Byte {
  3. 'b' 0 byte;
  4. };
  5. defn
  6. byteat(addr)
  7. {
  8. local x;
  9. complex Byte addr;
  10. x = addr.byte;
  11. return x\d;
  12. }
  13. defn
  14. B2T(addr) {
  15. complex Bhdr addr;
  16. addr = addr+addr.size-sizeofBtail;
  17. complex Btail addr;
  18. return addr;
  19. }
  20. defn
  21. B2D(addr) {
  22. local x;
  23. x = addr+sizeofBhdr;
  24. return x\X;
  25. }
  26. defn
  27. D2B(addr) {
  28. local x;
  29. x = addr-sizeofBhdr;
  30. complex Bhdr x;
  31. return x;
  32. }
  33. defn
  34. B2NB(addr) {
  35. complex Bhdr addr;
  36. addr = addr+addr.size;
  37. complex Bhdr addr;
  38. return addr;
  39. }
  40. defn
  41. A2TB(addr) {
  42. local b;
  43. complex Arena addr;
  44. b = addr+addr.asize-sizeofBhdr;
  45. complex Bhdr b;
  46. return b;
  47. }
  48. defn
  49. A2B(addr) {
  50. return B2NB(addr);
  51. }
  52. defn
  53. B2PT(addr) {
  54. complex Bhdr addr;
  55. addr = addr-sizeofBtail;
  56. complex Btail addr;
  57. return addr;
  58. }
  59. defn
  60. SHORT(addr) {
  61. local hi, lo;
  62. hi = byteat(addr);
  63. lo = byteat(addr+1);
  64. return lo+hi*256;
  65. }
  66. defn
  67. Btail(addr) {
  68. complex Btail addr;
  69. print(" magic0 ", addr.magic0, "\n");
  70. print(" datadiff ", SHORT(addr.datasize), "\n");
  71. print(" magic1 ", addr.magic1, "\n");
  72. print(" size ", addr.size\X, "\n");
  73. print(" hdr ", addr+sizeofBtail-addr.size\X, "\n");
  74. };
  75. defn
  76. Tail(addr)
  77. {
  78. print(" ", B2T(addr)\X, "\n");
  79. Btail(B2T(addr));
  80. }
  81. defn
  82. Magic(m)
  83. {
  84. if m == FREE_MAGIC then
  85. return "free";
  86. if m == ARENA_MAGIC then
  87. return "arena";
  88. if m == UNKEMPT_MAGIC then
  89. return "unkempt";
  90. if m == KEMPT_MAGIC then
  91. return "kempt";
  92. if m == ARENATAIL_MAGIC then
  93. return "arenatail";
  94. if m == DEAD_MAGIC then
  95. return "dead";
  96. return "unknown magic";
  97. }
  98. defn
  99. Block(addr)
  100. {
  101. complex Bhdr addr;
  102. print(" ", Magic(addr.magic), "\n");
  103. print(" data ", B2D(addr), "\n");
  104. print(" datasize ", getdsize(addr), "\n");
  105. Bhdr(addr);
  106. Tail(addr);
  107. }
  108. defn
  109. getdsize(addr)
  110. {
  111. complex Bhdr addr;
  112. local x;
  113. x = addr.size\d;
  114. x = x-SHORT(B2T(addr).datasize);
  115. return x\d;
  116. }
  117. defn
  118. datamagic(x)
  119. {
  120. x = x%4;
  121. if x == 0 then return 0xFE;
  122. if x == 1 then return 0xF1;
  123. if x == 2 then return 0xF0;
  124. if x == 3 then return 0xFA;
  125. }
  126. defn
  127. checkblock(addr)
  128. {
  129. local badmagic, datamagic, a, b, t, q, n, dsize, taddr, checked;
  130. complex Bhdr addr;
  131. taddr = B2T(addr);
  132. complex Btail taddr;
  133. if addr.magic == FREE_MAGIC || addr.magic == UNKEMPT_MAGIC then {
  134. if taddr.magic0 != TAIL_MAGIC0 || taddr.magic1 != TAIL_MAGIC1 then
  135. print(addr\X, " corrupt tail magic\n");
  136. if taddr.size != addr.size then
  137. print(addr\X, " corrupt tail header pointer\n");
  138. }
  139. if addr.magic == ARENA_MAGIC then {
  140. taddr = A2TB(addr);
  141. if taddr.magic != ARENATAIL_MAGIC then
  142. print(addr\X, " arena with bad tail block\n");
  143. else
  144. addr = taddr;
  145. }
  146. if addr.magic == ARENATAIL_MAGIC then {
  147. if addr.size != 0 then
  148. print(addr\X, " bad size in arena tail\n");
  149. }
  150. if addr.magic == KEMPT_MAGIC then {
  151. a = addr;
  152. complex Alloc a;
  153. if a.size > 1024*1024*1024 then
  154. print(addr\X, " block ridiculously large\n");
  155. t = B2T(addr);
  156. if t.magic0 != TAIL_MAGIC0 || t.magic1 != TAIL_MAGIC1 then
  157. print(addr\X, " bad tail magic\n");
  158. if t.size != addr.size then
  159. print(addr\X, " bad tail pointer\n");
  160. dsize = getdsize(a);
  161. if dsize > a.size then
  162. print(addr\X, " too much data in block\n");
  163. q = B2D(a)\X+dsize;
  164. n = 4;
  165. if q+4 > t then
  166. n = t-q;
  167. badmagic = 0;
  168. loop 0,n-1 do {
  169. if byteat(q) != datamagic(q) then {
  170. badmagic=1;
  171. }
  172. q = q+1;
  173. }
  174. if badmagic then
  175. print(addr\X, " size ", dsize, " user has overwritten boundary\n");
  176. }
  177. }
  178. defn
  179. checkarena(arena)
  180. {
  181. local atail, b;
  182. atail = A2TB(arena);
  183. complex Bhdr arena;
  184. b = a;
  185. while b.magic != ARENATAIL_MAGIC && b < atail do {
  186. checkblock(b);
  187. if B2NB(b) == b then {
  188. print("B2NB(", b\X, ") = b\n");
  189. b = atail; // end loop
  190. }
  191. b = B2NB(b);
  192. }
  193. checkblock(b);
  194. if b != atail then
  195. print("found wrong tail to arena ", arena\X, "\n");
  196. }
  197. defn
  198. checkpool(p)
  199. {
  200. complex Pool p;
  201. a = p.arenalist;
  202. while a != 0 do {
  203. complex Arena a;
  204. checkarena(a);
  205. a = a.down;
  206. }
  207. }
  208. defn
  209. gendumptree(f, in, s)
  210. {
  211. complex Free f;
  212. loop 1,in do {print(" ");}
  213. print(s, " size ", f.size\D, " left ", f.left\X, " right ", f.right\X, "\n");
  214. if f.left != 0 && f.left < 0x7FFFFFFF then
  215. gendumptree(f.left, in+1, "l");
  216. if f.right != 0 && f.right < 0x7FFFFFFF then
  217. gendumptree(f.right, in+1, "r");
  218. }
  219. defn
  220. dumptree(f)
  221. {
  222. gendumptree(f, 0, "*");
  223. }