📄 objcopy.c
字号:
{ list_matching_formats (matching); free (matching); } status = 1; }}/* Create a section in OBFD with the same name and attributes as ISECTION in IBFD. */static voidsetup_section (ibfd, isection, obfdarg) bfd *ibfd; sec_ptr isection; PTR obfdarg;{ bfd *obfd = (bfd *) obfdarg; struct section_list *p; sec_ptr osection; bfd_size_type size; bfd_vma vma; bfd_vma lma; flagword flags; const char *err; if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0 && (strip_symbols == STRIP_DEBUG || strip_symbols == STRIP_UNNEEDED || strip_symbols == STRIP_ALL || discard_locals == LOCALS_ALL || convert_debugging)) return; p = find_section_list (bfd_section_name (ibfd, isection), false); if (p != NULL) p->used = true; if (sections_removed && p != NULL && p->remove) return; if (sections_copied && (p == NULL || ! p->copy)) return; osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection)); if (osection == NULL) { err = _("making"); goto loser; } size = bfd_section_size (ibfd, isection); if (copy_byte >= 0) size = (size + interleave - 1) / interleave; if (! bfd_set_section_size (obfd, osection, size)) { err = _("size"); goto loser; } vma = bfd_section_vma (ibfd, isection); if (p != NULL && p->change_vma == CHANGE_MODIFY) vma += p->vma_val; else if (p != NULL && p->change_vma == CHANGE_SET) vma = p->vma_val; else vma += change_section_address; if (! bfd_set_section_vma (obfd, osection, vma)) { err = _("vma"); goto loser; } lma = isection->lma; if ((p != NULL) && p->change_lma != CHANGE_IGNORE) { if (p->change_lma == CHANGE_MODIFY) lma += p->lma_val; else if (p->change_lma == CHANGE_SET) lma = p->lma_val; else abort (); } else lma += change_section_address; osection->lma = lma; /* FIXME: This is probably not enough. If we change the LMA we may have to recompute the header for the file as well. */ if (bfd_set_section_alignment (obfd, osection, bfd_section_alignment (ibfd, isection)) == false) { err = _("alignment"); goto loser; } flags = bfd_get_section_flags (ibfd, isection); if (p != NULL && p->set_flags) flags = p->flags | (flags & SEC_HAS_CONTENTS); if (!bfd_set_section_flags (obfd, osection, flags)) { err = _("flags"); goto loser; } /* This used to be mangle_section; we do here to avoid using bfd_get_section_by_name since some formats allow multiple sections with the same name. */ isection->output_section = osection; isection->output_offset = 0; /* Allow the BFD backend to copy any private data it understands from the input section to the output section. */ if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection)) { err = _("private data"); goto loser; } /* All went well */ return;loser: non_fatal (_("%s: section `%s': error in %s: %s"), bfd_get_filename (ibfd), bfd_section_name (ibfd, isection), err, bfd_errmsg (bfd_get_error ())); status = 1;}/* Copy the data of input section ISECTION of IBFD to an output section with the same name in OBFD. If stripping then don't copy any relocation info. */static voidcopy_section (ibfd, isection, obfdarg) bfd *ibfd; sec_ptr isection; PTR obfdarg;{ bfd *obfd = (bfd *) obfdarg; struct section_list *p; arelent **relpp; long relcount; sec_ptr osection; bfd_size_type size; long relsize; /* If we have already failed earlier on, do not keep on generating complaints now. */ if (status != 0) return; if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0 && (strip_symbols == STRIP_DEBUG || strip_symbols == STRIP_UNNEEDED || strip_symbols == STRIP_ALL || discard_locals == LOCALS_ALL || convert_debugging)) { return; } p = find_section_list (bfd_section_name (ibfd, isection), false); if (sections_removed && p != NULL && p->remove) return; if (sections_copied && (p == NULL || ! p->copy)) return; osection = isection->output_section; size = bfd_get_section_size_before_reloc (isection); if (size == 0 || osection == 0) return; relsize = bfd_get_reloc_upper_bound (ibfd, isection); if (relsize < 0) RETURN_NONFATAL (bfd_get_filename (ibfd)); if (relsize == 0) bfd_set_reloc (obfd, osection, (arelent **) NULL, 0); else { relpp = (arelent **) xmalloc (relsize); relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp); if (relcount < 0) RETURN_NONFATAL (bfd_get_filename (ibfd)); if (strip_symbols == STRIP_ALL) { /* Remove relocations which are not in keep_strip_specific_list. */ arelent **temp_relpp; long temp_relcount = 0; long i; temp_relpp = (arelent **) xmalloc (relsize); for (i = 0; i < relcount; i++) if (is_specified_symbol (bfd_asymbol_name (*relpp [i]->sym_ptr_ptr), keep_specific_list)) temp_relpp [temp_relcount++] = relpp [i]; relcount = temp_relcount; free (relpp); relpp = temp_relpp; } bfd_set_reloc (obfd, osection, (relcount == 0 ? (arelent **) NULL : relpp), relcount); } isection->_cooked_size = isection->_raw_size; isection->reloc_done = true; if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS) { PTR memhunk = (PTR) xmalloc ((unsigned) size); if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0, size)) RETURN_NONFATAL (bfd_get_filename (ibfd)); if (copy_byte >= 0) filter_bytes (memhunk, &size); if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0, size)) RETURN_NONFATAL (bfd_get_filename (obfd)); free (memhunk); } else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0) { PTR memhunk = (PTR) xmalloc ((unsigned) size); /* We don't permit the user to turn off the SEC_HAS_CONTENTS flag--they can just remove the section entirely and add it back again. However, we do permit them to turn on the SEC_HAS_CONTENTS flag, and take it to mean that the section contents should be zeroed out. */ memset (memhunk, 0, size); if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0, size)) RETURN_NONFATAL (bfd_get_filename (obfd)); free (memhunk); }}/* Get all the sections. This is used when --gap-fill or --pad-to is used. */static voidget_sections (obfd, osection, secppparg) bfd *obfd ATTRIBUTE_UNUSED; asection *osection; PTR secppparg;{ asection ***secppp = (asection ***) secppparg; **secppp = osection; ++(*secppp);}/* Sort sections by VMA. This is called via qsort, and is used when --gap-fill or --pad-to is used. We force non loadable or empty sections to the front, where they are easier to ignore. */static intcompare_section_lma (arg1, arg2) const PTR arg1; const PTR arg2;{ const asection **sec1 = (const asection **) arg1; const asection **sec2 = (const asection **) arg2; flagword flags1, flags2; /* Sort non loadable sections to the front. */ flags1 = (*sec1)->flags; flags2 = (*sec2)->flags; if ((flags1 & SEC_HAS_CONTENTS) == 0 || (flags1 & SEC_LOAD) == 0) { if ((flags2 & SEC_HAS_CONTENTS) != 0 && (flags2 & SEC_LOAD) != 0) return -1; } else { if ((flags2 & SEC_HAS_CONTENTS) == 0 || (flags2 & SEC_LOAD) == 0) return 1; } /* Sort sections by LMA. */ if ((*sec1)->lma > (*sec2)->lma) return 1; else if ((*sec1)->lma < (*sec2)->lma) return -1; /* Sort sections with the same LMA by size. */ if ((*sec1)->_raw_size > (*sec2)->_raw_size) return 1; else if ((*sec1)->_raw_size < (*sec2)->_raw_size) return -1; return 0;}/* Mark all the symbols which will be used in output relocations with the BSF_KEEP flag so that those symbols will not be stripped. Ignore relocations which will not appear in the output file. */static voidmark_symbols_used_in_relocations (ibfd, isection, symbolsarg) bfd *ibfd; sec_ptr isection; PTR symbolsarg;{ asymbol **symbols = (asymbol **) symbolsarg; long relsize; arelent **relpp; long relcount, i; /* Ignore an input section with no corresponding output section. */ if (isection->output_section == NULL) return; relsize = bfd_get_reloc_upper_bound (ibfd, isection); if (relsize < 0) bfd_fatal (bfd_get_filename (ibfd)); if (relsize == 0) return; relpp = (arelent **) xmalloc (relsize); relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols); if (relcount < 0) bfd_fatal (bfd_get_filename (ibfd)); /* Examine each symbol used in a relocation. If it's not one of the special bfd section symbols, then mark it with BSF_KEEP. */ for (i = 0; i < relcount; i++) { if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol) (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP; } if (relpp != NULL) free (relpp);}/* Write out debugging information. */static booleanwrite_debugging_info (obfd, dhandle, symcountp, symppp) bfd *obfd; PTR dhandle; long *symcountp ATTRIBUTE_UNUSED; asymbol ***symppp ATTRIBUTE_UNUSED;{ if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour) return write_ieee_debugging_info (obfd, dhandle); if (bfd_get_flavour (obfd) == bfd_target_coff_flavour || bfd_get_flavour (obfd) == bfd_target_elf_flavour) { bfd_byte *syms, *strings; bfd_size_type symsize, stringsize; asection *stabsec, *stabstrsec; if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms, &symsize, &strings, &stringsize)) return false; stabsec = bfd_make_section (obfd, ".stab"); stabstrsec = bfd_make_section (obfd, ".stabstr"); if (stabsec == NULL || stabstrsec == NULL || ! bfd_set_section_size (obfd, stabsec, symsize) || ! bfd_set_section_size (obfd, stabstrsec, stringsize) || ! bfd_set_section_alignment (obfd, stabsec, 2) || ! bfd_set_section_alignment (obfd, stabstrsec, 0) || ! bfd_set_section_flags (obfd, stabsec, (SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING)) || ! bfd_set_section_flags (obfd, stabstrsec, (SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING))) { non_fatal (_("%s: can't create debugging section: %s"), bfd_get_filename (obfd), bfd_errmsg (bfd_get_error ())); return false; } /* We can get away with setting the section contents now because the next thing the caller is going to do is copy over the real sections. We may someday have to split the contents setting out of this function. */ if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0, symsize) || ! bfd_set_section_contents (obfd, stabstrsec, strings, (file_ptr) 0, stringsize)) { non_fatal (_("%s: can't set debugging section contents: %s"), bfd_get_filename (obfd), bfd_errmsg (bfd_get_error ())); return false; } return true; } non_fatal (_("%s: don't know how to write debugging information for %s"), bfd_get_filename (obfd), bfd_get_target (obfd)); return false;}static intstrip_main (argc, argv) int argc; char *argv[];{ char *input_target = NULL, *output_target = NULL; boolean show_version = false; int c, i; struct section_list *p; char *output_file = NULL; while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXVvW:", strip_options, (int *) 0)) != EOF) { switch (c) { case 'I': input_target = optarg; break; case 'O': output_target = optarg; break; case 'F': input_target = output_target = optarg; break; case 'R': p = find_section_list (optarg, true); p->remove = true; sections_removed = true; break; case 's': strip_symbols = STRIP_ALL; break; case 'S':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -