📄 outelf.c
字号:
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 + -