Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
7.9 KiB

4 years ago
  1. /*
  2. * Module: procedure.d
  3. * Author: Mark I. Himelstein, Himelsoft, Inc.
  4. * Purpose: returns values for procedure queries on MIPS COFF symbol table
  5. */
  6. #include "conv.h"
  7. static pSYMR save_psymend; /* stBlock fetch save ptr to stEnd */
  8. eval_f get_compiler_version;
  9. #define GET_PROC_FIELD(routine_suffix, field_name, const) \
  10. extern data \
  11. get_procedure_##routine_suffix( \
  12. arg_s *parg, /* arg entry causing call */ \
  13. callinfo_s *pinfo, /* info we need to pass around */ \
  14. long *plength) /* for varying length fields */ \
  15. { \
  16. /* return field for procedure contain symbol we are up \
  17. * to. \
  18. */ \
  19. \
  20. parg; \
  21. plength; \
  22. \
  23. if (pinfo->ppdr == 0) { \
  24. fatal("tried to retrieve proc field without active procedure\n"); \
  25. } /* if */ \
  26. \
  27. return (data)(pinfo->ppdr->field_name + const); \
  28. } /* GET_PROC_FIELD */
  29. extern data
  30. get_arg_count(
  31. arg_s *parg, /* arg entry causing call */
  32. callinfo_s *pinfo, /* info we need to pass around */
  33. long *plength) /* for varying length fields */
  34. {
  35. /* only for typedefs, function variables, etc. */
  36. parg;
  37. plength;
  38. if (pinfo->psym[-1].st == stProto) {
  39. return pinfo->psym[-1].iss; /* where we stashed arglist count */
  40. } /* if */
  41. return 0;
  42. } /* get_proto_list */
  43. extern data
  44. get_proto_list(
  45. arg_s *parg, /* arg entry causing call */
  46. callinfo_s *pinfo, /* info we need to pass around */
  47. long *plength) /* for varying length fields */
  48. {
  49. unsigned short type_index;
  50. SYMR sym;
  51. /* only for typedefs, function variables, etc. */
  52. parg;
  53. plength;
  54. if (pinfo->psym[-1].st == stProto) {
  55. return pinfo->psym[-1].value; /* where we stashed arglist typeindex */
  56. } /* if */
  57. /* empty list so create one, save&restore sym since list_end modifies it */
  58. sym = *pinfo->psym;
  59. type_index = list_start(parg, pinfo, plength);
  60. list_end(parg, pinfo, plength);
  61. *pinfo->psym = sym;
  62. return type_index;
  63. } /* get_proto_list */
  64. extern data
  65. get_procedure_length(
  66. arg_s *parg, /* arg entry causing call */
  67. callinfo_s *pinfo, /* info we need to pass around */
  68. long *plength) /* for varying length fields */
  69. {
  70. /* return frame register for procedure contain symbol we are up
  71. * to.
  72. */
  73. pSYMR psymend; /* pointer to end of symbols for procedure */
  74. parg;
  75. plength;
  76. if (pinfo->psym->st != stProc && pinfo->psym->st != stStaticProc) {
  77. fatal("tried to retrieve procedure length for non-proc symbol\n");
  78. } /* if */
  79. if (pinfo->psym->index == indexNil ||
  80. pinfo->pfdr->caux < (long)pinfo->psym->index) {
  81. fatal("tried to retrieve proc length from damaged symbol table\n");
  82. } /* if */
  83. /* get index to end symbol and turn it into a pointer */
  84. psymend = isym_to_psym(pinfo, iaux_to_isym(pinfo, pinfo->psym->index)-1);
  85. return (data)(psymend->value);
  86. } /* get_procedure_length */
  87. extern data
  88. get_procedure_debug_start(
  89. arg_s *parg, /* arg entry causing call */
  90. callinfo_s *pinfo, /* info we need to pass around */
  91. long *plength) /* for varying length fields */
  92. {
  93. /* return offset to first nonprologue byte.
  94. */
  95. pSYMR psymstop; /* end of procedure stop looking for stBlock */
  96. pSYMR psymend; /* end of block symbol */
  97. pSYMR psym; /* copy of pinfo->psym we can increment */
  98. parg;
  99. plength;
  100. if (save_psymend != 0) {
  101. fatal("tried to get debug start before we cleared last proc\n");
  102. } /* if */
  103. if (pinfo->psym->st != stProc && pinfo->psym->st != stStaticProc) {
  104. fatal("tried to retrieve procedure length for non-proc symbol\n");
  105. } /* if */
  106. if (pinfo->psym->index == indexNil ||
  107. pinfo->pfdr->caux < (long)pinfo->psym->index) {
  108. fatal("tried to retrieve proc length from damaged symbol table\n");
  109. } /* if */
  110. /* get index to end of procedure symbol and turn it into a pointer */
  111. psymstop = isym_to_psym(pinfo, iaux_to_isym(pinfo, pinfo->psym->index)-1);
  112. psym = pinfo->psym;
  113. do {
  114. psym++;
  115. if (psym->st == stProc || psym->st == stStaticProc) {
  116. fatal("unexpected nested procedure\n");
  117. } /* if */
  118. if (psym->st == stBlock) {
  119. /* get pointer to end symbol, if it is not a text block,
  120. * use the end symbol to skip over it.
  121. */
  122. if (psym->index == indexNil || psym->index == 0) {
  123. fatal("tried to get endsym for inappropriate symbol\n");
  124. } /* if */
  125. psymend = isym_to_psym(pinfo, psym->index - 1);
  126. if (psym->sc != scText) {
  127. /* other type of block like struct definition */
  128. psym = psymend;
  129. continue;
  130. } /* if */
  131. /* got it */
  132. break;
  133. } /* if */
  134. } while (psym < psymstop);
  135. if (psym >= psymstop) {
  136. /* none found, emit warning & return 0 */
  137. warning("returning 0 because we can't find initial stBlock\n");
  138. save_psymend = 0; /* optimization for debug end */
  139. return 0;
  140. } /* if */
  141. save_psymend = psymend; /* optimization for debug end */
  142. /* set st values so we'll ignore this as a block later */
  143. psym->st = stEndParam; /* we still need to emit this symbol */
  144. psymend->st = stIgnore; /* no need to look at this one at all */
  145. return psym->value;
  146. } /* get_procedure_debug_start */
  147. extern data
  148. get_procedure_args(
  149. arg_s *parg, /* arg entry causing call */
  150. callinfo_s *pinfo, /* info we need to pass around */
  151. long *plength) /* for varying length fields */
  152. {
  153. data value;
  154. /* debug did all of my work for me */
  155. parg;
  156. plength;
  157. if (save_psymend == 0) {
  158. return 0;
  159. } /* if */
  160. value = save_psymend->value + pinfo->ppdr->adr;
  161. save_psymend = 0;
  162. generate_relocation(buffer_total(symbol_buf), pinfo->psym->st,
  163. pinfo->psym->sc, value, pinfo->index);
  164. return value;
  165. } /* get_procedure_debug_end */
  166. extern data
  167. get_procedure_debug_end(
  168. arg_s *parg, /* arg entry causing call */
  169. callinfo_s *pinfo, /* info we need to pass around */
  170. long *plength) /* for varying length fields */
  171. {
  172. data value;
  173. /* debug did all of my work for me */
  174. parg;
  175. plength;
  176. if (save_psymend == 0) {
  177. return 0;
  178. } /* if */
  179. value = save_psymend->value;
  180. save_psymend = 0;
  181. return value;
  182. } /* get_procedure_debug_end */
  183. GET_PROC_FIELD(framereg, framereg, 10)
  184. GET_PROC_FIELD(returnreg, pcreg, 10)
  185. GET_PROC_FIELD(saved_regs_mask, regmask, 0)
  186. GET_PROC_FIELD(saved_fpregs_mask, fregmask, 0)
  187. GET_PROC_FIELD(saved_regs_offset, regoffset, 0)
  188. GET_PROC_FIELD(saved_fpregs_offset, fregoffset, 0)
  189. GET_PROC_FIELD(frame_size, frameoffset, 0)