Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring keg_relocate to use ELFShim#interpreter #7797

Merged
merged 1 commit into from Jun 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 9 additions & 8 deletions Library/Homebrew/extend/os/linux/keg_relocate.rb
Expand Up @@ -27,6 +27,7 @@ def change_rpath(file, old_prefix, new_prefix)
# patchelf requires that the ELF file have a .dynstr section.
# Skip ELF files that do not have a .dynstr section.
return if ["cannot find section .dynstr", "strange: no string table"].include?(old_rpath)

unless $CHILD_STATUS.success?
raise ErrorDuringExecution.new(cmd_rpath, status: $CHILD_STATUS, output: [[:stderr, old_rpath]])
end
Expand All @@ -41,15 +42,15 @@ def change_rpath(file, old_prefix, new_prefix)
new_rpath = rpath.join(":")
cmd = [patchelf, "--force-rpath", "--set-rpath", new_rpath]

if file.with_interpreter?
old_interpreter = Utils.safe_popen_read(patchelf, "--print-interpreter", file).strip
new_interpreter = if File.readable? "#{new_prefix}/lib/ld.so"
"#{new_prefix}/lib/ld.so"
else
old_interpreter.sub old_prefix, new_prefix
end
cmd << "--set-interpreter" << new_interpreter if old_interpreter != new_interpreter
old_interpreter = file.interpreter
new_interpreter = if old_interpreter.nil?
nil
elsif File.readable? "#{new_prefix}/lib/ld.so"
"#{new_prefix}/lib/ld.so"
else
old_interpreter.sub old_prefix, new_prefix
end
cmd << "--set-interpreter" << new_interpreter if old_interpreter != new_interpreter
rmNULL marked this conversation as resolved.
Show resolved Hide resolved

return if old_rpath == new_rpath && old_interpreter == new_interpreter

Expand Down
34 changes: 15 additions & 19 deletions Library/Homebrew/os/linux/elf.rb
Expand Up @@ -68,28 +68,24 @@ def binary_executable?
elf_type == :executable
end

def with_interpreter?
return @with_interpreter if defined? @with_interpreter
def interpreter
return @interpreter if defined? @interpreter

@with_interpreter = if binary_executable?
true
elsif dylib?
if HOMEBREW_PATCHELF_RB
begin
patchelf_patcher.interpreter.present?
rescue PatchELF::PatchError => e
opoo e unless e.to_s.start_with? "No interpreter found"
false
end
elsif which "readelf"
Utils.popen_read("readelf", "-l", to_path).include?(" INTERP ")
elsif which "file"
Utils.popen_read("file", "-L", "-b", to_path).include?(" interpreter ")
else
raise "Please install either readelf (from binutils) or file."
@interpreter = if HOMEBREW_PATCHELF_RB
begin
patchelf_patcher.interpreter
rescue PatchELF::PatchError => e
opoo e unless e.to_s.start_with? "No interpreter found"
nil
end
elsif (patchelf = DevelopmentTools.locate "patchelf")
interp = Utils.popen_read(patchelf, "--print-interpreter", to_s, err: :out).strip
$CHILD_STATUS.success? ? interp : nil
elsif (file = DevelopmentTools.locate("file"))
output = Utils.popen_read(file, "-L", "-b", to_s, err: :out).strip
output[/^ELF.*, interpreter (.+?), /, 1]
else
false
raise "Please install either patchelf or file."
end
end

Expand Down