rdlib.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. * rdlib.c - routines for manipulating RDOFF libraries (.rdl)
  35. */
  36. #include "compiler.h"
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include "rdfutils.h"
  41. #include "rdlib.h"
  42. #include "rdlar.h"
  43. /* See Texinfo documentation about new RDOFF libraries format */
  44. int rdl_error = 0;
  45. char *rdl_errors[5] = {
  46. "no error", "could not open file", "invalid file structure",
  47. "file contains modules of an unsupported RDOFF version",
  48. "module not found"
  49. };
  50. int rdl_verify(const char *filename)
  51. {
  52. FILE *fp;
  53. char buf[257];
  54. int i;
  55. int32_t length;
  56. static char lastverified[256];
  57. static int lastresult = -1;
  58. if (lastresult != -1 && !strcmp(filename, lastverified))
  59. return lastresult;
  60. fp = fopen(filename, "rb");
  61. strcpy(lastverified, filename);
  62. if (!fp)
  63. return (rdl_error = lastresult = 1);
  64. while (!feof(fp)) {
  65. i = 0;
  66. while (fread(buf + i, 1, 1, fp) == 1 && i < 257 && buf[i])
  67. i++;
  68. if (feof(fp))
  69. break;
  70. if (buf[0] == '.') {
  71. /*
  72. * A special module, eg a signature block or a directory.
  73. * Format of such a module is defined to be:
  74. * six char type identifier
  75. * int32_t count bytes content
  76. * content
  77. * so we can handle it uniformaly with RDOFF2 modules.
  78. */
  79. nasm_read(buf, 6, fp);
  80. buf[6] = 0;
  81. /* Currently, nothing useful to do with signature block.. */
  82. } else {
  83. nasm_read(buf, 6, fp);
  84. buf[6] = 0;
  85. if (strncmp(buf, "RDOFF", 5)) {
  86. fclose(fp);
  87. return rdl_error = lastresult = 2;
  88. } else if (buf[5] != '2') {
  89. fclose(fp);
  90. return rdl_error = lastresult = 3;
  91. }
  92. }
  93. nasm_read(&length, 4, fp);
  94. fseek(fp, length, SEEK_CUR); /* skip over the module */
  95. }
  96. fclose(fp);
  97. return lastresult = 0; /* library in correct format */
  98. }
  99. int rdl_open(struct librarynode *lib, const char *name)
  100. {
  101. int i = rdl_verify(name);
  102. if (i)
  103. return i;
  104. lib->fp = NULL;
  105. lib->name = nasm_strdup(name);
  106. lib->referenced = 0;
  107. lib->next = NULL;
  108. return 0;
  109. }
  110. int rdl_searchlib(struct librarynode *lib, const char *label, rdffile * f)
  111. {
  112. char buf[512];
  113. int i, t;
  114. void *hdr;
  115. rdfheaderrec *r;
  116. int32_t l;
  117. rdl_error = 0;
  118. lib->referenced++;
  119. if (!lib->fp) {
  120. lib->fp = fopen(lib->name, "rb");
  121. if (!lib->fp) {
  122. rdl_error = 1;
  123. return 0;
  124. }
  125. } else
  126. rewind(lib->fp);
  127. while (!feof(lib->fp)) {
  128. /*
  129. * read the module name from the file, and prepend
  130. * the library name and '.' to it.
  131. */
  132. strcpy(buf, lib->name);
  133. i = strlen(lib->name);
  134. buf[i++] = '.';
  135. t = i;
  136. while (fread(buf + i, 1, 1, lib->fp) == 1 && i < 512 && buf[i])
  137. i++;
  138. buf[i] = 0;
  139. if (feof(lib->fp))
  140. break;
  141. if (!strcmp(buf + t, ".dir")) { /* skip over directory */
  142. nasm_read(&l, 4, lib->fp);
  143. fseek(lib->fp, l, SEEK_CUR);
  144. continue;
  145. }
  146. /*
  147. * open the RDOFF module
  148. */
  149. if (rdfopenhere(f, lib->fp, &lib->referenced, buf)) {
  150. rdl_error = 16 * rdf_errno;
  151. return 0;
  152. }
  153. /*
  154. * read in the header, and scan for exported symbols
  155. */
  156. hdr = nasm_malloc(f->header_len);
  157. rdfloadseg(f, RDOFF_HEADER, hdr);
  158. while ((r = rdfgetheaderrec(f))) {
  159. if (r->type != 3) /* not an export */
  160. continue;
  161. if (!strcmp(r->e.label, label)) { /* match! */
  162. nasm_free(hdr); /* reset to 'just open' */
  163. f->header_loc = NULL; /* state... */
  164. f->header_fp = 0;
  165. return 1;
  166. }
  167. }
  168. /* find start of next module... */
  169. i = f->eof_offset;
  170. rdfclose(f);
  171. fseek(lib->fp, i, SEEK_SET);
  172. }
  173. /*
  174. * close the file if nobody else is using it
  175. */
  176. lib->referenced--;
  177. if (!lib->referenced) {
  178. fclose(lib->fp);
  179. lib->fp = NULL;
  180. }
  181. return 0;
  182. }
  183. int rdl_openmodule(struct librarynode *lib, int moduleno, rdffile * f)
  184. {
  185. char buf[512];
  186. int i, cmod, t;
  187. int32_t length;
  188. lib->referenced++;
  189. if (!lib->fp) {
  190. lib->fp = fopen(lib->name, "rb");
  191. if (!lib->fp) {
  192. lib->referenced--;
  193. return (rdl_error = 1);
  194. }
  195. } else
  196. rewind(lib->fp);
  197. cmod = -1;
  198. while (!feof(lib->fp)) {
  199. strcpy(buf, lib->name);
  200. i = strlen(buf);
  201. buf[i++] = '.';
  202. t = i;
  203. while (fread(buf + i, 1, 1, lib->fp) == 1 && i < 512 && buf[i])
  204. i++;
  205. buf[i] = 0;
  206. if (feof(lib->fp))
  207. break;
  208. if (buf[t] != '.') /* special module - not counted in the numbering */
  209. cmod++; /* of RDOFF modules - must be referred to by name */
  210. if (cmod == moduleno) {
  211. rdl_error = 16 *
  212. rdfopenhere(f, lib->fp, &lib->referenced, buf);
  213. lib->referenced--;
  214. if (!lib->referenced) {
  215. fclose(lib->fp);
  216. lib->fp = NULL;
  217. }
  218. return rdl_error;
  219. }
  220. nasm_read(buf, 6, lib->fp);
  221. buf[6] = 0;
  222. if (buf[t] == '.') {
  223. /* do nothing */
  224. } else if (strncmp(buf, "RDOFF", 5)) {
  225. if (!--lib->referenced) {
  226. fclose(lib->fp);
  227. lib->fp = NULL;
  228. }
  229. return rdl_error = 2;
  230. } else if (buf[5] != '2') {
  231. if (!--lib->referenced) {
  232. fclose(lib->fp);
  233. lib->fp = NULL;
  234. }
  235. return rdl_error = 3;
  236. }
  237. nasm_read(&length, 4, lib->fp);
  238. fseek(lib->fp, length, SEEK_CUR); /* skip over the module */
  239. }
  240. if (!--lib->referenced) {
  241. fclose(lib->fp);
  242. lib->fp = NULL;
  243. }
  244. return rdl_error = 4; /* module not found */
  245. }
  246. void rdl_perror(const char *apname, const char *filename)
  247. {
  248. if (rdl_error >= 16)
  249. rdfperror(apname, filename);
  250. else
  251. fprintf(stderr, "%s:%s:%s\n", apname, filename,
  252. rdl_errors[rdl_error]);
  253. }