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

📄 outelf.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 3 页
字号:
    elf_section_header (0, 0, 0, NULL, FALSE, 0L, 0, 0, 0, 0); /* SHN_UNDEF */    scount=1; /* needed for the stabs debugging to track the symtable section */    p = shstrtab+1;    for (i=0; i<nsects; i++) {	elf_section_header (p - shstrtab, sects[i]->type, sects[i]->flags,			    (sects[i]->type == SHT_PROGBITS ?			     sects[i]->data : NULL), TRUE,			    sects[i]->len, 0, 0, sects[i]->align, 0);	p += strlen(p)+1;	scount++; /* dito */    }    elf_section_header (p - shstrtab, 1, 0, comment, FALSE,			(long)commlen, 0, 0, 1, 0);/* .comment */    scount++; /* dito */    p += strlen(p)+1;    elf_section_header (p - shstrtab, 3, 0, shstrtab, FALSE,			(long)shstrtablen, 0, 0, 1, 0);/* .shstrtab */    scount++; /* dito */    p += strlen(p)+1;    elf_section_header (p - shstrtab, 2, 0, symtab, TRUE,			symtablen, nsects+4, symtablocal, 4, 16);/* .symtab */    symtabsection = scount; /* now we got the symtab section index in the ELF file */    p += strlen(p)+1;    elf_section_header (p - shstrtab, 3, 0, strs, TRUE,			strslen, 0, 0, 1, 0);	    /* .strtab */    for (i=0; i<nsects; i++) if (sects[i]->head) {	p += strlen(p)+1;	elf_section_header (p - shstrtab, 9, 0, sects[i]->rel, TRUE,			    sects[i]->rellen, nsects+3, i+1, 4, 8);    }    if (of_elf.current_dfmt == &df_stabs) {      /* for debugging information, create the last three sections	 which are the .stab , .stabstr and .rel.stab sections respectively */      /* this function call creates the stab sections in memory */      stabs_generate();      if ((stabbuf)&&(stabstrbuf)&&(stabrelbuf)) {	      p += strlen(p)+1;	      elf_section_header(p-shstrtab,1,0,stabbuf,0,stablen,nsections-2,0,4,12);	      p += strlen(p)+1;	      elf_section_header(p-shstrtab,3,0,stabstrbuf,0,stabstrlen,0,0,4,0);	      p += strlen(p)+1;	      /* link -> symtable  info -> section to refer to */	      elf_section_header(p-shstrtab,9,0,stabrelbuf,0,stabrellen,symtabsection,nsections-3,4,8);      }    }    fwrite (align_str, align, 1, elffp);    /*     * Now output the sections.     */    elf_write_sections();    nasm_free (elf_sects);    saa_free (symtab);}static struct SAA *elf_build_symtab (long *len, long *local){    struct SAA *s = saa_init(1L);    struct Symbol *sym;    unsigned char entry[16], *p;    int i;    *len = *local = 0;    /*     * First, an all-zeros entry, required by the ELF spec.     */    saa_wbytes (s, NULL, 16L);	       /* null symbol table entry */    *len += 16;    (*local)++;    /*     * Next, an entry for the file name.     */    p = entry;    WRITELONG (p, 1);		       /* we know it's 1st thing in strtab */    WRITELONG (p, 0);		       /* no value */    WRITELONG (p, 0);		       /* no size either */    WRITESHORT (p, 4);		       /* type FILE */    WRITESHORT (p, SHN_ABS);    saa_wbytes (s, entry, 16L);    *len += 16;    (*local)++;    /*     * Now some standard symbols defining the segments, for relocation     * purposes.     */    for (i = 1; i <= nsects+1; i++) {	p = entry;	WRITELONG (p, 0);	       /* no symbol name */	WRITELONG (p, 0);	       /* offset zero */	WRITELONG (p, 0);	       /* size zero */	WRITESHORT (p, 3);	       /* local section-type thing */	WRITESHORT (p, (i==1 ? SHN_ABS : i-1));   /* the section id */	saa_wbytes (s, entry, 16L);	*len += 16;	(*local)++;    }    /*     * Now the other local symbols.     */    saa_rewind (syms);    while ( (sym = saa_rstruct (syms)) ) {	if (sym->type & SYM_GLOBAL)	    continue;	p = entry;	WRITELONG (p, sym->strpos);	WRITELONG (p, sym->value);	WRITELONG (p, sym->size);	WRITESHORT (p, sym->type);     /* local non-typed thing */	WRITESHORT (p, sym->section);	saa_wbytes (s, entry, 16L);        *len += 16;	(*local)++;    }    /*     * Now the global symbols.     */    saa_rewind (syms);    while ( (sym = saa_rstruct (syms)) ) {	if (!(sym->type & SYM_GLOBAL))	    continue;	p = entry;	WRITELONG (p, sym->strpos);	WRITELONG (p, sym->value);	WRITELONG (p, sym->size);	WRITESHORT (p, sym->type);     /* global non-typed thing */	WRITESHORT (p, sym->section);	saa_wbytes (s, entry, 16L);	*len += 16;    }    return s;}static struct SAA *elf_build_reltab (long *len, struct Reloc *r) {    struct SAA *s;    unsigned char *p, entry[8];    if (!r)	return NULL;    s = saa_init(1L);    *len = 0;    while (r) {	long sym = r->symbol;	if (sym >= GLOBAL_TEMP_BASE)	    sym += -GLOBAL_TEMP_BASE + (nsects+3) + nlocals;	p = entry;	WRITELONG (p, r->address);	WRITELONG (p, (sym << 8) + r->type);	saa_wbytes (s, entry, 8L);	*len += 8;	r = r->next;    }    return s;}static void elf_section_header (int name, int type, int flags,				void *data, int is_saa, long datalen,				int link, int info, int align, int eltsize){    elf_sects[elf_nsect].data = data;    elf_sects[elf_nsect].len = datalen;    elf_sects[elf_nsect].is_saa = is_saa;    elf_nsect++;    fwritelong ((long)name, elffp);    fwritelong ((long)type, elffp);    fwritelong ((long)flags, elffp);    fwritelong (0L, elffp);	       /* no address, ever, in object files */    fwritelong (type == 0 ? 0L : elf_foffs, elffp);    fwritelong (datalen, elffp);    if (data)	elf_foffs += (datalen+SEG_ALIGN_1) & ~SEG_ALIGN_1;    fwritelong ((long)link, elffp);    fwritelong ((long)info, elffp);    fwritelong ((long)align, elffp);    fwritelong ((long)eltsize, elffp);}static void elf_write_sections (void){    int i;    for (i = 0; i < elf_nsect; i++)	if (elf_sects[i].data) {	    long len = elf_sects[i].len;	    long reallen = (len+SEG_ALIGN_1) & ~SEG_ALIGN_1;	    long align = reallen - len;	    if (elf_sects[i].is_saa)		saa_fpwrite (elf_sects[i].data, elffp);	    else		fwrite (elf_sects[i].data, len, 1, elffp);	    fwrite (align_str, align, 1, elffp);	}}static void elf_sect_write (struct Section *sect,			     const unsigned char *data, unsigned long len) {    saa_wbytes (sect->data, data, len);    sect->len += len;}static long elf_segbase (long segment) {    return segment;}static int elf_directive (char *directive, char *value, int pass) {    return 0;}static void elf_filename (char *inname, char *outname, efunc error) {    strcpy(elf_module, inname);    standard_extension (inname, outname, ".o", error);}static const char *elf_stdmac[] = {    "%define __SECT__ [section .text]",    "%macro __NASM_CDecl__ 1",    "%define $_%1 $%1",    "%endmacro",    NULL};static int elf_set_info(enum geninfo type, char **val){    return 0;}static struct dfmt df_stabs = {  "ELF32 (i386) stabs debug format for Linux",  "stabs",  stabs_init,  stabs_linenum,  stabs_deflabel,  stabs_directive,  stabs_typevalue,  stabs_output,  stabs_cleanup};struct dfmt *elf_debugs_arr[2]={&df_stabs,NULL};struct ofmt of_elf = {    "ELF32 (i386) object files (e.g. Linux)",    "elf",    NULL,    elf_debugs_arr,    &null_debug_form,    elf_stdmac,    elf_init,    elf_set_info,    elf_out,    elf_deflabel,    elf_section_names,    elf_segbase,    elf_directive,    elf_filename,    elf_cleanup};/* again, the stabs debugging stuff (code) */void stabs_init(struct ofmt *of,void *id,FILE *fp,efunc error){}void stabs_linenum(const char *filename,long linenumber,long segto){  if (!stabs_filename) {    stabs_filename = (char *)nasm_malloc(strlen(filename)+1);    strcpy(stabs_filename,filename);  } else {    if (strcmp(stabs_filename,filename)) {      /* yep, a memory leak...this program is one-shot anyway, so who cares...	 in fact, this leak comes in quite handy to maintain a list of files	 encountered so far in the symbol lines... */           /* why not nasm_free(stabs_filename); we're done with the old one */            stabs_filename = (char *)nasm_malloc(strlen(filename)+1);      strcpy(stabs_filename,filename);    }  }  stabs_immcall=1;  currentline=linenumber;}void stabs_deflabel(char *name,long segment,long offset,int is_global,char *special){}void stabs_directive(const char *directive,const char *params){}void stabs_typevalue(long type){}void stabs_output(int type,void *param){  struct symlininfo *s;  struct linelist *el;  if (type==TY_STABSSYMLIN) {    if (stabs_immcall) {      s=(struct symlininfo *)param;      if (strcmp( s->name,".text")) return; /* we are only interested in the text stuff */      numlinestabs++;      el=(struct linelist *)nasm_malloc(sizeof(struct linelist));      el->info.offset=s->offset;      el->info.section=s->section;      el->info.name=s->name;      el->line=currentline;      el->filename=stabs_filename;      el->next=0;      if (stabslines) {	stabslines->last->next=el;	stabslines->last=el;      } else {	stabslines=el;	stabslines->last=el;      }    }  }  stabs_immcall=0;}#define WRITE_STAB(p,n_strx,n_type,n_other,n_desc,n_value) \  do {\    WRITELONG(p,n_strx); \    WRITECHAR(p,n_type); \    WRITECHAR(p,n_other); \    WRITESHORT(p,n_desc); \    WRITELONG(p,n_value); \  } while (0)/* for creating the .stab , .stabstr and .rel.stab sections in memory */void stabs_generate(void){  int i,numfiles,strsize,numstabs=0,currfile,mainfileindex;  unsigned char *sbuf,*ssbuf,*rbuf,*sptr,*rptr;  char **allfiles;  int *fileidx;  struct linelist *ptr;  ptr=stabslines;  allfiles = (char **)nasm_malloc(numlinestabs*sizeof(char *));  for (i=0;i<numlinestabs;i++) allfiles[i]=0;  numfiles=0;  while (ptr) {    if (numfiles==0) {      allfiles[0]=ptr->filename;      numfiles++;    } else {      for (i=0;i<numfiles;i++) {	if (!strcmp(allfiles[i],ptr->filename)) break;      }      if (i>=numfiles) {	allfiles[i]=ptr->filename;	numfiles++;      }    }    ptr=ptr->next;  }  strsize=1;  fileidx = (int *)nasm_malloc(numfiles*sizeof(int));  for (i=0;i<numfiles;i++) {    fileidx[i]=strsize;    strsize+=strlen(allfiles[i])+1;  }	mainfileindex=0;  for (i=0;i<numfiles;i++) {  	if (!strcmp(allfiles[i],elf_module)) {  		mainfileindex=i;  		break;		}	}		  			/* worst case size of the stab buffer would be:		the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line		*/  sbuf = (unsigned char *)nasm_malloc((numlinestabs*2+3)*sizeof(struct stabentry));  ssbuf = (unsigned char *)nasm_malloc(strsize);  rbuf = (unsigned char *)nasm_malloc(numlinestabs*8*(2+3));  rptr=rbuf;  for (i=0;i<numfiles;i++) {    strcpy((char *)ssbuf+fileidx[i],allfiles[i]);  }  ssbuf[0]=0;  stabstrlen = strsize; /* set global variable for length of stab strings */  sptr=sbuf;  /* this is the first stab, its strx points to the filename of the     the source-file, the n_desc field should be set to the number     of remaining stabs  */  WRITE_STAB(sptr, fileidx[0], 0, 0, 0, strlen(allfiles[0]+12));  ptr=stabslines;  numstabs = 0;  if ( ptr ) {    /* this is the stab for the main source file */    WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);        /* relocation stuff */    /* IS THIS SANE?  WHAT DOES SECTION+3 MEAN HERE? */    WRITELONG(rptr, (sptr-sbuf)-4);    WRITELONG(rptr, ((ptr->info.section+3)<<8)|R_386_32);        numstabs++;    currfile=mainfileindex;  }  while (ptr) {    if (strcmp(allfiles[currfile],ptr->filename)) {      /* oops file has changed... */      for (i=0;i<numfiles;i++) if (!strcmp(allfiles[i],ptr->filename)) break;      currfile=i;      WRITE_STAB(sptr,fileidx[currfile],N_SOL,0,0,ptr->info.offset);      numstabs++;      /* relocation stuff */    /* IS THIS SANE?  WHAT DOES SECTION+3 MEAN HERE? */      WRITELONG(rptr, (sptr-sbuf)-4);      WRITELONG(rptr, ((ptr->info.section+3)<<8)|R_386_32);    }    WRITE_STAB(sptr,0,N_SLINE,0,ptr->line,ptr->info.offset);    numstabs++;    /* relocation stuff */    /* IS THIS SANE?  WHAT DOES SECTION+3 MEAN HERE? */    WRITELONG(rptr, (sptr-sbuf)-4);    WRITELONG(rptr, ((ptr->info.section+3)<<8)|R_386_32);    ptr=ptr->next;  }  ((struct stabentry *)sbuf)->n_desc=numstabs;  nasm_free(allfiles);  nasm_free(fileidx);  stablen = (sptr-sbuf);  stabrellen=(rptr-rbuf);  stabrelbuf= rbuf;  stabbuf = sbuf;  stabstrbuf = ssbuf;}void stabs_cleanup() {  struct linelist *ptr,*del;  if (!stabslines) return;  ptr=stabslines;  while (ptr) {    del=ptr;    ptr=ptr->next;    nasm_free(del);  }  if (stabbuf) nasm_free(stabbuf);  if (stabrelbuf) nasm_free(stabrelbuf);  if (stabstrbuf) nasm_free(stabstrbuf);}#endif /* OF_ELF */

⌨️ 快捷键说明

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