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 + -
显示快捷键?