Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 224901 | Differences between
and this patch

Collapse All | Expand All

(-)cmake-2.6.1-orig/Source/cmFileCommand.cxx (-3 / +14 lines)
Lines 1486-1492 cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args) Link Here
1486
  cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
1486
  cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
1487
  bool have_ft = cmSystemTools::FileTimeGet(file, ft);
1487
  bool have_ft = cmSystemTools::FileTimeGet(file, ft);
1488
  std::string emsg;
1488
  std::string emsg;
1489
  if(!cmSystemTools::RemoveRPath(file, &emsg))
1489
  bool removed;
1490
  if(!cmSystemTools::RemoveRPath(file, &emsg, &removed))
1490
    {
1491
    {
1491
    cmOStringStream e;
1492
    cmOStringStream e;
1492
    e << "RPATH_REMOVE could not remove RPATH from file:\n"
1493
    e << "RPATH_REMOVE could not remove RPATH from file:\n"
Lines 1495-1503 cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args) Link Here
1495
    this->SetError(e.str().c_str());
1496
    this->SetError(e.str().c_str());
1496
    success = false;
1497
    success = false;
1497
    }
1498
    }
1498
  if(success && have_ft)
1499
  if(success)
1499
    {
1500
    {
1500
    cmSystemTools::FileTimeSet(file, ft);
1501
    if(removed)
1502
      {
1503
      std::string message = "Removed runtime path from \"";
1504
      message += file;
1505
      message += "\"";
1506
      this->Makefile->DisplayStatus(message.c_str(), -1);
1507
      }
1508
    if(have_ft)
1509
      {
1510
      cmSystemTools::FileTimeSet(file, ft);
1511
      }
1501
    }
1512
    }
1502
  cmSystemTools::FileTimeDelete(ft);
1513
  cmSystemTools::FileTimeDelete(ft);
1503
  return success;
1514
  return success;
