From 6b64c328f239a146c1ce5a85c27b0ff1636f3987 Mon Sep 17 00:00:00 2001 From: Sebastian Bauer Date: Tue, 1 Dec 2015 13:51:20 +0100 Subject: [PATCH 6/8] Introduced strip-unneeded-rel-relocs. Normally, on AmigaOS we keep all relocs for executables as we don't have an isolated address space. However, not all relative relocs are necessary to be kept, for instance if they are refering to the same program section. With the newly introduced strip option --strip-unneeded-rel-relocs these can be removed now. --- binutils/objcopy.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 88bd071eefa8b5426eaadfd6431e9de5d4a4591b..4beee77179b85479d5b43507d9eb2a6e0caf384e 100644 --- binutils/objcopy.c +++ binutils/objcopy.c @@ -101,12 +101,15 @@ enum strip_action STRIP_ALL /* Strip all symbols. */ }; /* Which symbols to remove. */ static enum strip_action strip_symbols; +/* Shall we strip unneeded relative relocs? */ +static int strip_unneeded_rel_relocs; + enum locals_action { LOCALS_UNDEF, LOCALS_START_L, /* Discard locals starting with L. */ LOCALS_ALL /* Discard all locals. */ }; @@ -315,13 +318,14 @@ enum command_line_switch OPTION_IMAGE_BASE, OPTION_SECTION_ALIGNMENT, OPTION_STACK, OPTION_INTERLEAVE_WIDTH, OPTION_SUBSYSTEM, OPTION_EXTRACT_DWO, - OPTION_STRIP_DWO + OPTION_STRIP_DWO, + OPTION_STRIP_UNNEEED_REL_RELOCS }; /* Options to handle if running as "strip". */ static struct option strip_options[] = { @@ -343,12 +347,13 @@ static struct option strip_options[] = {"preserve-dates", no_argument, 0, 'p'}, {"remove-section", required_argument, 0, 'R'}, {"strip-all", no_argument, 0, 's'}, {"strip-debug", no_argument, 0, 'S'}, {"strip-dwo", no_argument, 0, OPTION_STRIP_DWO}, {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, + {"strip-unneeded-rel-relocs", no_argument, 0, OPTION_STRIP_UNNEEED_REL_RELOCS}, {"strip-symbol", required_argument, 0, 'N'}, {"target", required_argument, 0, 'F'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"wildcard", no_argument, 0, 'w'}, {0, no_argument, 0, 0} @@ -2771,30 +2776,38 @@ copy_relocations_in_section (bfd *ibfd, sec_ptr isection, void *obfdarg) temp_relpp = (arelent **) xmalloc (relsize); for (i = 0; i < relcount; i++) { asection *sec; sec = bfd_get_section(*relpp[i]->sym_ptr_ptr); -// printf("%d: %s (0x%lx + 0x%lx) value 0x%lx (in section %s)\n", +// printf("%ld: %s (0x%lx + 0x%lx) value 0x%lx (in section %s)\n", // i, bfd_asymbol_name (*relpp [i]->sym_ptr_ptr), relpp [i]->address, relpp [i]->addend, // bfd_asymbol_value(*relpp [i]->sym_ptr_ptr), // bfd_section_name(ibfd, sec)); /* Keep the symbol */ if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr), keep_specific_htab)) temp_relpp [temp_relcount++] = relpp [i]; else { - /* Don't keep the symbol, but keep the reloc */ - temp_relpp [temp_relcount] = relpp[i]; - temp_relpp [temp_relcount]->addend = bfd_asymbol_value(*relpp [i]->sym_ptr_ptr) + /* Don't keep the symbol, but keep the reloc unless it is a relative reloc that is + * requested by the user to be removed. For now, we also don't discard the reloc if + * its targeting a different section. This can happen for relocs in the .rodata + * segment that refering to the .text segment. AmigaOS will possibly split these + * up. + */ + if (!strip_unneeded_rel_relocs || !relpp [i]->howto->pc_relative || sec->index != osection->index) + { + temp_relpp [temp_relcount] = relpp[i]; + temp_relpp [temp_relcount]->addend = bfd_asymbol_value(*relpp [i]->sym_ptr_ptr) - sec->vma + relpp[i]->addend; - temp_relpp [temp_relcount]->sym_ptr_ptr = sec->symbol_ptr_ptr; - temp_relcount++; + temp_relpp [temp_relcount]->sym_ptr_ptr = sec->symbol_ptr_ptr; + temp_relcount++; + } } } relcount = temp_relcount; free (relpp); relpp = temp_relpp; } @@ -3124,12 +3137,15 @@ strip_main (int argc, char *argv[]) case OPTION_STRIP_DWO: strip_symbols = STRIP_DWO; break; case OPTION_STRIP_UNNEEDED: strip_symbols = STRIP_UNNEEDED; break; + case OPTION_STRIP_UNNEEED_REL_RELOCS: + strip_unneeded_rel_relocs = 1; + break; case 'K': add_specific_symbol (optarg, keep_specific_htab); break; case 'N': add_specific_symbol (optarg, strip_specific_htab); break; -- 2.11.0