/[gentoo-x86]/dev-util/cmake/files/cmake-2.6.1-rpath.patch
Gentoo

Contents of /dev-util/cmake/files/cmake-2.6.1-rpath.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations) (download)
Tue Dec 2 23:25:37 2008 UTC (5 years, 7 months ago) by scarabeus
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +0 -0 lines
FILE REMOVED
Dupe old. Update current to eapi2. Fixes bug #226153.
(Portage version: 2.2_rc16/cvs/Linux 2.6.27-gentoo x86_64)

1 diff --git cmake-2.6.1-orig/Source/cmFileCommand.cxx cmake-2.6.1/Source/cmFileCommand.cxx
2 index 6ac6bcc..e8e64a4 100644
3 --- cmake-2.6.1-orig/Source/cmFileCommand.cxx
4 +++ cmake-2.6.1/Source/cmFileCommand.cxx
5 @@ -1486,7 +1486,8 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
6 cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
7 bool have_ft = cmSystemTools::FileTimeGet(file, ft);
8 std::string emsg;
9 - if(!cmSystemTools::RemoveRPath(file, &emsg))
10 + bool removed;
11 + if(!cmSystemTools::RemoveRPath(file, &emsg, &removed))
12 {
13 cmOStringStream e;
14 e << "RPATH_REMOVE could not remove RPATH from file:\n"
15 @@ -1495,9 +1496,19 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
16 this->SetError(e.str().c_str());
17 success = false;
18 }
19 - if(success && have_ft)
20 + if(success)
21 {
22 - cmSystemTools::FileTimeSet(file, ft);
23 + if(removed)
24 + {
25 + std::string message = "Removed runtime path from \"";
26 + message += file;
27 + message += "\"";
28 + this->Makefile->DisplayStatus(message.c_str(), -1);
29 + }
30 + if(have_ft)
31 + {
32 + cmSystemTools::FileTimeSet(file, ft);
33 + }
34 }
35 cmSystemTools::FileTimeDelete(ft);
36 return success;
37 diff --git cmake-2.6.1-orig/Source/cmSystemTools.cxx cmake-2.6.1/Source/cmSystemTools.cxx
38 index 4e1f945..f333a4c 100644
39 --- cmake-2.6.1-orig/Source/cmSystemTools.cxx
40 +++ cmake-2.6.1/Source/cmSystemTools.cxx
41 @@ -26,6 +26,7 @@
42 #if defined(CMAKE_BUILD_WITH_CMAKE)
43 # include <cmsys/Terminal.h>
44 #endif
45 +#include <cmsys/stl/algorithm>
46
47 #if defined(_WIN32)
48 # include <windows.h>
49 @@ -2328,6 +2329,16 @@ std::string::size_type cmSystemToolsFindRPath(std::string const& have,
50 }
51 #endif
52
53 +#if defined(CMAKE_USE_ELF_PARSER)
54 +struct cmSystemToolsRPathInfo
55 +{
56 + unsigned long Position;
57 + unsigned long Size;
58 + std::string Name;
59 + std::string Value;
60 +};
61 +#endif
62 +
63 //----------------------------------------------------------------------------
64 bool cmSystemTools::ChangeRPath(std::string const& file,
65 std::string const& oldRPath,
66 @@ -2340,37 +2351,71 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
67 {
68 *changed = false;
69 }
70 - unsigned long rpathPosition = 0;
71 - unsigned long rpathSize = 0;
72 - std::string rpathPrefix;
73 - std::string rpathSuffix;
74 + int rp_count = 0;
75 + cmSystemToolsRPathInfo rp[2];
76 {
77 // Parse the ELF binary.
78 cmELF elf(file.c_str());
79
80 - // Get the RPATH or RUNPATH entry from it.
81 - cmELF::StringEntry const* se = elf.GetRPath();
82 - if(!se)
83 + // Get the RPATH and RUNPATH entries from it.
84 + int se_count = 0;
85 + cmELF::StringEntry const* se[2] = {0, 0};
86 + const char* se_name[2] = {0, 0};
87 + if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
88 {
89 - se = elf.GetRunPath();
90 + se[se_count] = se_rpath;
91 + se_name[se_count] = "RPATH";
92 + ++se_count;
93 + }
94 + if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
95 + {
96 + se[se_count] = se_runpath;
97 + se_name[se_count] = "RUNPATH";
98 + ++se_count;
99 + }
100 + if(se_count == 0)
101 + {
102 + if(newRPath.empty())
103 + {
104 + // The new rpath is empty and there is no rpath anyway so it is
105 + // okay.
106 + return true;
107 + }
108 + else
109 + {
110 + if(emsg)
111 + {
112 + *emsg = "No valid ELF RPATH or RUNPATH entry exists in the file; ";
113 + *emsg += elf.GetErrorMessage();
114 + }
115 + return false;
116 + }
117 }
118
119 - if(se)
120 + for(int i=0; i < se_count; ++i)
121 {
122 + // If both RPATH and RUNPATH refer to the same string literal it
123 + // needs to be changed only once.
124 + if(rp_count && rp[0].Position == se[i]->Position)
125 + {
126 + continue;
127 + }
128 +
129 // Make sure the current rpath contains the old rpath.
130 - std::string::size_type pos = cmSystemToolsFindRPath(se->Value, oldRPath);
131 + std::string::size_type pos =
132 + cmSystemToolsFindRPath(se[i]->Value, oldRPath);
133 if(pos == std::string::npos)
134 {
135 // If it contains the new rpath instead then it is okay.
136 - if(cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos)
137 + if(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos)
138 {
139 - return true;
140 + continue;
141 }
142 if(emsg)
143 {
144 cmOStringStream e;
145 - e << "The current RPATH is:\n"
146 - << " " << se->Value << "\n"
147 + e << "The current " << se_name[i] << " is:\n"
148 + << " " << se[i]->Value << "\n"
149 << "which does not contain:\n"
150 << " " << oldRPath << "\n"
151 << "as was expected.";
152 @@ -2379,47 +2424,43 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
153 return false;
154 }
155
156 - // Store information about the entry.
157 - rpathPosition = se->Position;
158 - rpathSize = se->Size;
159 + // Store information about the entry in the file.
160 + rp[rp_count].Position = se[i]->Position;
161 + rp[rp_count].Size = se[i]->Size;
162 + rp[rp_count].Name = se_name[i];
163
164 - // Store the part of the path we must preserve.
165 - rpathPrefix = se->Value.substr(0, pos);
166 - rpathSuffix = se->Value.substr(pos+oldRPath.length(), oldRPath.npos);
167 - }
168 - else if(newRPath.empty())
169 - {
170 - // The new rpath is empty and there is no rpath anyway so it is
171 - // okay.
172 - return true;
173 - }
174 - else
175 - {
176 - if(emsg)
177 + // Construct the new value which preserves the part of the path
178 + // not being changed.
179 + rp[rp_count].Value = se[i]->Value.substr(0, pos);
180 + rp[rp_count].Value += newRPath;
181 + rp[rp_count].Value += se[i]->Value.substr(pos+oldRPath.length(),
182 + oldRPath.npos);
183 +
184 + // Make sure there is enough room to store the new rpath and at
185 + // least one null terminator.
186 + if(rp[rp_count].Size < rp[rp_count].Value.length()+1)
187 {
188 - *emsg = "No valid ELF RPATH entry exists in the file; ";
189 - *emsg += elf.GetErrorMessage();
190 + if(emsg)
191 + {
192 + *emsg = "The replacement path is too long for the ";
193 + *emsg += se_name[i];
194 + *emsg += " entry.";
195 + }
196 + return false;
197 }
198 - return false;
199 +
200 + // This entry is ready for update.
201 + ++rp_count;
202 }
203 }
204 - // Compute the full new rpath.
205 - std::string rpath = rpathPrefix;
206 - rpath += newRPath;
207 - rpath += rpathSuffix;
208
209 - // Make sure there is enough room to store the new rpath and at
210 - // least one null terminator.
211 - if(rpathSize < rpath.length()+1)
212 + // If no runtime path needs to be changed, we are done.
213 + if(rp_count == 0)
214 {
215 - if(emsg)
216 - {
217 - *emsg = "The replacement RPATH is too long.";
218 - }
219 - return false;
220 + return true;
221 }
222
223 - // Open the file for update and seek to the RPATH position.
224 + // Open the file for update.
225 std::ofstream f(file.c_str(),
226 std::ios::in | std::ios::out | std::ios::binary);
227 if(!f)
228 @@ -2430,40 +2471,49 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
229 }
230 return false;
231 }
232 - if(!f.seekp(rpathPosition))
233 +
234 + // Store the new RPATH and RUNPATH strings.
235 + for(int i=0; i < rp_count; ++i)
236 {
237 - if(emsg)
238 + // Seek to the RPATH position.
239 + if(!f.seekp(rp[i].Position))
240 {
241 - *emsg = "Error seeking to RPATH position.";
242 + if(emsg)
243 + {
244 + *emsg = "Error seeking to ";
245 + *emsg += rp[i].Name;
246 + *emsg += " position.";
247 + }
248 + return false;
249 }
250 - return false;
251 - }
252
253 - // Write the new rpath. Follow it with enough null terminators to
254 - // fill the string table entry.
255 - f << rpath;
256 - for(unsigned long i=rpath.length(); i < rpathSize; ++i)
257 - {
258 - f << '\0';
259 - }
260 + // Write the new rpath. Follow it with enough null terminators to
261 + // fill the string table entry.
262 + f << rp[i].Value;
263 + for(unsigned long j=rp[i].Value.length(); j < rp[i].Size; ++j)
264 + {
265 + f << '\0';
266 + }
267
268 - // Make sure everything was okay.
269 - if(f)
270 - {
271 - if(changed)
272 + // Make sure it wrote correctly.
273 + if(!f)
274 {
275 - *changed = true;
276 + if(emsg)
277 + {
278 + *emsg = "Error writing the new ";
279 + *emsg += rp[i].Name;
280 + *emsg += " string to the file.";
281 + }
282 + return false;
283 }
284 - return true;
285 }
286 - else
287 +
288 + // Everything was updated successfully.
289 + if(changed)
290 {
291 - if(emsg)
292 - {
293 - *emsg = "Error writing the new rpath to the file.";
294 - }
295 - return false;
296 + *changed = true;
297 }
298 + return true;
299 #else
300 (void)file;
301 (void)oldRPath;
302 @@ -2475,57 +2525,95 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
303 }
304
305 //----------------------------------------------------------------------------
306 -bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
307 +bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
308 + bool* removed)
309 {
310 #if defined(CMAKE_USE_ELF_PARSER)
311 - unsigned long rpathPosition = 0;
312 - unsigned long rpathSize = 0;
313 - unsigned long rpathEntryPosition = 0;
314 + if(removed)
315 + {
316 + *removed = false;
317 + }
318 + int zeroCount = 0;
319 + unsigned long zeroPosition[2] = {0,0};
320 + unsigned long zeroSize[2] = {0,0};
321 + unsigned long bytesBegin = 0;
322 std::vector<char> bytes;
323 {
324 // Parse the ELF binary.
325 cmELF elf(file.c_str());
326
327 - // Get the RPATH or RUNPATH entry from it.
328 - cmELF::StringEntry const* se = elf.GetRPath();
329 - if(!se)
330 + // Get the RPATH and RUNPATH entries from it and sort them by index
331 + // in the dynamic section header.
332 + int se_count = 0;
333 + cmELF::StringEntry const* se[2] = {0, 0};
334 + if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
335 {
336 - se = elf.GetRunPath();
337 + se[se_count++] = se_rpath;
338 }
339 -
340 - if(se)
341 + if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
342 {
343 - // Store information about the entry.
344 - rpathPosition = se->Position;
345 - rpathSize = se->Size;
346 - rpathEntryPosition = elf.GetDynamicEntryPosition(se->IndexInSection);
347 + se[se_count++] = se_runpath;
348 + }
349 + if(se_count == 0)
350 + {
351 + // There is no RPATH or RUNPATH anyway.
352 + return true;
353 + }
354 + if(se_count == 2 && se[1]->IndexInSection < se[0]->IndexInSection)
355 + {
356 + cmsys_stl::swap(se[0], se[1]);
357 + }
358
359 - // Get the file range containing the rest of the DYNAMIC table
360 - // after the RPATH entry.
361 - unsigned long nextEntryPosition =
362 - elf.GetDynamicEntryPosition(se->IndexInSection+1);
363 - unsigned int count = elf.GetDynamicEntryCount();
364 - if(count == 0)
365 + // Get the size of the dynamic section header.
366 + unsigned int count = elf.GetDynamicEntryCount();
367 + if(count == 0)
368 + {
369 + // This should happen only for invalid ELF files where a DT_NULL
370 + // appears before the end of the table.
371 + if(emsg)
372 {
373 - // This should happen only for invalid ELF files where a DT_NULL
374 - // appears before the end of the table.
375 - if(emsg)
376 - {
377 - *emsg = "DYNAMIC section contains a DT_NULL before the end.";
378 - }
379 - return false;
380 + *emsg = "DYNAMIC section contains a DT_NULL before the end.";
381 }
382 - unsigned long nullEntryPosition = elf.GetDynamicEntryPosition(count);
383 + return false;
384 + }
385 +
386 + // Save information about the string entries to be zeroed.
387 + zeroCount = se_count;
388 + for(int i=0; i < se_count; ++i)
389 + {
390 + zeroPosition[i] = se[i]->Position;
391 + zeroSize[i] = se[i]->Size;
392 + }
393 +
394 + // Get the range of file positions corresponding to each entry and
395 + // the rest of the table after them.
396 + unsigned long entryBegin[3] = {0,0,0};
397 + unsigned long entryEnd[2] = {0,0};
398 + for(int i=0; i < se_count; ++i)
399 + {
400 + entryBegin[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection);
401 + entryEnd[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection+1);
402 + }
403 + entryBegin[se_count] = elf.GetDynamicEntryPosition(count);
404 +
405 + // The data are to be written over the old table entries starting at
406 + // the first one being removed.
407 + bytesBegin = entryBegin[0];
408 + unsigned long bytesEnd = entryBegin[se_count];
409
410 - // Allocate and fill a buffer with zeros.
411 - bytes.resize(nullEntryPosition - rpathEntryPosition, 0);
412 + // Allocate a buffer to hold the part of the file to be written.
413 + // Initialize it with zeros.
414 + bytes.resize(bytesEnd - bytesBegin, 0);
415
416 - // Read the part of the DYNAMIC section header that will move.
417 - // The remainder of the buffer will be left with zeros which
418 - // represent a DT_NULL entry.
419 - if(!elf.ReadBytes(nextEntryPosition,
420 - nullEntryPosition - nextEntryPosition,
421 - &bytes[0]))
422 + // Read the part of the DYNAMIC section header that will move.
423 + // The remainder of the buffer will be left with zeros which
424 + // represent a DT_NULL entry.
425 + char* data = &bytes[0];
426 + for(int i=0; i < se_count; ++i)
427 + {
428 + // Read data between the entries being removed.
429 + unsigned long sz = entryBegin[i+1] - entryEnd[i];
430 + if(sz > 0 && !elf.ReadBytes(entryEnd[i], sz, data))
431 {
432 if(emsg)
433 {
434 @@ -2533,11 +2621,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
435 }
436 return false;
437 }
438 - }
439 - else
440 - {
441 - // There is no RPATH or RUNPATH anyway.
442 - return true;
443 + data += sz;
444 }
445 }
446
447 @@ -2554,7 +2638,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
448 }
449
450 // Write the new DYNAMIC table header.
451 - if(!f.seekp(rpathEntryPosition))
452 + if(!f.seekp(bytesBegin))
453 {
454 if(emsg)
455 {
456 @@ -2571,36 +2655,41 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
457 return false;
458 }
459
460 - // Fill the RPATH string with zero bytes.
461 - if(!f.seekp(rpathPosition))
462 + // Fill the RPATH and RUNPATH strings with zero bytes.
463 + for(int i=0; i < zeroCount; ++i)
464 {
465 - if(emsg)
466 + if(!f.seekp(zeroPosition[i]))
467 {
468 - *emsg = "Error seeking to RPATH position.";
469 + if(emsg)
470 + {
471 + *emsg = "Error seeking to RPATH position.";
472 + }
473 + return false;
474 + }
475 + for(unsigned long j=0; j < zeroSize[i]; ++j)
476 + {
477 + f << '\0';
478 + }
479 + if(!f)
480 + {
481 + if(emsg)
482 + {
483 + *emsg = "Error writing the empty rpath string to the file.";
484 + }
485 + return false;
486 }
487 - return false;
488 - }
489 - for(unsigned long i=0; i < rpathSize; ++i)
490 - {
491 - f << '\0';
492 }
493
494 - // Make sure everything was okay.
495 - if(f)
496 - {
497 - return true;
498 - }
499 - else
500 + // Everything was updated successfully.
501 + if(removed)
502 {
503 - if(emsg)
504 - {
505 - *emsg = "Error writing the empty rpath to the file.";
506 - }
507 - return false;
508 + *removed = true;
509 }
510 + return true;
511 #else
512 (void)file;
513 (void)emsg;
514 + (void)removed;
515 return false;
516 #endif
517 }
518 diff --git cmake-2.6.1-orig/Source/cmSystemTools.h cmake-2.6.1/Source/cmSystemTools.h
519 index 493ff71..1ff12bf 100644
520 --- cmake-2.6.1-orig/Source/cmSystemTools.h
521 +++ cmake-2.6.1/Source/cmSystemTools.h
522 @@ -396,7 +396,8 @@ public:
523 bool* changed = 0);
524
525 /** Try to remove the RPATH from an ELF binary. */
526 - static bool RemoveRPath(std::string const& file, std::string* emsg = 0);
527 + static bool RemoveRPath(std::string const& file, std::string* emsg = 0,
528 + bool* removed = 0);
529
530 /** Check whether the RPATH in an ELF binary contains the path
531 given. */

  ViewVC Help
Powered by ViewVC 1.1.20