rdfdump.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /* ----------------------------------------------------------------------- *
  2. *
  3. * Copyright 1996-2014 The NASM Authors - All Rights Reserved
  4. * See the file AUTHORS included with the NASM distribution for
  5. * the specific copyright holders.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following
  9. * conditions are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * * Redistributions in binary form must reproduce the above
  14. * copyright notice, this list of conditions and the following
  15. * disclaimer in the documentation and/or other materials provided
  16. * with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  19. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  20. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  29. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  30. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. * ----------------------------------------------------------------------- */
  33. /*
  34. * rdfdump.c - dump RDOFF file header.
  35. */
  36. #include "compiler.h"
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include "rdfutils.h"
  41. #define PROGRAM_VERSION "2.3"
  42. FILE *infile;
  43. static void print_header(int32_t length, int rdf_version)
  44. {
  45. char buf[129], t, l, s, flags;
  46. uint8_t reclen;
  47. int32_t o, ll;
  48. uint16_t rs;
  49. while (length > 0) {
  50. nasm_read(&t, 1, infile);
  51. if (rdf_version >= 2) {
  52. nasm_read(&reclen, 1, infile);
  53. }
  54. switch (t) {
  55. case RDFREC_GENERIC: /* generic record */
  56. printf(" generic record (length=%d)\n", (int)reclen);
  57. fseek(infile, reclen, SEEK_CUR);
  58. break;
  59. case RDFREC_RELOC: /* relocation record */
  60. case RDFREC_SEGRELOC: /* segment relocation */
  61. nasm_read(&s, 1, infile);
  62. nasm_read(&o, 4, infile);
  63. nasm_read(&l, 1, infile);
  64. nasm_read(&rs, 2, infile);
  65. printf(" %s: location (%04x:%08"PRIx32"), length %d, "
  66. "referred seg %04x\n",
  67. t == 1 ? "relocation" : "seg relocation", (int)s,
  68. translateint32_t(o), (int)l, translateint16_t(rs));
  69. if (rdf_version >= 2 && reclen != 8)
  70. printf(" warning: reclen != 8\n");
  71. if (rdf_version == 1)
  72. length -= 9;
  73. if (rdf_version == 1 && t == 6)
  74. printf
  75. (" warning: seg relocation not supported in RDOFF1\n");
  76. break;
  77. case RDFREC_IMPORT: /* import record */
  78. case RDFREC_FARIMPORT: /* import far symbol */
  79. nasm_read(&flags, 1, infile);
  80. nasm_read(&rs, 2, infile);
  81. ll = 0;
  82. if (rdf_version == 1) {
  83. do {
  84. nasm_read(&buf[ll], 1, infile);
  85. } while (buf[ll++]);
  86. } else {
  87. for (; ll < reclen - 3; ll++)
  88. nasm_read(&buf[ll], 1, infile);
  89. }
  90. if (t == 7)
  91. printf("far ");
  92. printf((flags & SYM_IMPORT) ? " import" : " extern");
  93. if (flags & SYM_FUNCTION)
  94. printf(" proc");
  95. if (flags & SYM_DATA)
  96. printf(" data");
  97. printf(": segment %04x = %s\n", translateint16_t(rs), buf);
  98. if (rdf_version == 1)
  99. length -= ll + 3;
  100. if (rdf_version == 1 && t == 7)
  101. printf
  102. (" warning: far import not supported in RDOFF1\n");
  103. break;
  104. case RDFREC_GLOBAL: /* export record */
  105. nasm_read(&flags, 1, infile);
  106. nasm_read(&s, 1, infile);
  107. nasm_read(&o, 4, infile);
  108. ll = 0;
  109. if (rdf_version == 1) {
  110. do {
  111. nasm_read(&buf[ll], 1, infile);
  112. } while (buf[ll++]);
  113. } else {
  114. for (; ll < reclen - 6; ll++)
  115. nasm_read(&buf[ll], 1, infile);
  116. }
  117. printf((flags & SYM_GLOBAL) ? " export" : " public");
  118. if (flags & SYM_FUNCTION)
  119. printf(" proc");
  120. if (flags & SYM_DATA)
  121. printf(" data");
  122. printf(": (%04x:%08"PRIx32") = %s\n", (int)s, translateint32_t(o), buf);
  123. if (rdf_version == 1)
  124. length -= ll + 6;
  125. break;
  126. case RDFREC_DLL: /* DLL and Module records */
  127. case RDFREC_MODNAME:
  128. ll = 0;
  129. if (rdf_version == 1) {
  130. do {
  131. nasm_read(&buf[ll], 1, infile);
  132. } while (buf[ll++]);
  133. } else {
  134. for (; ll < reclen; ll++)
  135. nasm_read(&buf[ll], 1, infile);
  136. }
  137. if (t == 4)
  138. printf(" dll: %s\n", buf);
  139. else
  140. printf(" module: %s\n", buf);
  141. if (rdf_version == 1)
  142. length -= ll + 1;
  143. break;
  144. case RDFREC_BSS: /* BSS reservation */
  145. nasm_read(&ll, 4, infile);
  146. printf(" bss reservation: %08"PRIx32" bytes\n", translateint32_t(ll));
  147. if (rdf_version == 1)
  148. length -= 5;
  149. if (rdf_version > 1 && reclen != 4)
  150. printf(" warning: reclen != 4\n");
  151. break;
  152. case RDFREC_COMMON:{
  153. uint16_t seg, align;
  154. uint32_t size;
  155. nasm_read(&seg, 2, infile);
  156. nasm_read(&size, 4, infile);
  157. nasm_read(&align, 2, infile);
  158. for (ll = 0; ll < reclen - 8; ll++)
  159. nasm_read(buf + ll, 1, infile);
  160. printf(" common: segment %04x = %s, %"PRId32":%d\n",
  161. translateint16_t(seg), buf, translateint32_t(size),
  162. translateint16_t(align));
  163. break;
  164. }
  165. default:
  166. printf(" unrecognized record (type %d", (int)t);
  167. if (rdf_version > 1) {
  168. printf(", length %d", (int)reclen);
  169. fseek(infile, reclen, SEEK_CUR);
  170. } else
  171. length--;
  172. printf(")\n");
  173. }
  174. if (rdf_version != 1)
  175. length -= 2 + reclen;
  176. }
  177. }
  178. int main(int argc, char **argv)
  179. {
  180. char id[7];
  181. int32_t l;
  182. uint16_t s;
  183. int verbose = 0;
  184. int32_t offset;
  185. int foundnullsegment = 0;
  186. int version;
  187. int32_t segmentcontentlength = 0;
  188. int nsegments = 0;
  189. int32_t headerlength = 0;
  190. int32_t objectlength = 0;
  191. printf("RDOFF dump utility, version %s\n", PROGRAM_VERSION);
  192. printf("RDOFF2 revision %s\n", RDOFF2_REVISION);
  193. puts("Copyright (c) 1996,99 Julian R Hall\n"
  194. "Improvements and fixes (c) 2002-2004 RET & COM Research.");
  195. if (argc < 2) {
  196. fputs("Usage: rdfdump [-v] <filename>\n", stderr);
  197. exit(1);
  198. }
  199. rdoff_init();
  200. if (!strcmp(argv[1], "-v")) {
  201. verbose = 1;
  202. if (argc < 3) {
  203. fputs("required parameter missing\n", stderr);
  204. exit(1);
  205. }
  206. argv++;
  207. }
  208. infile = fopen(argv[1], "rb");
  209. if (!infile) {
  210. fprintf(stderr, "rdfdump: Could not open %s\n", argv[1]);
  211. exit(1);
  212. }
  213. nasm_read(id, 6, infile);
  214. if (strncmp(id, "RDOFF", 5)) {
  215. fputs("rdfdump: File does not contain valid RDOFF header\n",
  216. stderr);
  217. exit(1);
  218. }
  219. printf("File %s: RDOFF version %c\n\n", argv[1], id[5]);
  220. if (id[5] < '1' || id[5] > '2') {
  221. fprintf(stderr, "rdfdump: unknown RDOFF version '%c'\n", id[5]);
  222. exit(1);
  223. }
  224. version = id[5] - '0';
  225. if (version > 1) {
  226. nasm_read(&l, 4, infile);
  227. objectlength = translateint32_t(l);
  228. printf("Object content size: %"PRId32" bytes\n", objectlength);
  229. }
  230. nasm_read(&l, 4, infile);
  231. headerlength = translateint32_t(l);
  232. printf("Header (%"PRId32" bytes):\n", headerlength);
  233. print_header(headerlength, version);
  234. if (version == 1) {
  235. nasm_read(&l, 4, infile);
  236. l = translateint32_t(l);
  237. printf("\nText segment length = %"PRId32" bytes\n", l);
  238. offset = 0;
  239. while (l--) {
  240. nasm_read(id, 1, infile);
  241. if (verbose) {
  242. if (offset % 16 == 0)
  243. printf("\n%08"PRIx32" ", offset);
  244. printf(" %02x", (int)(uint8_t)id[0]);
  245. offset++;
  246. }
  247. }
  248. if (verbose)
  249. printf("\n\n");
  250. nasm_read(&l, 4, infile);
  251. l = translateint32_t(l);
  252. printf("Data segment length = %"PRId32" bytes\n", l);
  253. if (verbose) {
  254. offset = 0;
  255. while (l--) {
  256. nasm_read(id, 1, infile);
  257. if (offset % 16 == 0)
  258. printf("\n%08"PRIx32" ", offset);
  259. printf(" %02x", (int)(uint8_t)id[0]);
  260. offset++;
  261. }
  262. printf("\n");
  263. }
  264. } else {
  265. do {
  266. nasm_read(&s, 2, infile);
  267. s = translateint16_t(s);
  268. if (!s) {
  269. printf("\nNULL segment\n");
  270. foundnullsegment = 1;
  271. break;
  272. }
  273. printf("\nSegment:\n Type = %04X (%s)\n", (int)s,
  274. translatesegmenttype(s));
  275. nsegments++;
  276. nasm_read(&s, 2, infile);
  277. printf(" Number = %04X\n", (int)translateint16_t(s));
  278. nasm_read(&s, 2, infile);
  279. printf(" Resrvd = %04X\n", (int)translateint16_t(s));
  280. nasm_read(&l, 4, infile);
  281. l = translateint32_t(l);
  282. printf(" Length = %"PRId32" bytes\n", l);
  283. segmentcontentlength += l;
  284. offset = 0;
  285. while (l--) {
  286. nasm_read(id, 1, infile);
  287. if (verbose) {
  288. if (offset % 16 == 0)
  289. printf("\n%08"PRIx32" ", offset);
  290. printf(" %02x", (int)(uint8_t)id[0]);
  291. offset++;
  292. }
  293. }
  294. if (verbose)
  295. printf("\n");
  296. } while (!feof(infile));
  297. if (!foundnullsegment)
  298. printf("\nWarning: unexpected end of file - "
  299. "NULL segment not found\n");
  300. printf("\nTotal number of segments: %d\n", nsegments);
  301. printf("Total segment content length: %"PRId32" bytes\n",
  302. segmentcontentlength);
  303. /* calculate what the total object content length should have been */
  304. l = segmentcontentlength + 10 * (nsegments + 1) + headerlength + 4;
  305. if (l != objectlength)
  306. printf("Warning: actual object length (%"PRId32") != "
  307. "stored object length (%"PRId32")\n", l, objectlength);
  308. }
  309. fclose(infile);
  310. return 0;
  311. }