⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldrdf.c

📁 一个免费的汇编语言编译器的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		switch (hr->r.length)
		{
		case 1:
		    offset += *data;
		    if (offset < -127 || offset > 128)
			fprintf(error_file, "warning: relocation out of range "
				"at %s(%02x:%08lx)\n", cur->name,
				(int)hr->r.segment, hr->r.offset);
		    *data = (char) offset;
		    break;
		case 2:
		    offset += * (short *)data;
		    if (offset < -32767 || offset > 32768)
			fprintf(error_file, "warning: relocation out of range "
				"at %s(%02x:%08lx)\n", cur->name,
				(int)hr->r.segment, hr->r.offset);
		    * (short *)data = (short) offset;
		    break;
		case 4:
		    * (long *)data += offset;
		    /* we can't easily detect overflow on this one */
		    break;
		}

		/*
		 * If the relocation was relative between two symbols in
		 * the same segment, then we're done.
		 *
		 * Otherwise, we need to output a new relocation record
		 * with the references updated segment and offset...
		 */
		if (! isrelative || cur->seginfo[localseg].dest_seg != seg)
		{
		    hr->r.segment = cur->seginfo[localseg].dest_seg;
		    hr->r.offset += cur->seginfo[localseg].reloc;
		    hr->r.refseg = seg;
		    if (isrelative)
		    	hr->r.segment += 64;
		    rdfaddheader(rdfheader, hr);
		}
		break;

	    case RDFREC_IMPORT:		/* import symbol */
	    case RDFREC_FARIMPORT:
		/*
		 * scan the global symbol table for the symbol
		 * and associate its location with the segment number 
		 * for this module
		 */
		se = symtabFind(symtab, hr->i.label);
		if (!se || se->segment == -1) {
		    if (options.warnUnresolved) {
		    	switch (options.warnUnresolved) {
			    case 1:
				fprintf(error_file, "warning");
				break;
			    case 2:
				fprintf(error_file, "error");
				errorcount++;
			}
			fprintf(error_file, ": unresolved reference to `%s'"
				" in module `%s'\n", hr->i.label, cur->name);
		    }
		    /*
		     * we need to allocate a segment number for this
		     * symbol, and store it in the symbol table for
		     * future reference
		     */ 
		    if (!se) {
			se=malloc(sizeof(*se));
			if (!se) {
			    fprintf(stderr, "ldrdf: out of memory\n");
			    exit(1);
			}
			se->name = strdup(hr->i.label);
			se->flags = 0;
			se->segment = availableseg++;
			se->offset = 0;
			symtabInsert(symtab, se);
		    }
		    else {
			se->segment = availableseg++;
			se->offset = 0;
		    }
		    /*
		     * output a header record that imports it to the
		     * recently allocated segment number...
		     */
		    newrec = *hr;
		    newrec.i.segment = se->segment;
		    rdfaddheader(rdfheader, &newrec);
		}

		add_seglocation(&segs, hr->i.segment, se->segment, se->offset);
		
		break;

	    case RDFREC_GLOBAL:		/* export symbol */
		/*
		 * need to insert an export for this symbol into the new
		 * header, unless we're stripping symbols. Even if we're
		 * stripping, put the symbol if it's marked as SYM_GLOBAL.
		 */
		if (options.strip && !(hr->e.flags & SYM_GLOBAL))
		    break;

		if (hr->e.segment == 2) {
		    seg = 2;
		    offset = cur->bss_reloc;
		}
		else {
		    localseg = rdffindsegment(&cur->f, hr->e.segment);
		    if (localseg == -1) {
			fprintf(stderr, "%s: exported symbol `%s' from "
				"unrecognised segment\n", cur->name,
				hr->e.label);
			errorcount++;
			break;
		    }
		    offset = cur->seginfo[localseg].reloc;
		    seg = cur->seginfo[localseg].dest_seg;
		}

		hr->e.segment = seg;	
		hr->e.offset += offset;
		rdfaddheader(rdfheader, hr);
		break;

	    case RDFREC_MODNAME:	 /* module name */
		 /*
		  * Insert module name record if export symbols
		  * are not stripped.
		  * If module name begins with '$' - insert it anyway.
		  */
		if (options.strip && hr->m.modname[0] != '$') break;
		rdfaddheader(rdfheader, hr);
		break;

	    case RDFREC_DLL:	 	/* DLL name */
		 /*
		  * Insert DLL name if it begins with '$'
		  */
		if (hr->d.libname[0] != '$') break;
		rdfaddheader(rdfheader, hr);
		break;

	    case RDFREC_SEGRELOC:	 /* segment fixup */
		/*
		 * modify the segment numbers if necessary, and
		 * pass straight through to the output module header
		 *
		 * *** FIXME ***
		 */
		if (hr->r.segment == 2) {
		    fprintf(stderr, "%s: segment fixup in BSS section\n",
			    cur->name);
		    errorcount++;
		    break;
		}
		localseg = rdffindsegment(&cur->f, hr->r.segment);
		if (localseg == -1) {
		    fprintf(stderr, "%s: segment fixup in unrecognised"
			    " segment (%d)\n", cur->name, hr->r.segment);
		    errorcount++;
		    break;
		}
		hr->r.segment = cur->seginfo[localseg].dest_seg;
		hr->r.offset += cur->seginfo[localseg].reloc;

		if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset))
		{
		    fprintf(stderr, "%s: segment fixup to undefined "
			    "segment %04x\n", cur->name, (int)hr->r.refseg);
		    errorcount++;
		    break;
		}
		hr->r.refseg = seg;
		rdfaddheader(rdfheader, hr);
		break;

	    case RDFREC_COMMON:		/* Common variable */
		/* Is this symbol already in the table? */
		se = symtabFind(symtab, hr->c.label);
		if (!se) {
		    printf("%s is not in symtab yet\n", hr->c.label);
		    break;
		}
		/* Add segment location */
		add_seglocation(&segs, hr->c.segment, se->segment, se->offset);
		break;
	    }
	}

	free(header);
	done_seglocations(&segs);

    }

    /*
     * combined BSS reservation for the entire results
     */
    newrec.type = RDFREC_BSS;
    newrec.b.reclen = 4;
    newrec.b.amount = bss_length;
    rdfaddheader(rdfheader, &newrec);

    /*
     * Write the header
     */
    for (i = 0; i < nsegs; i++)
    {
	if (i == 2) continue;
	rdfaddsegment (rdfheader, outputseg[i].length);
    }
    
    rdfwriteheader(f, rdfheader);
    rdfdoneheader(rdfheader);
    
    /*
     * Step through the segments, one at a time, writing out into
     * the output file
     */
    for (i = 0; i < nsegs; i++)
    {
	int16 s;
	long l;
	
	if (i == 2) continue;

	s = translateshort(outputseg[i].type);
	fwrite(&s, 2, 1, f);
	s = translateshort(outputseg[i].number);
	fwrite(&s, 2, 1, f);
	s = translateshort(outputseg[i].reserved);
	fwrite(&s, 2, 1, f);
	l = translatelong(outputseg[i].length);
	fwrite(&l, 4, 1, f);

	fwrite(outputseg[i].data, outputseg[i].length, 1, f);
    }

    fwrite("\0\0\0\0\0\0\0\0\0\0", 10, 1, f);
}

