@@ -63,6 +63,8 @@ static bool clobberOldSections = true;
63
63
static std::vector<std::string> fileNames;
64
64
static std::string outputFileName;
65
65
static bool alwaysWrite = false ;
66
+ static std::string oldRPath;
67
+ static std::vector<std::string> neededLibraries;
66
68
#ifdef DEFAULT_PAGESIZE
67
69
static int forcedPageSize = DEFAULT_PAGESIZE;
68
70
#else
@@ -1645,7 +1647,7 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op,
1645
1647
1646
1648
switch (op) {
1647
1649
case rpPrint: {
1648
- printf ( " %s \n " , rpath ? rpath : " " );
1650
+ oldRPath = std::string ( rpath ? rpath : " " );
1649
1651
return ;
1650
1652
}
1651
1653
case rpRemove: {
@@ -1968,6 +1970,7 @@ void ElfFile<ElfFileParamNames>::addNeeded(const std::set<std::string> & libs)
1968
1970
template <ElfFileParams>
1969
1971
void ElfFile<ElfFileParamNames>::printNeededLibs() const
1970
1972
{
1973
+ neededLibraries.clear ();
1971
1974
const auto shdrDynamic = findSectionHeader (" .dynamic" );
1972
1975
const auto shdrDynStr = findSectionHeader (" .dynstr" );
1973
1976
const char *strTab = (const char *)fileContents->data () + rdi (shdrDynStr.sh_offset );
@@ -1977,7 +1980,7 @@ void ElfFile<ElfFileParamNames>::printNeededLibs() const
1977
1980
for (; rdi (dyn->d_tag ) != DT_NULL; dyn++) {
1978
1981
if (rdi (dyn->d_tag ) == DT_NEEDED) {
1979
1982
const char *name = strTab + rdi (dyn->d_un .d_val );
1980
- printf ( " %s \n " , name);
1983
+ neededLibraries. push_back ( name);
1981
1984
}
1982
1985
}
1983
1986
}
@@ -2569,196 +2572,33 @@ static void showHelp(const std::string & progName)
2569
2572
FILENAME...\n " , progName.c_str ());
2570
2573
}
2571
2574
2572
-
2573
- static int mainWrapped (int argc, char * * argv)
2575
+ std::string patchelf::get_rpath (const std::string& filename)
2574
2576
{
2575
- if (argc <= 1 ) {
2576
- showHelp (argv[0 ]);
2577
- return 1 ;
2578
- }
2579
-
2580
- if (getenv (" PATCHELF_DEBUG" ) != nullptr )
2581
- debugMode = true ;
2582
-
2583
- int i;
2584
- for (i = 1 ; i < argc; ++i) {
2585
- std::string arg (argv[i]);
2586
- if (arg == " --set-interpreter" || arg == " --interpreter" ) {
2587
- if (++i == argc) error (" missing argument" );
2588
- newInterpreter = resolveArgument (argv[i]);
2589
- }
2590
- else if (arg == " --page-size" ) {
2591
- if (++i == argc) error (" missing argument" );
2592
- forcedPageSize = atoi (argv[i]);
2593
- if (forcedPageSize <= 0 ) error (" invalid argument to --page-size" );
2594
- }
2595
- else if (arg == " --print-interpreter" ) {
2596
- printInterpreter = true ;
2597
- }
2598
- else if (arg == " --print-os-abi" ) {
2599
- printOsAbi = true ;
2600
- }
2601
- else if (arg == " --set-os-abi" ) {
2602
- if (++i == argc) error (" missing argument" );
2603
- setOsAbi = true ;
2604
- newOsAbi = resolveArgument (argv[i]);
2605
- }
2606
- else if (arg == " --print-soname" ) {
2607
- printSoname = true ;
2608
- }
2609
- else if (arg == " --set-soname" ) {
2610
- if (++i == argc) error (" missing argument" );
2611
- setSoname = true ;
2612
- newSoname = resolveArgument (argv[i]);
2613
- }
2614
- else if (arg == " --remove-rpath" ) {
2615
- removeRPath = true ;
2616
- }
2617
- else if (arg == " --shrink-rpath" ) {
2618
- shrinkRPath = true ;
2619
- }
2620
- else if (arg == " --allowed-rpath-prefixes" ) {
2621
- if (++i == argc) error (" missing argument" );
2622
- allowedRpathPrefixes = splitColonDelimitedString (argv[i]);
2623
- }
2624
- else if (arg == " --set-rpath" ) {
2625
- if (++i == argc) error (" missing argument" );
2626
- setRPath = true ;
2627
- newRPath = resolveArgument (argv[i]);
2628
- }
2629
- else if (arg == " --add-rpath" ) {
2630
- if (++i == argc) error (" missing argument" );
2631
- addRPath = true ;
2632
- newRPath = resolveArgument (argv[i]);
2633
- }
2634
- else if (arg == " --print-rpath" ) {
2635
- printRPath = true ;
2636
- }
2637
- else if (arg == " --force-rpath" ) {
2638
- /* Generally we prefer to emit DT_RUNPATH instead of
2639
- DT_RPATH, as the latter is obsolete. However, there is
2640
- a slight semantic difference: DT_RUNPATH is "scoped",
2641
- it only affects the executable or library in question,
2642
- not its recursive imports. So maybe you really want to
2643
- force the use of DT_RPATH. That's what this option
2644
- does. Without it, DT_RPATH (if encountered) is
2645
- converted to DT_RUNPATH, and if neither is present, a
2646
- DT_RUNPATH is added. With it, DT_RPATH isn't converted
2647
- to DT_RUNPATH, and if neither is present, a DT_RPATH is
2648
- added. */
2649
- forceRPath = true ;
2650
- }
2651
- else if (arg == " --print-needed" ) {
2652
- printNeeded = true ;
2653
- }
2654
- else if (arg == " --no-sort" ) {
2655
- noSort = true ;
2656
- }
2657
- else if (arg == " --add-needed" ) {
2658
- if (++i == argc) error (" missing argument" );
2659
- neededLibsToAdd.insert (resolveArgument (argv[i]));
2660
- }
2661
- else if (arg == " --remove-needed" ) {
2662
- if (++i == argc) error (" missing argument" );
2663
- neededLibsToRemove.insert (resolveArgument (argv[i]));
2664
- }
2665
- else if (arg == " --replace-needed" ) {
2666
- if (i+2 >= argc) error (" missing argument(s)" );
2667
- neededLibsToReplace[ argv[i+1 ] ] = argv[i+2 ];
2668
- i += 2 ;
2669
- }
2670
- else if (arg == " --clear-symbol-version" ) {
2671
- if (++i == argc) error (" missing argument" );
2672
- symbolsToClearVersion.insert (resolveArgument (argv[i]));
2673
- }
2674
- else if (arg == " --print-execstack" ) {
2675
- printExecstack = true ;
2676
- }
2677
- else if (arg == " --clear-execstack" ) {
2678
- clearExecstack = true ;
2679
- }
2680
- else if (arg == " --set-execstack" ) {
2681
- setExecstack = true ;
2682
- }
2683
- else if (arg == " --output" ) {
2684
- if (++i == argc) error (" missing argument" );
2685
- outputFileName = resolveArgument (argv[i]);
2686
- alwaysWrite = true ;
2687
- }
2688
- else if (arg == " --debug" ) {
2689
- debugMode = true ;
2690
- }
2691
- else if (arg == " --no-default-lib" ) {
2692
- noDefaultLib = true ;
2693
- }
2694
- else if (arg == " --add-debug-tag" ) {
2695
- addDebugTag = true ;
2696
- }
2697
- else if (arg == " --rename-dynamic-symbols" ) {
2698
- renameDynamicSymbols = true ;
2699
- if (++i == argc) error (" missing argument" );
2700
-
2701
- const char * fname = argv[i];
2702
- std::ifstream infile (fname);
2703
- if (!infile) error (fmt (" Cannot open map file " , fname));
2704
-
2705
- std::string line, from, to;
2706
- size_t lineCount = 1 ;
2707
- while (std::getline (infile, line))
2708
- {
2709
- std::istringstream iss (line);
2710
- if (!(iss >> from))
2711
- break ;
2712
- if (!(iss >> to))
2713
- error (fmt (fname, " :" , lineCount, " : Map file line is missing the second element" ));
2714
- if (symbolsToRenameKeys.count (from))
2715
- error (fmt (fname, " :" , lineCount, " : Name '" , from, " ' appears twice in the map file" ));
2716
- if (from.find (' @' ) != std::string_view::npos || to.find (' @' ) != std::string_view::npos)
2717
- error (fmt (fname, " :" , lineCount, " : Name pair contains version tag: " , from, " " , to));
2718
- lineCount++;
2719
- symbolsToRename[*symbolsToRenameKeys.insert (from).first ] = to;
2720
- }
2721
- }
2722
- else if (arg == " --no-clobber-old-sections" ) {
2723
- clobberOldSections = false ;
2724
- }
2725
- else if (arg == " --help" || arg == " -h" ) {
2726
- showHelp (argv[0 ]);
2727
- return 0 ;
2728
- }
2729
- else if (arg == " --version" ) {
2730
- printf (PACKAGE_STRING " \n " );
2731
- return 0 ;
2732
- }
2733
- else {
2734
- fileNames.push_back (arg);
2735
- }
2736
- }
2737
-
2738
- if (fileNames.empty ()) error (" missing filename" );
2739
-
2740
- if (!outputFileName.empty () && fileNames.size () != 1 )
2741
- error (" --output option only allowed with single input file" );
2742
-
2743
- if (setRPath && addRPath)
2744
- error (" --set-rpath option not allowed with --add-rpath" );
2745
-
2577
+ fileNames.push_back (filename);
2578
+ printRPath = true ;
2746
2579
patchElf ();
2580
+ return oldRPath;
2581
+ }
2747
2582
2748
- return 0 ;
2583
+ void patchelf::set_rpath (const std::string& filename, const std::string& rp)
2584
+ {
2585
+ fileNames.push_back (filename);
2586
+ setRPath = true ;
2587
+ newRPath = rp;
2588
+ patchElf ();
2749
2589
}
2750
2590
2751
- int main ( int argc, char * * argv )
2591
+ std::vector<std::string> patchelf::get_needed_libraries ( const std::string& filename )
2752
2592
{
2753
- #ifdef __OpenBSD__
2754
- if (pledge (" stdio rpath wpath cpath" , NULL ) == -1 )
2755
- error (" pledge" );
2756
- #endif
2593
+ fileNames.push_back (filename);
2594
+ printNeeded = true ;
2595
+ patchElf ();
2596
+ return neededLibraries;
2597
+ }
2757
2598
2758
- try {
2759
- return mainWrapped (argc, argv);
2760
- } catch (std::exception & e) {
2761
- fprintf (stderr, " patchelf: %s\n " , e.what ());
2762
- return 1 ;
2763
- }
2599
+ void patchelf::replace_needed_library (const std::string& filename, const std::string& oldLib, const std::string& newLib)
2600
+ {
2601
+ fileNames.push_back (filename);
2602
+ neededLibsToReplace[oldLib] = newLib;
2603
+ patchElf ();
2764
2604
}
0 commit comments