(-)cmake-2.6.1-orig/Source/cmSystemTools.cxx (-132 / +221 lines)
Lines 26-31 Link Here
26
#if defined(CMAKE_BUILD_WITH_CMAKE)
26
#if defined(CMAKE_BUILD_WITH_CMAKE)
27
# include <cmsys/Terminal.h>
27
# include <cmsys/Terminal.h>
28
#endif
28
#endif
29
#include <cmsys/stl/algorithm>
29
30
30
#if defined(_WIN32)
31
#if defined(_WIN32)
31
# include <windows.h>
32
# include <windows.h>
Lines 2328-2333 std::string::size_type cmSystemToolsFindRPath(std::string const& have, Link Here
2328
}
2329
}
2329
#endif
2330
#endif
2330
2331
2332
#if defined(CMAKE_USE_ELF_PARSER)
2333
struct cmSystemToolsRPathInfo
2334
{
2335
  unsigned long Position;
2336
  unsigned long Size;
2337
  std::string Name;
2338
  std::string Value;
2339
};
2340
#endif
2341
2331
//----------------------------------------------------------------------------
2342
//----------------------------------------------------------------------------
2332
bool cmSystemTools::ChangeRPath(std::string const& file,
2343
bool cmSystemTools::ChangeRPath(std::string const& file,
2333
                                std::string const& oldRPath,
2344
                                std::string const& oldRPath,
Lines 2340-2376 bool cmSystemTools::ChangeRPath(std::string const& file, Link Here
2340
    {
2351
    {
2341
    *changed = false;
2352
    *changed = false;
2342
    }
2353
    }
2343
  unsigned long rpathPosition = 0;
2354
  int rp_count = 0;
2344
  unsigned long rpathSize = 0;
2355
  cmSystemToolsRPathInfo rp[2];
2345
  std::string rpathPrefix;
2346
  std::string rpathSuffix;
2347
  {
2356
  {
2348
  // Parse the ELF binary.
2357
  // Parse the ELF binary.
2349
  cmELF elf(file.c_str());
2358
  cmELF elf(file.c_str());
2350
2359
2351
  // Get the RPATH or RUNPATH entry from it.
2360
  // Get the RPATH and RUNPATH entries from it.
2352
  cmELF::StringEntry const* se = elf.GetRPath();
2361
  int se_count = 0;
2353
  if(!se)
2362
  cmELF::StringEntry const* se[2] = {0, 0};
2363
  const char* se_name[2] = {0, 0};
2364
  if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
2354
    {
2365
    {
2355
    se = elf.GetRunPath();
2366
    se[se_count] = se_rpath;
2367
    se_name[se_count] = "RPATH";
2368
    ++se_count;
2369
    }
2370
  if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
2371
    {
2372
    se[se_count] = se_runpath;
2373
    se_name[se_count] = "RUNPATH";
2374
    ++se_count;
2375
    }
2376
  if(se_count == 0)
2377
    {
2378
    if(newRPath.empty())
2379
      {
2380
      // The new rpath is empty and there is no rpath anyway so it is
2381
      // okay.
2382
      return true;
2383
      }
2384
    else
2385
      {
2386
      if(emsg)
2387
        {
2388
        *emsg = "No valid ELF RPATH or RUNPATH entry exists in the file; ";
2389
        *emsg += elf.GetErrorMessage();
2390
        }
2391
      return false;
2392
      }
2356
    }
2393
    }
2357
2394
2358
  if(se)
2395
  for(int i=0; i < se_count; ++i)
2359
    {
2396
    {
2397
    // If both RPATH and RUNPATH refer to the same string literal it
2398
    // needs to be changed only once.
2399
    if(rp_count && rp[0].Position == se[i]->Position)
2400
      {
2401
      continue;
2402
      }
2403
2360
    // Make sure the current rpath contains the old rpath.
2404
    // Make sure the current rpath contains the old rpath.
2361
    std::string::size_type pos = cmSystemToolsFindRPath(se->Value, oldRPath);
2405
    std::string::size_type pos =
2406
      cmSystemToolsFindRPath(se[i]->Value, oldRPath);
2362
    if(pos == std::string::npos)
2407
    if(pos == std::string::npos)
2363
      {
2408
      {
2364
      // If it contains the new rpath instead then it is okay.
2409
      // If it contains the new rpath instead then it is okay.
2365
      if(cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos)
2410
      if(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos)
2366
        {
2411
        {
2367
        return true;
2412
        continue;
2368
        }
2413
        }
2369
      if(emsg)
2414
      if(emsg)
2370
        {
2415
        {
2371
        cmOStringStream e;
2416
        cmOStringStream e;
2372
        e << "The current RPATH is:\n"
2417
        e << "The current " << se_name[i] << " is:\n"
2373
          << "  " << se->Value << "\n"
2418
          << "  " << se[i]->Value << "\n"
2374
          << "which does not contain:\n"
2419
          << "which does not contain:\n"
2375
          << "  " << oldRPath << "\n"
2420
          << "  " << oldRPath << "\n"
2376
          << "as was expected.";
2421
          << "as was expected.";
Lines 2379-2425 bool cmSystemTools::ChangeRPath(std::string const& file, Link Here
2379
      return false;
2424
      return false;
2380
      }
2425
      }
2381
2426
2382
    // Store information about the entry.
2427
    // Store information about the entry in the file.
2383
    rpathPosition = se->Position;
2428
    rp[rp_count].Position = se[i]->Position;
2384
    rpathSize = se->Size;
2429
    rp[rp_count].Size = se[i]->Size;
2430
    rp[rp_count].Name = se_name[i];
2385
2431
2386
    // Store the part of the path we must preserve.
2432
    // Construct the new value which preserves the part of the path
2387
    rpathPrefix = se->Value.substr(0, pos);
2433
    // not being changed.
2388
    rpathSuffix = se->Value.substr(pos+oldRPath.length(), oldRPath.npos);
2434
    rp[rp_count].Value = se[i]->Value.substr(0, pos);
2389
    }
2435
    rp[rp_count].Value += newRPath;
2390
  else if(newRPath.empty())
2436
    rp[rp_count].Value += se[i]->Value.substr(pos+oldRPath.length(),
2391
    {
2437
                                              oldRPath.npos);
2392
    // The new rpath is empty and there is no rpath anyway so it is
2438
2393
    // okay.
2439
    // Make sure there is enough room to store the new rpath and at
2394
    return true;
2440
    // least one null terminator.
2395
    }
2441
    if(rp[rp_count].Size < rp[rp_count].Value.length()+1)
2396
  else
2397
    {
2398
    if(emsg)
2399
      {
2442
      {
2400
      *emsg = "No valid ELF RPATH entry exists in the file; ";
2443
      if(emsg)
2401
      *emsg += elf.GetErrorMessage();
2444
        {
2445
        *emsg = "The replacement path is too long for the ";
2446
        *emsg += se_name[i];
2447
        *emsg += " entry.";
2448
        }
2449
      return false;
2402
      }
2450
      }
2403
    return false;
2451
2452
    // This entry is ready for update.
2453
    ++rp_count;
2404
    }
2454
    }
2405
  }
2455
  }
2406
  // Compute the full new rpath.
2407
  std::string rpath = rpathPrefix;
2408
  rpath += newRPath;
2409
  rpath += rpathSuffix;
2410
2456
2411
  // Make sure there is enough room to store the new rpath and at
2457
  // If no runtime path needs to be changed, we are done.
2412
  // least one null terminator.
2458
  if(rp_count == 0)
2413
  if(rpathSize < rpath.length()+1)
2414
    {
2459
    {
2415
    if(emsg)
2460
    return true;
2416
      {
2417
      *emsg = "The replacement RPATH is too long.";
2418
      }
2419
    return false;
2420
    }
2461
    }
2421
2462
2422
  // Open the file for update and seek to the RPATH position.
2463
  // Open the file for update.
2423
  std::ofstream f(file.c_str(),
2464
  std::ofstream f(file.c_str(),
2424
                  std::ios::in | std::ios::out | std::ios::binary);
2465
                  std::ios::in | std::ios::out | std::ios::binary);
2425
  if(!f)
2466
  if(!f)
Lines 2430-2469 bool cmSystemTools::ChangeRPath(std::string const& file, Link Here
2430
      }
2471
      }
2431
    return false;
2472
    return false;
2432
    }
2473
    }
2433
  if(!f.seekp(rpathPosition))
2474
2475
  // Store the new RPATH and RUNPATH strings.
2476
  for(int i=0; i < rp_count; ++i)
2434
    {
2477
    {
2435
    if(emsg)
2478
    // Seek to the RPATH position.
2479
    if(!f.seekp(rp[i].Position))
2436
      {
2480
      {
2437
      *emsg = "Error seeking to RPATH position.";
2481
      if(emsg)
2482
        {
2483
        *emsg = "Error seeking to ";
2484
        *emsg += rp[i].Name;
2485
        *emsg += " position.";
2486
        }
2487
      return false;
2438
      }
2488
      }
2439
    return false;
2440
    }
2441
2489
2442
  // Write the new rpath.  Follow it with enough null terminators to
2490
    // Write the new rpath.  Follow it with enough null terminators to
2443
  // fill the string table entry.
2491
    // fill the string table entry.
2444
  f << rpath;
2492
    f << rp[i].Value;
2445
  for(unsigned long i=rpath.length(); i < rpathSize; ++i)
2493
    for(unsigned long j=rp[i].Value.length(); j < rp[i].Size; ++j)
2446
    {
2494
      {
2447
    f << '\0';
2495
      f << '\0';
2448
    }
2496
      }
2449
2497
2450
  // Make sure everything was okay.
2498
    // Make sure it wrote correctly.
2451
  if(f)
2499
    if(!f)
2452
    {
2453
    if(changed)
2454
      {
2500
      {
2455
      *changed = true;
2501
      if(emsg)
2502
        {
2503
        *emsg = "Error writing the new ";
2504
        *emsg += rp[i].Name;
2505
        *emsg += " string to the file.";
2506
        }
2507
      return false;
2456
      }
2508
      }
2457
    return true;
2458
    }
2509
    }
2459
  else
2510
2511
  // Everything was updated successfully.
2512
  if(changed)
2460
    {
2513
    {
2461
    if(emsg)
2514
    *changed = true;
2462
      {
2463
      *emsg = "Error writing the new rpath to the file.";
2464
      }
2465
    return false;
2466
    }
2515
    }
2516
  return true;
2467
#else
2517
#else
2468
  (void)file;
2518
  (void)file;
2469
  (void)oldRPath;
2519
  (void)oldRPath;
Lines 2475-2531 bool cmSystemTools::ChangeRPath(std::string const& file, Link Here
2475
}
2525
}
2476
2526
2477
//----------------------------------------------------------------------------
2527
//----------------------------------------------------------------------------
2478
bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
2528
bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
2529
                                bool* removed)
2479
{
2530
{
2480
#if defined(CMAKE_USE_ELF_PARSER)
2531
#if defined(CMAKE_USE_ELF_PARSER)
2481
  unsigned long rpathPosition = 0;
2532
  if(removed)
2482
  unsigned long rpathSize = 0;
2533
    {
2483
  unsigned long rpathEntryPosition = 0;
2534
    *removed = false;
2535
    }
2536
  int zeroCount = 0;
2537
  unsigned long zeroPosition[2] = {0,0};
2538
  unsigned long zeroSize[2] = {0,0};
2539
  unsigned long bytesBegin = 0;
2484
  std::vector<char> bytes;
2540
  std::vector<char> bytes;
2485
  {
2541
  {
2486
  // Parse the ELF binary.
2542
  // Parse the ELF binary.
2487
  cmELF elf(file.c_str());
2543
  cmELF elf(file.c_str());
2488
2544
2489
  // Get the RPATH or RUNPATH entry from it.
2545
  // Get the RPATH and RUNPATH entries from it and sort them by index
2490
  cmELF::StringEntry const* se = elf.GetRPath();
2546
  // in the dynamic section header.
2491
  if(!se)
2547
  int se_count = 0;
2548
  cmELF::StringEntry const* se[2] = {0, 0};
2549
  if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
2492
    {
2550
    {
2493
    se = elf.GetRunPath();
2551
    se[se_count++] = se_rpath;
2494
    }
2552
    }
2495
2553
  if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
2496
  if(se)
2497
    {
2554
    {
2498
    // Store information about the entry.
2555
    se[se_count++] = se_runpath;
2499
    rpathPosition = se->Position;
2556
    }
2500
    rpathSize = se->Size;
2557
  if(se_count == 0)
2501
    rpathEntryPosition = elf.GetDynamicEntryPosition(se->IndexInSection);
2558
    {
2559
    // There is no RPATH or RUNPATH anyway.
2560
    return true;
2561
    }
2562
  if(se_count == 2 && se[1]->IndexInSection < se[0]->IndexInSection)
2563
    {
2564
    cmsys_stl::swap(se[0], se[1]);
2565
    }
2502
2566
2503
    // Get the file range containing the rest of the DYNAMIC table
2567
  // Get the size of the dynamic section header.
2504
    // after the RPATH entry.
2568
  unsigned int count = elf.GetDynamicEntryCount();
2505
    unsigned long nextEntryPosition =
2569
  if(count == 0)
2506
      elf.GetDynamicEntryPosition(se->IndexInSection+1);
2570
    {
2507
    unsigned int count = elf.GetDynamicEntryCount();
2571
    // This should happen only for invalid ELF files where a DT_NULL
2508
    if(count == 0)
2572
    // appears before the end of the table.
2573
    if(emsg)
2509
      {
2574
      {
2510
      // This should happen only for invalid ELF files where a DT_NULL
2575
      *emsg = "DYNAMIC section contains a DT_NULL before the end.";
2511
      // appears before the end of the table.
2512
      if(emsg)
2513
        {
2514
        *emsg = "DYNAMIC section contains a DT_NULL before the end.";
2515
        }
2516
      return false;
2517
      }
2576
      }
2518
    unsigned long nullEntryPosition = elf.GetDynamicEntryPosition(count);
2577
    return false;
2578
    }
2579
2580
  // Save information about the string entries to be zeroed.
2581
  zeroCount = se_count;
2582
  for(int i=0; i < se_count; ++i)
2583
    {
2584
    zeroPosition[i] = se[i]->Position;
2585
    zeroSize[i] = se[i]->Size;
2586
    }
2587
2588
  // Get the range of file positions corresponding to each entry and
2589
  // the rest of the table after them.
2590
  unsigned long entryBegin[3] = {0,0,0};
2591
  unsigned long entryEnd[2] = {0,0};
2592
  for(int i=0; i < se_count; ++i)
2593
    {
2594
    entryBegin[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection);
2595
    entryEnd[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection+1);
2596
    }
2597
  entryBegin[se_count] = elf.GetDynamicEntryPosition(count);
2598
2599
  // The data are to be written over the old table entries starting at
2600
  // the first one being removed.
2601
  bytesBegin = entryBegin[0];
2602
  unsigned long bytesEnd = entryBegin[se_count];
2519
2603
2520
    // Allocate and fill a buffer with zeros.
2604
  // Allocate a buffer to hold the part of the file to be written.
2521
    bytes.resize(nullEntryPosition - rpathEntryPosition, 0);
2605
  // Initialize it with zeros.
2606
  bytes.resize(bytesEnd - bytesBegin, 0);
2522
2607
2523
    // Read the part of the DYNAMIC section header that will move.
2608
  // Read the part of the DYNAMIC section header that will move.
2524
    // The remainder of the buffer will be left with zeros which
2609
  // The remainder of the buffer will be left with zeros which
2525
    // represent a DT_NULL entry.
2610
  // represent a DT_NULL entry.
2526
    if(!elf.ReadBytes(nextEntryPosition,
2611
  char* data = &bytes[0];
2527
                      nullEntryPosition - nextEntryPosition,
2612
  for(int i=0; i < se_count; ++i)
2528
                      &bytes[0]))
2613
    {
2614
    // Read data between the entries being removed.
2615
    unsigned long sz = entryBegin[i+1] - entryEnd[i];
2616
    if(sz > 0 && !elf.ReadBytes(entryEnd[i], sz, data))
2529
      {
2617
      {
2530
      if(emsg)
2618
      if(emsg)
2531
        {
2619
        {
Lines 2533-2543 bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg) Link Here
2533
        }
2621
        }
2534
      return false;
2622
      return false;
2535
      }
2623
      }
2536
    }
2624
    data += sz;
2537
  else
2538
    {
2539
    // There is no RPATH or RUNPATH anyway.
2540
    return true;
2541
    }
2625
    }
2542
  }
2626
  }
2543
2627
Lines 2554-2560 bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg) Link Here
2554
    }
