home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <a.out.h>
- #include "link.h"
-
- struct SYMBOL_REV {
- struct nlist n;
- struct symbol *child[2];
- char *version;
- };
-
- /*
- Try to read a module with symbole/version pairs added by genmodinfo
- */
- PUBLIC int MODULE::loadobj_withrev(
- const char *fname)
- {
- int ret = -1;
- FILE *fin = fopen(fname, "r");
- if (fin == NULL) {
- depmod_error("Cannot open %s", fname);
- }else{
- struct exec header;
- if (fread(&header, sizeof header, 1, fp)!=1){
- depmod_error ("Could not read header of %s", fname);
- }else if (N_MAGIC(header) != OMAGIC) {
- depmod_error ("%s: not an object file", fname);
- }else{
- // read in the symbol table
- fseek(fp, 0L, SEEK_END);
- long filesize = ftell(fp);
- fseek(fp, N_SYMOFF(header), SEEK_SET);
- int nbsym = header.a_syms / sizeof (struct nlist);
- SYMBOL_REV *symtab = (SYMBOL_REV*) malloc(nbsym
- * sizeof (SYMBOL_REV));
- if (symtab == NULL){
- depmod_error ("Can't allocate memory to read file %s"
- ,fname);
- }else{
- SYMBOL_REV *sp = symtab;
- for (int i = 0; i < nbsym; i++, sp++) {
- fread(&sp->n, sizeof sp->n, 1, fp);
- sp->child[0] = sp->child[1] = NULL;
- sp->version = NULL;
- }
- if (feof(fp) || ferror(fp)) {
- depmod_error ("Error reading %s", fname);
- }else{
- long len = filesize - N_STROFF(header);
- char *stringtab = (char*) malloc(len);
- if (stringtab != NULL){
- if (fread(stringtab, 1, len, fp) != len){
- depmod_error ("Error reading %s", filename);
- }
- symroot = NULL;
- for (i = nsymbols, sp = symtab ; --i >= 0 ; sp++) {
- pos = sp->n.n_un.n_strx;
- if (pos < 0 || pos >= len) {
- depmod_error ("Bad nlist entry");
- exit(2);
- }
- /* look up name and add sp to binary tree */
- findsym(stringtab + sp->n.n_un.n_strx, sp);
- if ((sp->n.n_type & N_EXT) && (sp->n.n_type != N_EXT))
- sp->n.n_other = DEF_BY_MODULE; /* abuse: mark extdef */
- else
- sp->n.n_other = 0; /* abuse: mark extref */
- }
-
- /* look for appended modinfo */
- for (i = 0, p = stringtab + len; i < len; --p, ++i) {
- if ((*p == '#') && (strncmp(p, "#modinfo\n", 9) == 0)) {
- struct symbol *xsp;
- char *nl;
- char use[10];
- char symname[SYM_MAX_NAME];
-
- modinfo = p;
- nl = strchr(p, '\n');
- ++nl;
- p = nl;
-
- while (nl && (nl < stringtab + len)) {
- if ((nl = strchr(p, '\n'))) {
- *nl = '\0';
- if ((nl != p) && (*p != '#') &&
- (sscanf(p, "%s%s", use, symname) == 2)) {
- xsp = findsym(symname, NULL);
- if (xsp) {
- p = nl;
- while (*--p > ' ')
- ;
- xsp->version = p + 1;
- }
-
- }
-
- ++nl;
- p = nl;
- }
- }
- break;
- }
- }
- fclose (fin);
- }
- return ret;
- }
-
-