pe-dll.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,946 行 · 第 1/4 页

C
1,946
字号
    {      if (pe_def_file->name)	{	  if (pe_def_file->is_dll)	    fprintf (out, "LIBRARY ");	  else	    fprintf (out, "NAME ");	  quoteput (pe_def_file->name, out, 1);	  if (pe_data (output_bfd)->pe_opthdr.ImageBase)	    fprintf (out, " BASE=0x%lx",		     (unsigned long) pe_data (output_bfd)->pe_opthdr.ImageBase);	  fprintf (out, "\n");	}      if (pe_def_file->description)	{	  fprintf (out, "DESCRIPTION ");	  quoteput (pe_def_file->description, out, 1);	  fprintf (out, "\n");	}      if (pe_def_file->version_minor != -1)	fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major,		 pe_def_file->version_minor);      else if (pe_def_file->version_major != -1)	fprintf (out, "VERSION %d\n", pe_def_file->version_major);      if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1)	fprintf (out, "\n");      if (pe_def_file->stack_commit != -1)	fprintf (out, "STACKSIZE 0x%x,0x%x\n",		 pe_def_file->stack_reserve, pe_def_file->stack_commit);      else if (pe_def_file->stack_reserve != -1)	fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve);      if (pe_def_file->heap_commit != -1)	fprintf (out, "HEAPSIZE 0x%x,0x%x\n",		 pe_def_file->heap_reserve, pe_def_file->heap_commit);      else if (pe_def_file->heap_reserve != -1)	fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve);      if (pe_def_file->num_section_defs > 0)	{	  fprintf (out, "\nSECTIONS\n\n");	  for (i = 0; i < pe_def_file->num_section_defs; i++)	    {	      fprintf (out, "    ");	      quoteput (pe_def_file->section_defs[i].name, out, 0);	      if (pe_def_file->section_defs[i].class)		{		  fprintf (out, " CLASS ");		  quoteput (pe_def_file->section_defs[i].class, out, 0);		}	      if (pe_def_file->section_defs[i].flag_read)		fprintf (out, " READ");	      if (pe_def_file->section_defs[i].flag_write)		fprintf (out, " WRITE");	      if (pe_def_file->section_defs[i].flag_execute)		fprintf (out, " EXECUTE");	      if (pe_def_file->section_defs[i].flag_shared)		fprintf (out, " SHARED");	      fprintf (out, "\n");	    }	}      if (pe_def_file->num_exports > 0)	{	  fprintf (out, "\nEXPORTS\n\n");	  for (i = 0; i < pe_def_file->num_exports; i++)	    {	      def_file_export *e = pe_def_file->exports + i;	      fprintf (out, "    ");	      quoteput (e->name, out, 0);	      if (e->internal_name && strcmp (e->internal_name, e->name))		{		  fprintf (out, " = ");		  quoteput (e->internal_name, out, 0);		}	      if (e->ordinal != -1)		fprintf (out, " @%d", e->ordinal);	      if (e->flag_private)		fprintf (out, " PRIVATE");	      if (e->flag_constant)		fprintf (out, " CONSTANT");	      if (e->flag_noname)		fprintf (out, " NONAME");	      if (e->flag_data)		fprintf (out, " DATA");	      fprintf (out, "\n");	    }	}      if (pe_def_file->num_imports > 0)	{	  fprintf (out, "\nIMPORTS\n\n");	  for (i = 0; i < pe_def_file->num_imports; i++)	    {	      def_file_import *im = pe_def_file->imports + i;	      fprintf (out, "    ");	      if (im->internal_name		  && (!im->name || strcmp (im->internal_name, im->name)))		{		  quoteput (im->internal_name, out, 0);		  fprintf (out, " = ");		}	      quoteput (im->module->name, out, 0);	      fprintf (out, ".");	      if (im->name)		quoteput (im->name, out, 0);	      else		fprintf (out, "%d", im->ordinal);	      fprintf (out, "\n");	    }	}    }  else    fprintf (out, _("; no contents available\n"));  if (fclose (out) == EOF)    {      /* xgettext:c-format */      einfo (_("%P: Error closing file `%s'\n"), pe_out_def_filename);    }}/************************************************************************ Generate the import library ************************************************************************/static asymbol **symtab;static int symptr;static int tmp_seq;static const char *dll_filename;static char *dll_symname;#define UNDSEC (asection *) &bfd_und_sectionstatic asection *quick_section (abfd, name, flags, align)     bfd *abfd;     const char *name;     int flags;     int align;{  asection *sec;  asymbol *sym;  sec = bfd_make_section_old_way (abfd, name);  bfd_set_section_flags (abfd, sec, flags | SEC_ALLOC | SEC_LOAD | SEC_KEEP);  bfd_set_section_alignment (abfd, sec, align);  /* Remember to undo this before trying to link internally!  */  sec->output_section = sec;  sym = bfd_make_empty_symbol (abfd);  symtab[symptr++] = sym;  sym->name = sec->name;  sym->section = sec;  sym->flags = BSF_LOCAL;  sym->value = 0;  return sec;}static voidquick_symbol (abfd, n1, n2, n3, sec, flags, addr)     bfd *abfd;     char *n1;     char *n2;     char *n3;     asection *sec;     int flags;     int addr;{  asymbol *sym;  char *name = (char *) xmalloc (strlen (n1) + strlen (n2) + strlen (n3) + 1);  strcpy (name, n1);  strcat (name, n2);  strcat (name, n3);  sym = bfd_make_empty_symbol (abfd);  sym->name = name;  sym->section = sec;  sym->flags = flags;  sym->value = addr;  symtab[symptr++] = sym;}static arelent *reltab = 0;static int relcount = 0, relsize = 0;static voidquick_reloc (abfd, address, which_howto, symidx)     bfd *abfd;     int address;     int which_howto;     int symidx;{  if (relcount >= (relsize - 1))    {      relsize += 10;      if (reltab)	reltab = (arelent *) xrealloc (reltab, relsize * sizeof (arelent));      else	reltab = (arelent *) xmalloc (relsize * sizeof (arelent));    }  reltab[relcount].address = address;  reltab[relcount].addend = 0;  reltab[relcount].howto = bfd_reloc_type_lookup (abfd, which_howto);  reltab[relcount].sym_ptr_ptr = symtab + symidx;  relcount++;}static voidsave_relocs (asection *sec){  int i;  sec->relocation = reltab;  sec->reloc_count = relcount;  sec->orelocation = (arelent **) xmalloc ((relcount + 1) * sizeof (arelent *));  for (i = 0; i < relcount; i++)    sec->orelocation[i] = sec->relocation + i;  sec->orelocation[relcount] = 0;  sec->flags |= SEC_RELOC;  reltab = 0;  relcount = relsize = 0;}/* *	.section	.idata$2 *	.global		__head_my_dll * __head_my_dll: *	.rva		hname *	.long		0 *	.long		0 *	.rva		__my_dll_iname *	.rva		fthunk * *	.section	.idata$5 *	.long		0 * fthunk: * *	.section	.idata$4 *	.long		0 * hname: */static bfd *make_head (parent)     bfd *parent;{  asection *id2, *id5, *id4;  unsigned char *d2, *d5, *d4;  char *oname;  bfd *abfd;  oname = (char *) xmalloc (20);  sprintf (oname, "d%06d.o", tmp_seq);  tmp_seq++;  abfd = bfd_create (oname, parent);  bfd_find_target (pe_details->object_target, abfd);  bfd_make_writable (abfd);  bfd_set_format (abfd, bfd_object);  bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);  symptr = 0;  symtab = (asymbol **) xmalloc (6 * sizeof (asymbol *));  id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);  id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);  id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);  quick_symbol (abfd, U ("_head_"), dll_symname, "", id2, BSF_GLOBAL, 0);  quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);  /* OK, pay attention here.  I got confused myself looking back at     it.  We create a four-byte section to mark the beginning of the     list, and we include an offset of 4 in the section, so that the     pointer to the list points to the *end* of this section, which is     the start of the list of sections from other objects.  */  bfd_set_section_size (abfd, id2, 20);  d2 = (unsigned char *) xmalloc (20);  id2->contents = d2;  memset (d2, 0, 20);  d2[0] = d2[16] = 4; /* reloc addend */  quick_reloc (abfd,  0, BFD_RELOC_RVA, 2);  quick_reloc (abfd, 12, BFD_RELOC_RVA, 4);  quick_reloc (abfd, 16, BFD_RELOC_RVA, 1);  save_relocs (id2);  bfd_set_section_size (abfd, id5, 4);  d5 = (unsigned char *) xmalloc (4);  id5->contents = d5;  memset (d5, 0, 4);  bfd_set_section_size (abfd, id4, 4);  d4 = (unsigned char *) xmalloc (4);  id4->contents = d4;  memset (d4, 0, 4);  bfd_set_symtab (abfd, symtab, symptr);  bfd_set_section_contents (abfd, id2, d2, 0, 20);  bfd_set_section_contents (abfd, id5, d5, 0, 4);  bfd_set_section_contents (abfd, id4, d4, 0, 4);  bfd_make_readable (abfd);  return abfd;}/* *	.section	.idata$4 *	.long		0 *	.section	.idata$5 *	.long		0 *	.section	idata$7 *	.global		__my_dll_iname *__my_dll_iname: *	.asciz		"my.dll" */static bfd *make_tail (parent)     bfd *parent;{  asection *id4, *id5, *id7;  unsigned char *d4, *d5, *d7;  int len;  char *oname;  bfd *abfd;  oname = (char *) xmalloc (20);  sprintf (oname, "d%06d.o", tmp_seq);  tmp_seq++;  abfd = bfd_create (oname, parent);  bfd_find_target (pe_details->object_target, abfd);  bfd_make_writable (abfd);  bfd_set_format (abfd, bfd_object);  bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);  symptr = 0;  symtab = (asymbol **) xmalloc (5 * sizeof (asymbol *));  id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);  id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);  id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);  quick_symbol (abfd, U (""), dll_symname, "_iname", id7, BSF_GLOBAL, 0);  bfd_set_section_size (abfd, id4, 4);  d4 = (unsigned char *) xmalloc (4);  id4->contents = d4;  memset (d4, 0, 4);  bfd_set_section_size (abfd, id5, 4);  d5 = (unsigned char *) xmalloc (4);  id5->contents = d5;  memset (d5, 0, 4);  len = strlen (dll_filename) + 1;  if (len & 1)    len++;  bfd_set_section_size (abfd, id7, len);  d7 = (unsigned char *) xmalloc (len);  id7->contents = d7;  strcpy (d7, dll_filename);  bfd_set_symtab (abfd, symtab, symptr);  bfd_set_section_contents (abfd, id4, d4, 0, 4);  bfd_set_section_contents (abfd, id5, d5, 0, 4);  bfd_set_section_contents (abfd, id7, d7, 0, len);  bfd_make_readable (abfd);  return abfd;}/* *	.text *	.global		_function *	.global		___imp_function *	.global		__imp__function *_function: *	jmp		*__imp__function: * *	.section	idata$7 *	.long		__head_my_dll * *	.section	.idata$5 *___imp_function: *__imp__function: *iat? *	.section	.idata$4 *iat? *	.section	.idata$6 *ID<ordinal>: *	.short		<hint> *	.asciz		"function" xlate? (add underscore, kill at) */static unsigned char jmp_ix86_bytes[] = {  0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90};/* *_function: *	mov.l	ip+8,r0 *	mov.l	@r0,r0 *	jmp	@r0 *	nop *	.dw	__imp_function */static unsigned char jmp_sh_bytes[] = {  0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00};/* *_function: *	lui	$t0,<high:__imp_function> *	lw	$t0,<low:__imp_function> *	jr	$t0 *	nop */static unsigned char jmp_mips_bytes[] = {  0x00, 0x00, 0x08, 0x3c,  0x00, 0x00, 0x08, 0x8d,  0x08, 0x00, 0x00, 0x01,  0x00, 0x00, 0x00, 0x00};static bfd *make_one (exp, parent)     def_file_export *exp;     bfd *parent;{  asection *tx, *id7, *id5, *id4, *id6;  unsigned char *td = NULL, *d7, *d5, *d4, *d6 = NULL;  int len;  char *oname;  bfd *abfd;  unsigned char *jmp_bytes = NULL;  int jmp_byte_count = 0;  switch (pe_details->pe_arch)    {    case PE_ARCH_i386:      jmp_bytes = jmp_ix86_bytes;      jmp_byte_count = sizeof (jmp_ix86_bytes);      break;    case PE_ARCH_sh:      jmp_bytes = jmp_sh_bytes;      jmp_byte_count = sizeof (jmp_sh_bytes);      break;    case PE_ARCH_mips:      jmp_bytes = jmp_mips_bytes;      jmp_byte_count = sizeof (jmp_mips_bytes);      break;    }  oname = (char *) xmalloc (20);  sprintf (oname, "d%06d.o", tmp_seq);  tmp_seq++;  abfd = bfd_create (oname, parent);  bfd_find_target (pe_details->object_target, abfd);  bfd_make_writable (abfd);  bfd_set_format (abfd, bfd_object);  bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);  symptr = 0;  symtab = (asymbol **) xmalloc (10 * sizeof (asymbol *));  tx  = quick_section (abfd, ".text",    SEC_CODE|SEC_HAS_CONTENTS, 2);  id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);  id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);  id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);  id6 = quick_section (abfd, ".idata$6", SEC_HAS_CONTENTS, 2);  if (! exp->flag_data)    quick_symbol (abfd, U (""), exp->internal_name, "", tx, BSF_GLOBAL, 0);  quick_symbol (abfd, U ("_head_"), dll_symname, "", UNDSEC, BSF_GLOBAL, 0);  quick_symbol (abfd, U ("_imp__"), exp->internal_name, "", id5, BSF_GLOBAL, 0);  if (pe_dll_compat_implib)    quick_symbol (abfd, U ("__imp_"), exp->internal_name, "",		  id5, BSF_GLOBAL, 0);

⌨️ 快捷键说明

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