2638
    }
2555
2639
2556
  // Write the new DYNAMIC table header.
2640
  // Write the new DYNAMIC table header.
2557
  if(!f.seekp(rpathEntryPosition))
2641
  if(!f.seekp(bytesBegin))
2558
    {
2642
    {
2559
    if(emsg)
2643
    if(emsg)
2560
      {
2644
      {
Lines 2571-2606 bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg) Link Here
2571
    return false;
2655
    return false;
2572
    }
2656
    }
2573
2657
2574
  // Fill the RPATH string with zero bytes.
2658
  // Fill the RPATH and RUNPATH strings with zero bytes.
2575
  if(!f.seekp(rpathPosition))
2659
  for(int i=0; i < zeroCount; ++i)
2576
    {
2660
    {
2577
    if(emsg)
2661
    if(!f.seekp(zeroPosition[i]))
2578
      {
2662
      {
2579
      *emsg = "Error seeking to RPATH position.";
2663
      if(emsg)
2664
        {
2665
        *emsg = "Error seeking to RPATH position.";
2666
        }
2667
      return false;
2668
      }
2669
    for(unsigned long j=0; j < zeroSize[i]; ++j)
2670
      {
2671
      f << '\0';
2672
      }
2673
    if(!f)
2674
      {
2675
      if(emsg)
2676
        {
2677
        *emsg = "Error writing the empty rpath string to the file.";
2678
        }
2679
      return false;
2580
      }
2680
      }
2581
    return false;
2582
    }
2583
  for(unsigned long i=0; i < rpathSize; ++i)
2584
    {
2585
    f << '\0';
2586
    }
2681
    }
2587
2682
2588
  // Make sure everything was okay.
2683
  // Everything was updated successfully.
2589
  if(f)
2684
  if(removed)
2590
    {
2591
    return true;
2592
    }
2593
  else
2594
    {
2685
    {
2595
    if(emsg)
2686
    *removed = true;
2596
      {
2597
      *emsg = "Error writing the empty rpath to the file.";
2598
      }
2599
    return false;
2600
    }
2687
    }
2688
  return true;
2601
#else
2689
#else
2602
  (void)file;
2690
  (void)file;
2603
  (void)emsg;
2691
  (void)emsg;
2692
  (void)removed;
2604
  return false;
2693
  return false;
2605
#endif
2694
#endif
2606
}
2695
}
(-)cmake-2.6.1-orig/Source/cmSystemTools.h (-1 / +2 lines)
Lines 396-402 public: Link Here
396
                          bool* changed = 0);
396
                          bool* changed = 0);
397
397
398
  /** Try to remove the RPATH from an ELF binary.  */
398
  /** Try to remove the RPATH from an ELF binary.  */
399
  static bool RemoveRPath(std::string const& file, std::string* emsg = 0);
399
  static bool RemoveRPath(std::string const& file, std::string* emsg = 0,
400
                          bool* removed = 0);
400
401
401
  /** Check whether the RPATH in an ELF binary contains the path
402
  /** Check whether the RPATH in an ELF binary contains the path
402
      given.  */
403
      given.  */

Return to bug 224901