summaryrefslogtreecommitdiff
path: root/ppc-amigaos/recipes/patches/binutils/0006-Introduced-strip-unneeded-rel-relocs.p
blob: 70a5e4be4904eb5c9a9b877a5aceee77df424172 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
From 6b64c328f239a146c1ce5a85c27b0ff1636f3987 Mon Sep 17 00:00:00 2001
From: Sebastian Bauer <mail@sebastianbauer.info>
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