File: glibc-2.10-ldso-rpath-prefix-option.2.patch

package info (click to toggle)
scratchbox2 2.2.4-1debian1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 5,392 kB
  • ctags: 5,239
  • sloc: ansic: 21,734; sh: 4,360; perl: 2,170; cpp: 1,913; makefile: 610; python: 184
file content (283 lines) | stat: -rw-r--r-- 9,529 bytes parent folder | download
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
Index: libc/elf/dl-load.c
===================================================================
--- libc/elf/dl-load.c	(revision 13883)
+++ libc/elf/dl-load.c	(working copy)
@@ -237,7 +237,7 @@
 
 char *
 _dl_dst_substitute (struct link_map *l, const char *name, char *result,
-		    int is_path)
+		    int is_path, const char *rpath_prefix)
 {
   const char *const start = name;
   char *last_elem, *wp;
@@ -273,6 +273,13 @@
 
 	  if (repl != NULL && repl != (const char *) -1)
 	    {
+	      if (__builtin_expect (rpath_prefix != NULL, 0))
+		{
+		  /* has rpath_prefix */
+		  size_t rpath_prefix_len = strlen (rpath_prefix);
+		  if (!strncmp (repl, rpath_prefix, rpath_prefix_len))
+		    repl += rpath_prefix_len;
+		}
 	      wp = __stpcpy (wp, repl);
 	      name += len;
 	    }
@@ -310,7 +317,7 @@
    belonging to the map is loaded.  In this case the path element
    containing $ORIGIN is left out.  */
 static char *
-expand_dynamic_string_token (struct link_map *l, const char *s)
+expand_dynamic_string_token (struct link_map *l, const char *s, const char *rpath_prefix)
 {
   /* We make two runs over the string.  First we determine how large the
      resulting string is and then we copy it over.  Since this is now
@@ -335,7 +342,7 @@
   if (result == NULL)
     return NULL;
 
-  return _dl_dst_substitute (l, s, result, 1);
+  return _dl_dst_substitute (l, s, result, 1, rpath_prefix);
 }
 
 
@@ -380,7 +387,8 @@
 
 static struct r_search_path_elem **
 fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
-	      int check_trusted, const char *what, const char *where)
+	      int check_trusted, const char *what, const char *where,
+	      const char *rpath_prefix)
 {
   char *cp;
   size_t nelems = 0;
@@ -436,10 +444,24 @@
 	}
 
       /* See if this directory is already known.  */
-      for (dirp = GL(dl_all_dirs); dirp != NULL; dirp = dirp->next)
-	if (dirp->dirnamelen == len && memcmp (cp, dirp->dirname, len) == 0)
-	  break;
+      if (__builtin_expect (rpath_prefix != NULL, 0))
+	{
+	  /* has rpath_prefix */
+	  size_t rpath_prefix_len = strlen (rpath_prefix);
 
+	  for (dirp = GL(dl_all_dirs); dirp != NULL; dirp = dirp->next)
+	    if (dirp->dirnamelen == (rpath_prefix_len+len) &&
+		(memcmp (cp, rpath_prefix, rpath_prefix_len) == 0) &&
+		(memcmp (cp+rpath_prefix_len, dirp->dirname, len) == 0))
+	      break;
+	}
+      else
+	{
+	  for (dirp = GL(dl_all_dirs); dirp != NULL; dirp = dirp->next)
+	    if (dirp->dirnamelen == len && memcmp (cp, dirp->dirname, len) == 0)
+	      break;
+	}
+
       if (dirp != NULL)
 	{
 	  /* It is available, see whether it's on our own list.  */
@@ -456,23 +478,44 @@
 	  size_t cnt;
 	  enum r_dir_status init_val;
 	  size_t where_len = where ? strlen (where) + 1 : 0;
+	  size_t rpath_prefix_len = 0;
 
+	  if (__builtin_expect (rpath_prefix != NULL, 0)
+	      && !INTUSE(__libc_enable_secure))
+	    {
+		rpath_prefix_len = strlen (rpath_prefix);
+		if (*cp != '/') rpath_prefix_len++; /* need to add a '/' */
+	    }
+
 	  /* It's a new directory.  Create an entry and add it.  */
 	  dirp = (struct r_search_path_elem *)
 	    malloc (sizeof (*dirp) + ncapstr * sizeof (enum r_dir_status)
-		    + where_len + len + 1);
+		    + where_len + rpath_prefix_len + len + 1);
 	  if (dirp == NULL)
 	    _dl_signal_error (ENOMEM, NULL, NULL,
 			      N_("cannot create cache for search path"));
 
 	  dirp->dirname = ((char *) dirp + sizeof (*dirp)
 			   + ncapstr * sizeof (enum r_dir_status));
-	  *((char *) __mempcpy ((char *) dirp->dirname, cp, len)) = '\0';
-	  dirp->dirnamelen = len;
+	  if (rpath_prefix_len == 0)
+	    {
+		  *((char *) __mempcpy ((char *) dirp->dirname, cp, len)) = '\0';
+	    }
+	  else
+	    {
+		char *prefixend;
 
-	  if (len > max_dirnamelen)
-	    max_dirnamelen = len;
+		prefixend = (char *) __mempcpy ((char *) dirp->dirname,
+				rpath_prefix, rpath_prefix_len);
+		if (*cp != '/')
+		  prefixend[-1] = '/'; /* replace \0 */
+		*((char *) __mempcpy (prefixend, cp, len)) = '\0';
+	    }
+	  dirp->dirnamelen = len + rpath_prefix_len;
 
+	  if ((len + rpath_prefix_len) > max_dirnamelen)
+	    max_dirnamelen = len + rpath_prefix_len;
+
 	  /* We have to make sure all the relative directories are
 	     never ignored.  The current directory might change and
 	     all our saved information would be void.  */
@@ -482,7 +525,8 @@
 
 	  dirp->what = what;
 	  if (__builtin_expect (where != NULL, 1))
-	    dirp->where = memcpy ((char *) dirp + sizeof (*dirp) + len + 1
+	    dirp->where = memcpy ((char *) dirp + sizeof (*dirp)
+				  + rpath_prefix_len + len + 1
 				  + (ncapstr * sizeof (enum r_dir_status)),
 				  where, where_len);
 	  else
@@ -551,7 +595,7 @@
 
   /* Make a writable copy.  At the same time expand possible dynamic
      string tokens.  */
-  copy = expand_dynamic_string_token (l, rpath);
+  copy = expand_dynamic_string_token (l, rpath, GLRO(dl_rpath_prefix));
   if (copy == NULL)
     {
       errstring = N_("cannot create RUNPATH/RPATH copy");
@@ -576,7 +620,7 @@
       _dl_signal_error (ENOMEM, NULL, NULL, errstring);
     }
 
-  fillin_rpath (copy, result, ":", 0, what, where);
+  fillin_rpath (copy, result, ":", 0, what, where, GLRO(dl_rpath_prefix));
 
   /* Free the copied RPATH string.  `fillin_rpath' make own copies if
      necessary.  */
@@ -749,7 +793,7 @@
 
 	  /* Allocate the necessary memory.  */
 	  llp_tmp = (char *) alloca (total + 1);
-	  llp_tmp = _dl_dst_substitute (l, llp, llp_tmp, 1);
+	  llp_tmp = _dl_dst_substitute (l, llp, llp_tmp, 1, NULL);
 	}
 #else
       llp_tmp = strdupa (llp);
@@ -775,7 +819,7 @@
 
       (void) fillin_rpath (llp_tmp, env_path_list.dirs, ":;",
 			   INTUSE(__libc_enable_secure), "LD_LIBRARY_PATH",
-			   NULL);
+			   NULL, NULL/*no prefix*/);
 
       if (env_path_list.dirs[0] == NULL)
 	{
@@ -2167,7 +2211,7 @@
     {
       /* The path may contain dynamic string tokens.  */
       realname = (loader
-		  ? expand_dynamic_string_token (loader, name)
+		  ? expand_dynamic_string_token (loader, name, NULL)
 		  : local_strdup (name));
       if (realname == NULL)
 	fd = -1;
Index: libc/elf/dl-support.c
===================================================================
--- libc/elf/dl-support.c	(revision 13883)
+++ libc/elf/dl-support.c	(working copy)
@@ -56,6 +56,9 @@
    ignored.  */
 const char *_dl_inhibit_rpath;
 
+/* prefix to be added to all RUNPATHs and RPATHs */
+const char *_dl_rpath_prefix = NULL;
+
 /* The map for the object we will profile.  */
 struct link_map *_dl_profile_map;
 
Index: libc/elf/rtld.c
===================================================================
--- libc/elf/rtld.c	(revision 13883)
+++ libc/elf/rtld.c	(working copy)
@@ -978,6 +978,15 @@
 	    _dl_argc -= 2;
 	    INTUSE(_dl_argv) += 2;
 	  }
+	else if (! strcmp (INTUSE(_dl_argv)[1], "--rpath-prefix")
+		 && _dl_argc > 2)
+	  {
+	    GLRO(dl_rpath_prefix) = INTUSE(_dl_argv)[2];
+
+	    _dl_skip_args += 2;
+	    _dl_argc -= 2;
+	    INTUSE(_dl_argv) += 2;
+	  }
 	else if (! strcmp (INTUSE(_dl_argv)[1], "--audit") && _dl_argc > 2)
 	  {
 	    process_dl_audit (INTUSE(_dl_argv)[2]);
@@ -1011,6 +1020,7 @@
                         object we can handle\n\
   --library-path PATH   use given PATH instead of content of the environment\n\
                         variable LD_LIBRARY_PATH\n\
+  --rpath-prefix PREFIX add PREFIX to every RUNPATH and RPATH component\n\
   --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object names\n\
                         in LIST\n\
   --audit LIST          use objects named in LIST as auditors\n");
Index: libc/sysdeps/generic/ldsodefs.h
===================================================================
--- libc/sysdeps/generic/ldsodefs.h	(revision 13883)
+++ libc/sysdeps/generic/ldsodefs.h	(working copy)
@@ -664,6 +664,12 @@
 
   /* 0 if internal pointer values should not be guarded, 1 if they should.  */
   EXTERN int _dl_pointer_guard;
+#endif
+
+  /* prefix for RPATH + RUNPATH components.  */
+  EXTERN const char *_dl_rpath_prefix;
+
+#ifdef SHARED
 };
 # define __rtld_global_attribute__
 # ifdef IS_IN_rtld
@@ -1047,7 +1053,8 @@
 
 /* Substitute DST values.  */
 extern char *_dl_dst_substitute (struct link_map *l, const char *name,
-				 char *result, int is_path) attribute_hidden;
+				 char *result, int is_path,
+				 const char *rpath_prefix) attribute_hidden;
 
 /* Check validity of the caller.  */
 extern int _dl_check_caller (const void *caller, enum allowmask mask)
Index: libc/elf/dl-open.c
===================================================================
--- libc/elf/dl-open.c	(revision 13883)
+++ libc/elf/dl-open.c	(working copy)
@@ -269,7 +269,7 @@
       char *new_file = (char *) alloca (required + 1);
 
       /* Generate the new file name.  */
-      _dl_dst_substitute (call_map, file, new_file, 0);
+      _dl_dst_substitute (call_map, file, new_file, 0, NULL);
 
       /* If the substitution failed don't try to load.  */
       if (*new_file == '\0')
Index: libc/elf/dl-deps.c
===================================================================
--- libc/elf/dl-deps.c	(revision 13883)
+++ libc/elf/dl-deps.c	(working copy)
@@ -117,7 +117,7 @@
 	__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str),  \
 						   __dst_cnt));		      \
 									      \
-	__result = _dl_dst_substitute (l, __str, __newp, 0);		      \
+	__result = _dl_dst_substitute (l, __str, __newp, 0, NULL);	      \
 									      \
 	if (*__result == '\0')						      \
 	  {								      \