/* =========================================================================
 * Main program
 */

void usage()
{
    printf("usage:\n"
           "   ldrdf [options] object modules ... [-llibrary ...]\n"
           "   ldrdf -r\n"
           "options:\n"
           "   -v[=n]          increases verbosity by 1, or sets it to n\n"
           "   -a nn           sets segment alignment value (default 16)\n"
           "   -s              strips exported symbols\n"
           "   -x              warn about unresolved symbols\n"
           "   -o name         write output in file 'name'\n"
           "   -j path         specify objects search path\n"
           "   -L path         specify libraries search path\n"
           "   -g file         embed 'file' as a first header record with type 'generic'\n");
    exit(0);
}

int main(int argc, char ** argv)
{
    char * outname = "aout.rdf";
    int  moduleloaded = 0;
    char *respstrings[128] = {0, };

    options.verbose = 0;
    options.align = 16;
    options.warnUnresolved = 0;
    options.strip = 0;

    error_file = stderr;

    argc --, argv ++;
    if (argc == 0) usage();
    while (argc && *argv && **argv == '-' && argv[0][1] != 'l')
    {
	switch(argv[0][1]) {
	case 'r':
	    printf("ldrdf (linker for RDF files) version " LDRDF_VERSION "\n");
	    printf( _RDOFF_H "\n");
	    exit(0);
	case 'v':
	    if (argv[0][2] == '=') {
		options.verbose = argv[0][3] - '0';
		if (options.verbose < 0 || options.verbose > 9) {
		    fprintf(stderr, "ldrdf: verbosity level must be a number"
			    " between 0 and 9\n");
		    exit(1);
		}
	    }
	    else
		options.verbose++;
	    break;
	case 'a':
	    options.align = atoi(argv[1]);
	    if (options.align <= 0) {
		fprintf(stderr,
			"ldrdf: -a expects a positive number argument\n");
		exit(1);
	    }
	    argv++, argc--;
	    break;
	case 's':
	    options.strip = 1;
	    break;
	case 'x':
	    options.warnUnresolved = 1;
	    if (argv[0][2]=='e')
		options.warnUnresolved++;
	    break;
	case 'o':
	    outname = argv[1];
	    argv++, argc--;
	    break;
	case 'j':
	    if (!objpath) {
              options.objpath = 1;
	      objpath = argv[1];
	      argv++, argc--;
	      break;
	     } else {
	      fprintf(stderr,"ldrdf: more than one objects search path specified\n");
	      exit(1);
	     }
	case 'L':
	    if (!libpath) {
              options.libpath = 1;
	      libpath = argv[1];
	      argv++, argc--;
	      break;
	     } else {
	      fprintf(stderr,"ldrdf: more than one libraries search path specified\n");
	      exit(1);
	     }
	case '@': {
	      int i=0;
	      char buf[256];
	      FILE *f;

              options.respfile = 1;
	      if (argv[1] != NULL) f = fopen(argv[1],"r");
	    else {
		fprintf(stderr,"ldrdf: no response file name specified\n");
		exit(1);
	       }

	    if (f == NULL) {
		fprintf(stderr,"ldrdf: unable to open response file\n");
		exit(1);
	       }
	    
	    argv++, argc--;
	    while (fgets(buf, sizeof(buf), f) != NULL) {
		char *p;
		if (buf[0]=='\n') continue;
		if ((p = strchr(buf,'\n')) != NULL) *p = '\0';
		if (i >= 128) {
		  fprintf(stderr,"ldrdf: too many input files\n");
		  exit(1);
		 }
		*(respstrings+i) = newstr(buf);
		argc++, i++;
	       }
            break;
	 }
	case '2':
            options.stderr_redir = 1;
	    error_file = stdout;
	    break;
	case 'g':
	    generic_rec_file = argv[1];
	    argv++, argc--;
		break;    
	default:
	    usage();
	}
	argv++, argc--;
    }

    if (options.verbose > 4) {
	printf("ldrdf invoked with options:\n");
	printf("    section alignment: %d bytes\n", options.align);
	printf("    output name: `%s'\n", outname);
	if (options.strip)
	    printf("    strip symbols\n");
	if (options.warnUnresolved == 1)
	    printf("    warn about unresolved symbols\n");
	if (options.warnUnresolved == 2)
	    printf("    error if unresolved symbols\n");    
        if (options.objpath)
            printf("    objects search path: %s\n",objpath);
        if (options.libpath)
            printf("    libraries search path: %s\n",libpath);
	printf("\n");
    }

    symtab = symtabNew();
    initsegments();

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

    while (argc) {
	if (!*argv) argv = respstrings;
	if (!*argv) break;
	if (!strncmp(*argv, "-l", 2)) /* library */
         {
	  if(libpath) add_library(newstrcat(libpath,*argv + 2));
          else add_library(*argv + 2);
         }
	else {
	    if(objpath) loadmodule(newstrcat(objpath,*argv));
	    else loadmodule(*argv);
	    moduleloaded = 1;
	}
	argv++, argc--;
    }

    if (! moduleloaded) {
	printf("ldrdf: nothing to do. ldrdf -h for usage\n");
	return 0;
    }

    search_libraries();

    if (options.verbose > 2)
    {
	printf ("symbol table:\n");
	symtabDump(symtab, stdout);
    }

    write_output(outname);

    if (errorcount > 0)	exit(1);
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -