int rdl_searchlib(struct librarynode *lib, const char *label, rdffile * f) { char buf[512]; int i, t; void *hdr; rdfheaderrec *r; int32_t l; rdl_error = 0; lib->referenced++; if (!lib->fp) { lib->fp = fopen(lib->name, "rb"); if (!lib->fp) { rdl_error = 1; return 0; } } else rewind(lib->fp); while (!feof(lib->fp)) { /* * read the module name from the file, and prepend * the library name and '.' to it. */ strcpy(buf, lib->name); i = strlen(lib->name); buf[i++] = '.'; t = i; while (fread(buf + i, 1, 1, lib->fp) == 1 && i < 512 && buf[i]) i++; buf[i] = 0; if (feof(lib->fp)) break; if (!strcmp(buf + t, ".dir")) { /* skip over directory */ nasm_read(&l, 4, lib->fp); fseek(lib->fp, l, SEEK_CUR); continue; } /* * open the RDOFF module */ if (rdfopenhere(f, lib->fp, &lib->referenced, buf)) { rdl_error = 16 * rdf_errno; return 0; } /* * read in the header, and scan for exported symbols */ hdr = nasm_malloc(f->header_len); rdfloadseg(f, RDOFF_HEADER, hdr); while ((r = rdfgetheaderrec(f))) { if (r->type != 3) /* not an export */ continue; if (!strcmp(r->e.label, label)) { /* match! */ nasm_free(hdr); /* reset to 'just open' */ f->header_loc = NULL; /* state... */ f->header_fp = 0; return 1; } } /* find start of next module... */ i = f->eof_offset; rdfclose(f); fseek(lib->fp, i, SEEK_SET); } /* * close the file if nobody else is using it */ lib->referenced--; if (!lib->referenced) { fclose(lib->fp); lib->fp = NULL; } return 0; }
int search_libraries() { struct librarynode * cur; rdffile f; int i; void * header; int segment; long offset; int doneanything = 0, keepfile; rdfheaderrec * hr; cur = libraries; while (cur) { if (options.verbose > 2) printf("scanning library `%s'...\n", cur->name); for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++) { if (options.verbose > 3) printf(" looking in module `%s'\n", f.name); header = malloc(f.header_len); if (!header) { fprintf(stderr, "ldrdf: not enough memory\n"); exit(1); } if (rdfloadseg(&f, RDOFF_HEADER, header)) { rdfperror("ldrdf", f.name); errorcount++; return 0; } keepfile = 0; while ((hr = rdfgetheaderrec (&f))) { /* we're only interested in exports, so skip others: */ if (hr->type != 3) continue; /* * Find the symbol in the symbol table. If the symbol isn't * defined, we aren't interested, so go on to the next. * If it is defined as anything but -1, we're also not * interested. But if it is defined as -1, insert this * module into the list of modules to use, and go * immediately on to the next module... */ if (! symtab_get(hr->e.label, &segment, &offset) || segment != -1) { continue; } doneanything = 1; keepfile = 1; /* * as there are undefined symbols, we can assume that * there are modules on the module list by the time * we get here. */ lastmodule->next = malloc(sizeof(*lastmodule->next)); if (!lastmodule->next) { fprintf(stderr, "ldrdf: not enough memory\n"); exit(1); } lastmodule = lastmodule->next; memcpy(&lastmodule->f, &f, sizeof(f)); lastmodule->name = strdup(f.name); processmodule(f.name, lastmodule); break; } if (!keepfile) rdfclose(&f); } if (rdl_error != 0 && rdl_error != RDL_ENOTFOUND) rdl_perror("ldrdf", cur->name); cur = cur->next; } return doneanything; }