Skip to content

change_rpath differs in behaviour from install_name_tool when handling duplicates #436

@carlocab

Description

@carlocab

Suppose I compile a dylib with a duplicate RPATH:

❯ clang -xc /dev/null -shared -rpath dupe -rpath dupe -o libdupes.dylib
❯ otool -l libdupes.dylib | rg -A2 LC_RPATH
          cmd LC_RPATH
      cmdsize 24
         path dupe (offset 12)
--
          cmd LC_RPATH
      cmdsize 24
         path dupe (offset 12)

(Admittedly, I don't know why one would do this, but pdnsrec still does.)

change_rpath handles changing one RPATH just fine, but chokes on the second:

❯ brew ruby -e 'MachO::Tools.change_rpath("libdupes.dylib", "dupe", "notdupe")'
❯ otool -l libdupes.dylib | rg -A2 LC_RPATH
          cmd LC_RPATH
      cmdsize 24
         path notdupe (offset 12)
--
          cmd LC_RPATH
      cmdsize 24
         path dupe (offset 12)
❯ brew ruby -e 'MachO::Tools.change_rpath("libdupes.dylib", "dupe", "notdupe")'
/usr/local/Homebrew/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/macho_file.rb:388:in `change_rpath': notdupe already exists (MachO::RpathExistsError)
        from /usr/local/Homebrew/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/tools.rb:60:in `change_rpath'
        from -e:1:in `<main>'

install_name_tool chugs along just fine, though:

❯ install_name_tool -rpath dupe notdupe libdupes.dylib
❯ otool -l libdupes.dylib | rg -A2 LC_RPATH
          cmd LC_RPATH
      cmdsize 24
         path notdupe (offset 12)
--
          cmd LC_RPATH
      cmdsize 24
         path notdupe (offset 12)

This is slightly related to changes we made in #362 and #366, and I think I realised this shortly after, but this slipped off my radar.

It might be that this is intentional and nothing needs changing here, but I just wanted to bring this up just in case you want ruby-macho to behave more look install_name_tool here.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions