nlmconv.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,181 行 · 第 1/5 页
C
2,181 行
/* If the date was not given, force it in. */ if (nlm_version_header (outbfd)->month == 0 && nlm_version_header (outbfd)->day == 0 && nlm_version_header (outbfd)->year == 0) { time_t now; struct tm *ptm; time (&now); ptm = localtime (&now); nlm_version_header (outbfd)->month = ptm->tm_mon + 1; nlm_version_header (outbfd)->day = ptm->tm_mday; nlm_version_header (outbfd)->year = ptm->tm_year + 1900; strncpy (version_hdr->stamp, "VeRsIoN#", 8); }#ifdef NLMCONV_POWERPC /* Resolve the stubs we build for PowerPC NetWare. */ if (bfd_get_arch (inbfd) == bfd_arch_powerpc) powerpc_resolve_stubs (inbfd, outbfd);#endif /* Copy over the sections. */ bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd); /* Finish up the header information. */ if (custom_file != NULL) { PTR data; data = xmalloc (custom_size); if (fread (data, 1, custom_size, custom_data) != custom_size) non_fatal (_("%s: read: %s"), custom_file, strerror (errno)); else { if (! bfd_set_section_contents (outbfd, custom_section, data, (file_ptr) 0, custom_size)) bfd_fatal (_("custom section")); nlm_fixed_header (outbfd)->customDataOffset = custom_section->filepos; nlm_fixed_header (outbfd)->customDataSize = custom_size; } free (data); } if (! debug_info) { /* As a special hack, the backend recognizes a debugInfoOffset of -1 to mean that it should not output any debugging information. This can not be handling by fiddling with the symbol table because exported symbols appear in both the export information and the debugging information. */ nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1; } if (map_file != NULL) non_fatal (_("warning: MAP and FULLMAP are not supported; try ld -M")); if (help_file != NULL) { PTR data; data = xmalloc (help_size); if (fread (data, 1, help_size, help_data) != help_size) non_fatal (_("%s: read: %s"), help_file, strerror (errno)); else { if (! bfd_set_section_contents (outbfd, help_section, data, (file_ptr) 0, help_size)) bfd_fatal (_("help section")); nlm_extended_header (outbfd)->helpFileOffset = help_section->filepos; nlm_extended_header (outbfd)->helpFileLength = help_size; } free (data); } if (message_file != NULL) { PTR data; data = xmalloc (message_size); if (fread (data, 1, message_size, message_data) != message_size) non_fatal (_("%s: read: %s"), message_file, strerror (errno)); else { if (! bfd_set_section_contents (outbfd, message_section, data, (file_ptr) 0, message_size)) bfd_fatal (_("message section")); nlm_extended_header (outbfd)->messageFileOffset = message_section->filepos; nlm_extended_header (outbfd)->messageFileLength = message_size; /* FIXME: Are these offsets correct on all platforms? Are they 32 bits on all platforms? What endianness? */ nlm_extended_header (outbfd)->languageID = bfd_h_get_32 (outbfd, (bfd_byte *) data + 106); nlm_extended_header (outbfd)->messageCount = bfd_h_get_32 (outbfd, (bfd_byte *) data + 110); } free (data); } if (modules != NULL) { PTR data; unsigned char *set; struct string_list *l; bfd_size_type c; data = xmalloc (module_size); c = 0; set = (unsigned char *) data; for (l = modules; l != NULL; l = l->next) { *set = strlen (l->string); strncpy (set + 1, l->string, *set); set += *set + 1; ++c; } if (! bfd_set_section_contents (outbfd, module_section, data, (file_ptr) 0, module_size)) bfd_fatal (_("module section")); nlm_fixed_header (outbfd)->moduleDependencyOffset = module_section->filepos; nlm_fixed_header (outbfd)->numberOfModuleDependencies = c; } if (rpc_file != NULL) { PTR data; data = xmalloc (rpc_size); if (fread (data, 1, rpc_size, rpc_data) != rpc_size) non_fatal (_("%s: read: %s"), rpc_file, strerror (errno)); else { if (! bfd_set_section_contents (outbfd, rpc_section, data, (file_ptr) 0, rpc_size)) bfd_fatal (_("rpc section")); nlm_extended_header (outbfd)->RPCDataOffset = rpc_section->filepos; nlm_extended_header (outbfd)->RPCDataLength = rpc_size; } free (data); } if (sharelib_file != NULL) { PTR data; data = xmalloc (shared_size); if (fseek (shared_data, shared_offset, SEEK_SET) != 0 || fread (data, 1, shared_size, shared_data) != shared_size) non_fatal (_("%s: read: %s"), sharelib_file, strerror (errno)); else { if (! bfd_set_section_contents (outbfd, shared_section, data, (file_ptr) 0, shared_size)) bfd_fatal (_("shared section")); } nlm_extended_header (outbfd)->sharedCodeOffset = sharedhdr.codeImageOffset - shared_offset + shared_section->filepos; nlm_extended_header (outbfd)->sharedCodeLength = sharedhdr.codeImageSize; nlm_extended_header (outbfd)->sharedDataOffset = sharedhdr.dataImageOffset - shared_offset + shared_section->filepos; nlm_extended_header (outbfd)->sharedDataLength = sharedhdr.dataImageSize; nlm_extended_header (outbfd)->sharedRelocationFixupOffset = (sharedhdr.relocationFixupOffset - shared_offset + shared_section->filepos); nlm_extended_header (outbfd)->sharedRelocationFixupCount = sharedhdr.numberOfRelocationFixups; nlm_extended_header (outbfd)->sharedExternalReferenceOffset = (sharedhdr.externalReferencesOffset - shared_offset + shared_section->filepos); nlm_extended_header (outbfd)->sharedExternalReferenceCount = sharedhdr.numberOfExternalReferences; nlm_extended_header (outbfd)->sharedPublicsOffset = sharedhdr.publicsOffset - shared_offset + shared_section->filepos; nlm_extended_header (outbfd)->sharedPublicsCount = sharedhdr.numberOfPublics; nlm_extended_header (outbfd)->sharedDebugRecordOffset = sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos; nlm_extended_header (outbfd)->sharedDebugRecordCount = sharedhdr.numberOfDebugRecords; nlm_extended_header (outbfd)->SharedInitializationOffset = sharedhdr.codeStartOffset; nlm_extended_header (outbfd)->SharedExitProcedureOffset = sharedhdr.exitProcedureOffset; free (data); } len = strlen (output_file); if (len > NLM_MODULE_NAME_SIZE - 2) len = NLM_MODULE_NAME_SIZE - 2; nlm_fixed_header (outbfd)->moduleName[0] = len; strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file, NLM_MODULE_NAME_SIZE - 2); nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0'; for (modname = nlm_fixed_header (outbfd)->moduleName; *modname != '\0'; modname++) if (islower ((unsigned char) *modname)) *modname = toupper (*modname); strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG", NLM_OLD_THREAD_NAME_LENGTH); nlm_cygnus_ext_header (outbfd)->offset = secsec->filepos; nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec); if (! bfd_close (outbfd)) bfd_fatal (output_file); if (! bfd_close (inbfd)) bfd_fatal (input_file); if (unlink_on_exit != NULL) unlink (unlink_on_exit); return 0;}/* Display a help message and exit. */static voidshow_help (){ printf (_("%s: Convert an object file into a NetWare Loadable Module\n"), program_name); show_usage (stdout, 0);}/* Show a usage message and exit. */static voidshow_usage (file, status) FILE *file; int status;{ fprintf (file, _("\Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\ [--input-target=bfdname] [--output-target=bfdname]\n\ [--header-file=file] [--linker=linker] [--debug]\n\ [--help] [--version]\n\ [in-file [out-file]]\n"), program_name); if (status == 0) fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO); exit (status);}/* Select the output format based on the input architecture, machine, and endianness. This chooses the appropriate NLM target. */static const char *select_output_format (arch, mach, bigendian) enum bfd_architecture arch; unsigned long mach; boolean bigendian;{ switch (arch) {#ifdef NLMCONV_I386 case bfd_arch_i386: return "nlm32-i386";#endif#ifdef NLMCONV_SPARC case bfd_arch_sparc: return "nlm32-sparc";#endif#ifdef NLMCONV_ALPHA case bfd_arch_alpha: return "nlm32-alpha";#endif#ifdef NLMCONV_POWERPC case bfd_arch_powerpc: return "nlm32-powerpc";#endif default: fatal (_("support not compiled in for %s"), bfd_printable_arch_mach (arch, mach)); } /*NOTREACHED*/}/* The BFD sections are copied in two passes. This function selects the output section for each input section, and sets up the section name, size, etc. */static voidsetup_sections (inbfd, insec, data_ptr) bfd *inbfd; asection *insec; PTR data_ptr;{ bfd *outbfd = (bfd *) data_ptr; flagword f; const char *outname; asection *outsec; bfd_vma offset; bfd_size_type align; bfd_size_type add; bfd_size_type secsecsize; f = bfd_get_section_flags (inbfd, insec); if (f & SEC_CODE) outname = NLM_CODE_NAME; else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS)) outname = NLM_INITIALIZED_DATA_NAME; else if (f & SEC_ALLOC) outname = NLM_UNINITIALIZED_DATA_NAME; else outname = bfd_section_name (inbfd, insec); outsec = bfd_get_section_by_name (outbfd, outname); if (outsec == NULL) { outsec = bfd_make_section (outbfd, outname); if (outsec == NULL) bfd_fatal (_("make section")); } insec->output_section = outsec; offset = bfd_section_size (outbfd, outsec); align = 1 << bfd_section_alignment (inbfd, insec); add = ((offset + align - 1) &~ (align - 1)) - offset; insec->output_offset = offset + add; if (! bfd_set_section_size (outbfd, outsec, (bfd_section_size (outbfd, outsec) + bfd_section_size (inbfd, insec) + add))) bfd_fatal (_("set section size")); if ((bfd_section_alignment (inbfd, insec) > bfd_section_alignment (outbfd, outsec)) && ! bfd_set_section_alignment (outbfd, outsec, bfd_section_alignment (inbfd, insec))) bfd_fatal (_("set section alignment")); if (! bfd_set_section_flags (outbfd, outsec, f | bfd_get_section_flags (outbfd, outsec))) bfd_fatal (_("set section flags")); bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0); /* For each input section we allocate space for an entry in .nlmsections. */ secsecsize = bfd_section_size (outbfd, secsec); secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1; secsecsize = (secsecsize + 3) &~ 3; secsecsize += 8; if (! bfd_set_section_size (outbfd, secsec, secsecsize)) bfd_fatal (_("set .nlmsections size"));}/* Copy the section contents. */static voidcopy_sections (inbfd, insec, data_ptr) bfd *inbfd; asection *insec; PTR data_ptr;{ static bfd_size_type secsecoff = 0; bfd *outbfd = (bfd *) data_ptr; const char *inname; asection *outsec; bfd_size_type size; PTR contents; long reloc_size; bfd_byte buf[4]; bfd_size_type add; inname = bfd_section_name (inbfd, insec); outsec = insec->output_section; assert (outsec != NULL); size = bfd_get_section_size_before_reloc (insec); /* FIXME: Why are these necessary? */ insec->_cooked_size = insec->_raw_size; insec->reloc_done = true; if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0) contents = NULL; else { contents = xmalloc (size); if (! bfd_get_section_contents (inbfd, insec, contents, (file_ptr) 0, size)) bfd_fatal (bfd_get_filename (inbfd)); } reloc_size = bfd_get_reloc_upper_bound (inbfd, insec); if (reloc_size < 0) bfd_fatal (bfd_get_filename (inbfd)); if (reloc_size != 0) { arelent **relocs; long reloc_count; relocs = (arelent **) xmalloc (reloc_size); reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols); if (reloc_count < 0) bfd_fatal (bfd_get_filename (inbfd)); mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents, size); /* FIXME: refers to internal BFD fields. */ if (outsec->orelocation != (arelent **) NULL) { bfd_size_type total_count; arelent **combined; total_count = reloc_count + outsec->reloc_count; combined = (arelent **) xmalloc (total_count * sizeof (arelent *)); memcpy (combined, outsec->orelocation, outsec->reloc_count * sizeof (arelent *)); memcpy (combined + outsec->reloc_count, relocs, (size_t) (reloc_count * sizeof (arelent *))); free (outsec->orelocation); reloc_count = total_count; relocs = combined; } bfd_set_reloc (outbfd, outsec, relocs, reloc_count); } if (contents != NULL) { if (! bfd_set_section_contents (outbfd, outsec, contents, insec->output_offset, size)) bfd_fatal (bfd_get_filename (outbfd)); free (contents); } /* Add this section to .nlmsections. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?