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); }
/* * 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; }