Do not obliterate old rpath because it might be used due to read only data sharing. Closes #1619.

pull/1638/head
Jussi Pakkanen 8 years ago
parent 0e45134dee
commit 0e47e74a77
  1. 15
      mesonbuild/scripts/depfixer.py
  2. 22
      run_unittests.py
  3. 3
      test cases/unit/7 run installed/foo/foo.c
  4. 7
      test cases/unit/7 run installed/foo/meson.build
  5. 9
      test cases/unit/7 run installed/meson.build
  6. 5
      test cases/unit/7 run installed/prog.c

@ -297,11 +297,20 @@ class Elf(DataSizes):
old_rpath = self.read_str()
if len(old_rpath) < len(new_rpath):
sys.exit("New rpath must not be longer than the old one.")
self.bf.seek(rp_off)
self.bf.write(new_rpath)
self.bf.write(b'\0' * (len(old_rpath) - len(new_rpath) + 1))
# The linker does read-only string deduplication. If there is a
# string that shares a suffix with the rpath, they might get
# dedupped. This means changing the rpath string might break something
# completely unrelated. This has already happened once with X.org.
# Thus we want to keep this change as small as possible to minimize
# the chance of obliterating other strings. It might still happen
# but our behaviour is identical to what chrpath does and it has
# been in use for ages so based on that this should be rare.
if len(new_rpath) == 0:
self.remove_rpath_entry(entrynum)
else:
self.bf.seek(rp_off)
self.bf.write(new_rpath)
self.bf.write(b'\0')
def remove_rpath_entry(self, entrynum):
sec = self.find_section(b'.dynamic')

@ -1460,6 +1460,28 @@ class LinuxlikeTests(BasePlatformTests):
self.assertIn('-Werror', plain_comp)
self.assertNotIn('-Werror', c03_comp)
def test_run_installed(self):
testdir = os.path.join(self.unit_test_dir, '7 run installed')
self.init(testdir)
self.build()
self.install()
installed_exe = os.path.join(self.installdir, 'usr/bin/prog')
installed_libdir = os.path.join(self.installdir, 'usr/foo')
installed_lib = os.path.join(installed_libdir, 'libfoo.so')
self.assertTrue(os.path.isfile(installed_exe))
self.assertTrue(os.path.isdir(installed_libdir))
self.assertTrue(os.path.isfile(installed_lib))
# Must fail when run without LD_LIBRARY_PATH to ensure that
# rpath has been properly stripped rather than pointing to the builddir.
self.assertNotEqual(subprocess.call(installed_exe, stderr=subprocess.DEVNULL), 0)
# When LD_LIBRARY_PATH is set it should start working.
# For some reason setting LD_LIBRARY_PATH in os.environ fails
# when all tests are run (but works when only this test is run),
# but doing this explicitly works.
env = os.environ.copy()
env['LD_LIBRARY_PATH'] = installed_libdir
self.assertEqual(subprocess.call(installed_exe, env=env), 0)
class RewriterTests(unittest.TestCase):
def setUp(self):

@ -0,0 +1,3 @@
int foo() {
return 0;
}

@ -0,0 +1,7 @@
# Try to invoke linker constant string deduplication,
# to ensure we are not clobbering shared strings.
# Name everything possible just as "foo".
foolib = shared_library('foo', 'foo.c',
install_dir : 'foo',
install : true)

@ -0,0 +1,9 @@
project('foo', 'c',
default_options : 'libdir=lib')
subdir('foo')
executable('prog', 'prog.c',
link_with : foolib,
install : true)

@ -0,0 +1,5 @@
int foo();
int main(int argc, char **argv) {
return foo();
}
Loading…
Cancel
Save