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

📄 ldrdf.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 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 + -