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;
}
Beispiel #2
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;
}