pe.em
来自「基于4个mips核的noc设计」· EM 代码 · 共 1,678 行 · 第 1/4 页
EM
1,678 行
LANG_FOR_EACH_INPUT_STATEMENT (is) { if (is->the_bfd->my_archive) { int idata2 = 0, reloc_count=0, is_imp = 0; asection *sec; /* See if this is an import library thunk. */ for (sec = is->the_bfd->sections; sec; sec = sec->next) { if (strcmp (sec->name, ".idata\$2") == 0) idata2 = 1; if (strncmp (sec->name, ".idata\$", 7) == 0) is_imp = 1; reloc_count += sec->reloc_count; } if (is_imp && !idata2 && reloc_count) { /* It is, look for the reference to head and see if it's from our own library. */ for (sec = is->the_bfd->sections; sec; sec = sec->next) { int i; long symsize; long relsize; asymbol **symbols; arelent **relocs; int nrelocs; symsize = bfd_get_symtab_upper_bound (is->the_bfd); if (symsize < 1) break; relsize = bfd_get_reloc_upper_bound (is->the_bfd, sec); if (relsize < 1) break; symbols = (asymbol **) xmalloc (symsize); symsize = bfd_canonicalize_symtab (is->the_bfd, symbols); if (symsize < 0) { einfo ("%X%P: unable to process symbols: %E"); return; } relocs = (arelent **) xmalloc ((size_t) relsize); nrelocs = bfd_canonicalize_reloc (is->the_bfd, sec, relocs, symbols); if (nrelocs < 0) { free (relocs); einfo ("%X%P: unable to process relocs: %E"); return; } for (i = 0; i < nrelocs; i++) { struct symbol_cache_entry *s; struct bfd_link_hash_entry * blhe; bfd *other_bfd; char *n; s = (relocs[i]->sym_ptr_ptr)[0]; if (s->flags & BSF_LOCAL) continue; /* Thunk section with reloc to another bfd. */ blhe = bfd_link_hash_lookup (link_info.hash, s->name, false, false, true); if (blhe == NULL || blhe->type != bfd_link_hash_defined) continue; other_bfd = blhe->u.def.section->owner; if (strcmp (is->the_bfd->my_archive->filename, other_bfd->my_archive->filename) == 0) continue; /* Rename this implib to match the other. */ n = (char *) xmalloc (strlen (other_bfd->my_archive->filename) + 1); strcpy (n, other_bfd->my_archive->filename); is->the_bfd->my_archive->filename = n; } free (relocs); /* Note - we do not free the symbols, they are now cached in the BFD. */ } } } } } { int is_ms_arch = 0; bfd *cur_arch = 0; lang_input_statement_type *is2; /* Careful - this is a shell script. Watch those dollar signs! */ /* Microsoft import libraries have every member named the same, and not in the right order for us to link them correctly. We must detect these and rename the members so that they'll link correctly. There are three types of objects: the head, the thunks, and the sentinel(s). The head is easy; it's the one with idata2. We assume that the sentinels won't have relocs, and the thunks will. It's easier than checking the symbol table for external references. */ LANG_FOR_EACH_INPUT_STATEMENT (is) { if (is->the_bfd->my_archive) { bfd *arch = is->the_bfd->my_archive; if (cur_arch != arch) { cur_arch = arch; is_ms_arch = 1; for (is2 = is; is2 && is2->the_bfd->my_archive == arch; is2 = (lang_input_statement_type *)is2->next) { if (strcmp (is->the_bfd->filename, is2->the_bfd->filename)) is_ms_arch = 0; } } if (is_ms_arch) { int idata2 = 0, reloc_count=0; asection *sec; char *new_name, seq; for (sec = is->the_bfd->sections; sec; sec = sec->next) { if (strcmp (sec->name, ".idata\$2") == 0) idata2 = 1; reloc_count += sec->reloc_count; } if (idata2) /* .idata2 is the TOC */ seq = 'a'; else if (reloc_count > 0) /* thunks */ seq = 'b'; else /* sentinel */ seq = 'c'; new_name = xmalloc (strlen (is->the_bfd->filename) + 3); sprintf (new_name, "%s.%c", is->the_bfd->filename, seq); is->the_bfd->filename = new_name; new_name = xmalloc (strlen (is->filename) + 3); sprintf (new_name, "%s.%c", is->filename, seq); is->filename = new_name; } } } }}static void gld_${EMULATION_NAME}_before_allocation(){#ifdef TARGET_IS_ppcpe /* Here we rummage through the found bfds to collect toc information */ { LANG_FOR_EACH_INPUT_STATEMENT (is) { if (!ppc_process_before_allocation (is->the_bfd, &link_info)) { /* xgettext:c-format */ einfo (_("Errors encountered processing file %s\n"), is->filename); } } } /* We have seen it all. Allocate it, and carry on */ ppc_allocate_toc_section (&link_info);#endif /* TARGET_IS_ppcpe */#if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe) /* FIXME: we should be able to set the size of the interworking stub section. Here we rummage through the found bfds to collect glue information. FIXME: should this be based on a command line option? krk@cygnus.com */ { LANG_FOR_EACH_INPUT_STATEMENT (is) { if (! bfd_arm_pe_process_before_allocation (is->the_bfd, & link_info, support_old_code)) { /* xgettext:c-format */ einfo (_("Errors encountered processing file %s for interworking"), is->filename); } } } /* We have seen it all. Allocate it, and carry on */ bfd_arm_pe_allocate_interworking_sections (& link_info);#endif /* TARGET_IS_armpe */}#ifdef DLL_SUPPORT/* This is called when an input file isn't recognized as a BFD. We check here for .DEF files and pull them in automatically. */static intsaw_option(char *option){ int i; for (i=0; init[i].ptr; i++) if (strcmp (init[i].symbol, option) == 0) return init[i].inited; return 0;}#endif /* DLL_SUPPORT */static booleangld_${EMULATION_NAME}_unrecognized_file(entry) lang_input_statement_type *entry ATTRIBUTE_UNUSED;{#ifdef DLL_SUPPORT const char *ext = entry->filename + strlen (entry->filename) - 4; if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0) { if (pe_def_file == 0) pe_def_file = def_file_empty (); def_file_parse (entry->filename, pe_def_file); if (pe_def_file) { int i, buflen=0, len; char *buf; for (i=0; i<pe_def_file->num_exports; i++) { len = strlen(pe_def_file->exports[i].internal_name); if (buflen < len+2) buflen = len+2; } buf = (char *) xmalloc (buflen); for (i=0; i<pe_def_file->num_exports; i++) { struct bfd_link_hash_entry *h; sprintf(buf, "_%s", pe_def_file->exports[i].internal_name); h = bfd_link_hash_lookup (link_info.hash, buf, true, true, true); if (h == (struct bfd_link_hash_entry *) NULL) einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); if (h->type == bfd_link_hash_new) { h->type = bfd_link_hash_undefined; h->u.undef.abfd = NULL; bfd_link_add_undef (link_info.hash, h); } } free (buf); /* def_file_print (stdout, pe_def_file); */ if (pe_def_file->is_dll == 1) link_info.shared = 1; if (pe_def_file->base_address != (bfd_vma)(-1)) { pe.ImageBase = pe_data (output_bfd)->pe_opthdr.ImageBase = init[IMAGEBASEOFF].value = pe_def_file->base_address; init[IMAGEBASEOFF].inited = 1; if (image_base_statement) image_base_statement->exp = exp_assop ('=', "__image_base__", exp_intop (pe.ImageBase)); }#if 0 /* Not sure if these *should* be set */ if (pe_def_file->version_major != -1) { pe.MajorImageVersion = pe_def_file->version_major; pe.MinorImageVersion = pe_def_file->version_minor; }#endif if (pe_def_file->stack_reserve != -1 && ! saw_option ("__size_of_stack_reserve__")) { pe.SizeOfStackReserve = pe_def_file->stack_reserve; if (pe_def_file->stack_commit != -1) pe.SizeOfStackCommit = pe_def_file->stack_commit; } if (pe_def_file->heap_reserve != -1 && ! saw_option ("__size_of_heap_reserve__")) { pe.SizeOfHeapReserve = pe_def_file->heap_reserve; if (pe_def_file->heap_commit != -1) pe.SizeOfHeapCommit = pe_def_file->heap_commit; } return true; } }#endif return false; }static booleangld_${EMULATION_NAME}_recognized_file(entry) lang_input_statement_type *entry ATTRIBUTE_UNUSED;{#ifdef DLL_SUPPORT#ifdef TARGET_IS_i386pe pe_dll_id_target ("pei-i386");#endif#ifdef TARGET_IS_shpe pe_dll_id_target ("pei-shl");#endif#ifdef TARGET_IS_mipspe pe_dll_id_target ("pei-mips");#endif#ifdef TARGET_IS_armpe pe_dll_id_target ("pei-arm-little");#endif if (bfd_get_format (entry->the_bfd) == bfd_object) { const char *ext = entry->filename + strlen (entry->filename) - 4; if (strcmp (ext, ".dll") == 0 || strcmp (ext, ".DLL") == 0) return pe_implied_import_dll (entry->filename); }#endif return false;}static voidgld_${EMULATION_NAME}_finish (){#if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe) struct bfd_link_hash_entry * h; if (thumb_entry_symbol != NULL) { h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, false, false, true); if (h != (struct bfd_link_hash_entry *) NULL && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak) && h->u.def.section->output_section != NULL) { static char buffer[32]; bfd_vma val; /* Special procesing is required for a Thumb entry symbol. The bottom bit of its address must be set. */ val = (h->u.def.value + bfd_get_section_vma (output_bfd, h->u.def.section->output_section) + h->u.def.section->output_offset); val |= 1; /* Now convert this value into a string and store it in entry_symbol where the lang_finish() function will pick it up. */ buffer[0] = '0'; buffer[1] = 'x'; sprintf_vma (buffer + 2, val); if (entry_symbol != NULL && entry_from_cmdline) einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"), thumb_entry_symbol, entry_symbol); entry_symbol = buffer; } else einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol); }#endif /* defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe) */#ifdef DLL_SUPPORT if (link_info.shared) { pe_dll_fill_sections (output_bfd, &link_info); if (pe_implib_filename) pe_dll_generate_implib (pe_def_file, pe_implib_filename); }#if defined(TARGET_IS_shpe) || defined(TARGET_IS_mipspe) /* ARM doesn't need relocs. */ else { pe_exe_fill_sections (output_bfd, &link_info); }#endif if (pe_out_def_filename) pe_dll_generate_def_file (pe_out_def_filename);#endif /* DLL_SUPPORT */}/* Place an orphan section. We use this to put sections in a reasonable place in the file, and to ensure that they are aligned as required. We handle grouped sections here as well. A section named .foo$nn goes into the output section .foo. All grouped sections are sorted by name. Grouped sections for the default sections are handled by the default linker script using wildcards, and are sorted by sort_sections. */struct orphan_save{ lang_output_section_statement_type *os; asection **section; lang_statement_union_type **stmt;};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?