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

📄 outrdf2.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 2 页
字号:
    ci.size = offset;    ci.segment = segment;    strncpy(ci.label, name, 32);    ci.label[32] = 0;    ci.reclen = 9 + strlen(ci.label);    ci.align = 0;        /*     * Check the special text to see if it's a valid number and power     * of two; if so, store it as the alignment for the common variable.     */    if (special) {	int err;        ci.align = readnum(special, &err);        if (err) error(ERR_NONFATAL, "alignment constraint `%s' is not a"                    	             " valid number", special);	else if ( (ci.align | (ci.align-1)) != 2*ci.align - 1)	    error(ERR_NONFATAL, "alignment constraint `%s' is not a"	                        " power of two", special);    }        write_common_rec(&ci);  }  /* We don't care about local labels or fix-up hints */  if (is_global != 1) return;  if (special) {    while(*special == ' ' || *special == '\t') special++;        if (!nasm_strnicmp(special, "export", 6)) {      special += 6;      export_flags |= SYM_GLOBAL;      }    if (*special) {      while(isspace(*special)) special++;      if (!nasm_stricmp(special, "far")) {        farsym = 1;      }      else if (!nasm_stricmp(special, "near")) {        farsym = 0;      }      else if (!nasm_stricmp(special, "proc") ||                !nasm_stricmp(special, "function")) {        export_flags |= SYM_FUNCTION;        }      else if (!nasm_stricmp(special, "data") ||               !nasm_stricmp(special, "object")) {        export_flags |= SYM_DATA;      }      else        error(ERR_NONFATAL, "unrecognised symbol type `%s'", special);    }	  }  if (name[0] == '.' && name[1] == '.' && name[2] != '@') {    error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);    return;  }  for (i = 0; i < nsegments; i++) {    if (segments[i].segnumber == segment>>1) break;  }  if (i >= nsegments) {   /* EXTERN declaration */    if (farsym)      ri.type = RDFREC_FARIMPORT;    else      ri.type = RDFREC_IMPORT;    ri.segment = segment;    strncpy(ri.label,name,32);    ri.label[32] = 0;    ri.reclen = 3 + strlen(ri.label);    write_import_rec(&ri);  } else if (is_global) {    r.type = RDFREC_GLOBAL;    r.flags = export_flags;    r.segment = segment;    r.offset = offset;    strncpy(r.label,name,32);    r.label[32] = 0;    r.reclen = 7 + strlen(r.label);    write_export_rec(&r);  }}static void membufwrite(int segment, const void * data, int bytes){  int i;  char buf[4], * b;  for (i = 0; i < nsegments; i++) {    if (segments[i].segnumber == segment) break;  }  if (i == nsegments)    error(ERR_PANIC, "can't find segment %d", segment);    if (bytes < 0) {    b = buf;    if (bytes == -2)      WRITESHORT(b,*(short *)data);    else      WRITELONG(b,*(long *)data);    data = buf;    bytes = -bytes;  }  segments[i].seglength += bytes;  saa_wbytes(seg[i],data,bytes);}static int getsegmentlength(int segment){  int i;  for (i = 0; i < nsegments; i++) {    if (segments[i].segnumber == segment) break;  }  if (i == nsegments)    error(ERR_PANIC, "can't find segment %d", segment);  return segments[i].seglength;}    static void rdf2_out (long segto, const void *data, unsigned long type,		     long segment, long wrt){  long bytes = type & OUT_SIZMASK;  struct RelocRec rr;  unsigned char databuf[4],*pd;  int seg;  if (segto == NO_SEG) {      if ((type & OUT_TYPMASK) != OUT_RESERVE)	  error (ERR_NONFATAL, "attempt to assemble code in ABSOLUTE space");      return;  }  segto >>= 1;    /* convert NASM segment no to RDF number */  for (seg = 0; seg < nsegments; seg++) {    if (segments[seg].segnumber == segto) break;  }  if (seg >= nsegments) {    error(ERR_NONFATAL,"specified segment not supported by rdf output format");    return;  }  if (wrt != NO_SEG) {    wrt = NO_SEG;		       /* continue to do _something_ */    error (ERR_NONFATAL, "WRT not supported by rdf output format");  }  type &= OUT_TYPMASK;  if (segto == 2 && type != OUT_RESERVE)  {      error(ERR_NONFATAL, "BSS segments may not be initialised");      /* just reserve the space for now... */      if (type == OUT_REL2ADR)	bytes = 2;      else	bytes = 4;      type = OUT_RESERVE;  }  if (type == OUT_RESERVE) {      if (segto == 2)		/* BSS segment space reserverd */	  bsslength += bytes;      else	while (bytes --)	    membufwrite(segto,databuf,1);  }  else if (type == OUT_RAWDATA) {      if (segment != NO_SEG)	  error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");      membufwrite(segto,data,bytes);  }  else if (type == OUT_ADDRESS) {    /* if segment == NO_SEG then we are writing an address of an       object within the same segment - do not produce reloc rec. */    /* FIXME - is this behaviour sane? at first glance it doesn't       appear to be. Must test this thoroughly...! */    if (segment != NO_SEG)    {	/* it's an address, so we must write a relocation record */	rr.type = RDFREC_RELOC;			/* type signature */	rr.reclen = 8;	rr.segment = segto;			/* segment we're currently in */	rr.offset = getsegmentlength(segto);	/* current offset */	rr.length = bytes;			/* length of reference */	rr.refseg = segment;			/* segment referred to */	write_reloc_rec(&rr);    }    pd = databuf;	/* convert address to little-endian */    if (bytes == 2)      WRITESHORT (pd, *(long *)data);    else      WRITELONG (pd, *(long *)data);    membufwrite(segto,databuf,bytes);  }  else if (type == OUT_REL2ADR)  {    if (segment == segto)      error(ERR_PANIC, "intra-segment OUT_REL2ADR");    rr.reclen = 8;    rr.offset = getsegmentlength(segto);	/* current offset */    rr.length = 2;		/* length of reference */    rr.refseg = segment;	/* segment referred to (will be >>1'd)*/    if (segment != NO_SEG && segment % 2) {      rr.type = RDFREC_SEGRELOC;      rr.segment = segto;	/* memory base refs *aren't ever* relative! */      write_reloc_rec(&rr);      /* what do we put in the code? Simply the data. This should almost       * always be zero, unless someone's doing segment arithmetic...       */      rr.offset = *(long *) data;    }    else    {      rr.type = RDFREC_RELOC;	/* type signature */      rr.segment = segto+64;	/* segment we're currently in + rel flag */      write_reloc_rec(&rr);      /* work out what to put in the code: offset of the end of this operand,       * subtracted from any data specified, so that loader can just add       * address of imported symbol onto it to get address relative to end of       * instruction: import_address + data(offset) - end_of_instrn */      rr.offset = *(long *)data -(rr.offset + bytes);    }        membufwrite(segto,&rr.offset,-2);  }  else if (type == OUT_REL4ADR)  {    if (segment == segto)      error(ERR_PANIC, "intra-segment OUT_REL4ADR");    if (segment != NO_SEG && segment % 2) {      error(ERR_PANIC, "erm... 4 byte segment base ref?");    }    rr.type = RDFREC_RELOC;	/* type signature */    rr.segment = segto+64;	/* segment we're currently in + rel tag */    rr.offset = getsegmentlength(segto);	/* current offset */    rr.length = 4;		/* length of reference */    rr.refseg = segment;	/* segment referred to */    rr.reclen = 8;    write_reloc_rec(&rr);    rr.offset = *(long *)data -(rr.offset + bytes);    membufwrite(segto,&rr.offset,-4);  }}static void rdf2_cleanup (int debuginfo) {  long		l;  struct BSSRec	bs;  int		i;    (void) debuginfo;  /* should write imported & exported symbol declarations to header here */  /* generate the output file... */  fwrite(RDOFF2Id,6,1,ofile);	/* file type magic number */  if (bsslength != 0)		/* reserve BSS */  {      bs.type = RDFREC_BSS;      bs.amount = bsslength;      bs.reclen = 4;      write_bss_rec(&bs);  }  /*   * calculate overall length of the output object   */  l = headerlength + 4;    for (i = 0; i < nsegments; i++) {    if (i == 2) continue;	/* skip BSS segment */    l += 10 + segments[i].seglength;  }  l += 10;	/* null segment */  fwritelong(l, ofile);  fwritelong(headerlength, ofile);  saa_fpwrite(header,ofile);	/* dump header */  saa_free(header);  for (i = 0; i < nsegments; i++) {    if (i == 2) continue;    fwriteshort(segments[i].segtype, ofile);    fwriteshort(segments[i].segnumber, ofile);    fwriteshort(segments[i].segreserved, ofile);    fwritelong(segments[i].seglength, ofile);    saa_fpwrite(seg[i], ofile);    saa_free(seg[i]);  }  /* null segment - write 10 bytes of zero */  fwritelong(0,ofile);  fwritelong(0,ofile);  fwriteshort(0,ofile);  fclose(ofile);}static long rdf2_segbase (long segment) {    return segment;}static int rdf2_directive (char *directive, char *value, int pass) {    struct DLLModRec r;    if (! strcmp(directive, "library")) {	if (pass == 1) {	    r.type = RDFREC_DLL;	    r.reclen=strlen(value)+1;	    strcpy(r.name, value);	    write_dllmod_rec(&r);	}	return 1;    }    if (! strcmp(directive, "module")) {	if (pass == 1) {	    r.type = RDFREC_MODNAME;	    r.reclen=strlen(value)+1;	    strcpy(r.name, value);	    write_dllmod_rec(&r);	}	return 1;    }        return 0;}static void rdf2_filename (char *inname, char *outname, efunc error) {  standard_extension(inname,outname,".rdf",error);}static const char *rdf2_stdmac[] = {    "%define __SECT__ [section .text]",    "%imacro library 1+.nolist",    "[library %1]",    "%endmacro",    "%imacro module 1+.nolist",    "[module %1]",    "%endmacro",    "%macro __NASM_CDecl__ 1",    "%endmacro",    NULL};static int rdf2_set_info(enum geninfo type, char **val){    return 0;}struct ofmt of_rdf2 = {  "Relocatable Dynamic Object File Format v2.0",  "rdf",  NULL,  null_debug_arr,  &null_debug_form,  rdf2_stdmac,  rdf2_init,  rdf2_set_info,  rdf2_out,  rdf2_deflabel,  rdf2_section_names,  rdf2_segbase,  rdf2_directive,  rdf2_filename,  rdf2_cleanup};#endif /* OF_RDF2 */

⌨️ 快捷键说明

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