Ejemplo n.º 1
0
void loadmodule(const char * filename)
{
    if (options.verbose)
	printf("loading `%s'\n", filename);

    /* allocate a new module entry on the end of the modules list */
    if (!modules)
    {
	modules = malloc (sizeof(*modules));
	lastmodule = modules;
    }
    else
    {
	lastmodule->next = malloc (sizeof(*modules));
	lastmodule = lastmodule->next;
    }

    if ( ! lastmodule)
    {
	fprintf(stderr, "ldrdf: out of memory\n");
	exit(1);
    }

    /* open the file using 'rdfopen', which returns nonzero on error */

    if (rdfopen(&lastmodule->f, filename) != 0)
    {
	rdfperror("ldrdf", filename);
	exit(1);
    }

    /* 
     * store information about the module, and determine what segments
     * it contains, and what we should do with them (determine relocation
     * factor if we decide to keep them)
     */

    lastmodule->header = NULL;
    lastmodule->name = strdup(filename);
    lastmodule->next = NULL;

    processmodule(filename, lastmodule);
}
Ejemplo n.º 2
0
Archivo: ldrdf.c Proyecto: aosm/nasm
/*
 * search_libraries()
 *
 * scans through the list of libraries, attempting to match symbols
 * defined in library modules against symbols that are referenced but
 * not defined (segment = -1 in the symbol table)
 *
 * returns 1 if any extra library modules are included, indicating that
 * another pass through the library list should be made (possibly).
 */
int search_libraries()
{
    struct librarynode *cur;
    rdffile f;
    int i;
    void *header;
    int segment;
    long offset;
    int doneanything = 0, pass = 1, keepfile;
    rdfheaderrec *hr;

    cur = libraries;

    while (cur) {
        if (options.verbose > 2)
            printf("scanning library `%s', pass %d...\n", cur->name, pass);

        for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++) {
            if (pass == 2 && lookformodule(f.name))
                continue;

            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 != RDFREC_GLOBAL)
                    continue;

                /*
                 * If the symbol is marked as SYM_GLOBAL, somebody will be
                 * definitely interested in it..
                 */
                if ((hr->e.flags & SYM_GLOBAL) == 0) {
                    /*
                     * otherwise the symbol is just public. Find it 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);
                lastmodule->next = NULL;
                processmodule(f.name, lastmodule);
                break;
            }
            if (!keepfile) {
                free(f.name);
                f.name = NULL;
                f.fp = NULL;
            }
        }
        if (rdl_error != 0 && rdl_error != RDL_ENOTFOUND)
            rdl_perror("ldrdf", cur->name);

        cur = cur->next;
        if (cur == NULL && pass == 1) {
            cur = libraries;
            pass++;
        }
    }

    return doneanything;
}