From: Michael Trent Date: Thu, 24 Jan 2019 20:59:44 +0000 (+0000) Subject: Limit dyld image suffixes guessed by guessLibraryShortName() X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6fda2e68f2a8a5289e28f1ca893111b918556f32;p=llvm Limit dyld image suffixes guessed by guessLibraryShortName() Summary: guessLibraryShortName() separates a full Mach-O dylib install name path into a short name and a dyld image suffix. The short name is the name of the dylib without its path or extension. The dyld image suffix is a string used by dyld to load variants of dylibs if available at runtime; for example, "when binding this process, load 'debug' variants of all required dylibs." dyld knows exactly what the image suffix is, but by convention diagnostic tools such as llvm-nm attempt to guess suffix names by looking at the install name path. These dyld image suffixes are separated from the short name by a '_' character. Because the '_' character is commonly used to separate words in filenames guessLibraryShortName() cannot reliably separate a dylib's short name from an arbitrary image suffix; imagine if both the short name and the suffix contains an '_' character! To better deal with this ambiguity, guessLibraryShortName() will recognize only "_debug" and "_profile" as valid Suffix values. Calling code needs to be tolerant of guessLibraryShortName() guessing incorrectly. The previous implementation of guessLibraryShortName() did not allow '_' characters to appear in short names. When present, the short name would be truncated, e.g., "libcompiler_rt" => "libcompiler". This change allows "libcompiler_rt" and "libcompiler_rt_debug" to both be recognized as "libcompiler_rt". rdar://47412244 Reviewers: kledzik, lhames, pete Reviewed By: pete Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D56978 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352104 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index a1cbef2c281..69e69bdcf93 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -2241,9 +2241,18 @@ uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const { // one of the two following forms: // libFoo.A.dylib // libFoo.dylib +// // The library may have a suffix trailing the name Foo of the form: // libFoo_profile.A.dylib // libFoo_profile.dylib +// These dyld image suffixes are separated from the short name by a '_' +// character. Because the '_' character is commonly used to separate words in +// filenames guessLibraryShortName() cannot reliably separate a dylib's short +// name from an arbitrary image suffix; imagine if both the short name and the +// suffix contains an '_' character! To better deal with this ambiguity, +// guessLibraryShortName() will recognize only "_debug" and "_profile" as valid +// Suffix values. Calling code needs to be tolerant of guessLibraryShortName() +// guessing incorrectly. // // The Name of the dynamic library is also recognized as a library name if it // has the following form: @@ -2251,7 +2260,6 @@ uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const { // // If the Name of the dynamic library is none of the forms above then a NULL // StringRef is returned. -// StringRef MachOObjectFile::guessLibraryShortName(StringRef Name, bool &isFramework, StringRef &Suffix) { @@ -2271,7 +2279,10 @@ StringRef MachOObjectFile::guessLibraryShortName(StringRef Name, Idx = Foo.rfind('_'); if (Idx != Foo.npos && Foo.size() >= 2) { Suffix = Foo.slice(Idx, Foo.npos); - Foo = Foo.slice(0, Idx); + if (Suffix != "_debug" && Suffix != "_profile") + Suffix = StringRef(); + else + Foo = Foo.slice(0, Idx); } // First look for the form Foo.framework/Foo @@ -2332,10 +2343,14 @@ guess_library: else b = b+1; // ignore any suffix after an underbar like Foo_profile.A.dylib - Idx = Name.find('_', b); + Idx = Name.rfind('_'); if (Idx != Name.npos && Idx != b) { Lib = Name.slice(b, Idx); Suffix = Name.slice(Idx, a); + if (Suffix != "_debug" && Suffix != "_profile") { + Suffix = StringRef(); + Lib = Name.slice(b, a); + } } else Lib = Name.slice(b, a); diff --git a/test/Object/Inputs/darwin-m-test3.macho-x86-64 b/test/Object/Inputs/darwin-m-test3.macho-x86-64 index 18960c4f6aa..bf72b59a235 100755 Binary files a/test/Object/Inputs/darwin-m-test3.macho-x86-64 and b/test/Object/Inputs/darwin-m-test3.macho-x86-64 differ diff --git a/test/Object/nm-darwin-m.test b/test/Object/nm-darwin-m.test index 5bb19dcacd3..a8d70070061 100644 --- a/test/Object/nm-darwin-m.test +++ b/test/Object/nm-darwin-m.test @@ -19,8 +19,8 @@ test2: (indirect) external _i (for __i) # This is testing is using darwin-m-test3.macho-x86-64 that is linked with # dylibs that have the follow set of -install_names: -# Foo.framework/Foo -# /System/Library/Frameworks/FooPath.framework/FooPath +# Foo.framework/Foo +# /System/Library/Frameworks/FooPath.framework/FooPath # FooSuffix.framework/FooSuffix_debug # /System/Library/Frameworks/FooPathSuffix.framework/FooPathSuffix_profile # FooVers.framework/Versions/A/FooVers @@ -32,8 +32,10 @@ test2: (indirect) external _i (for __i) # /usr/lib/libPathATS.A_profile.dylib # QT.A.qtx # /lib/QTPath.qtx +# /usr/lib/libfoo_bar.dylib +# /usr/lib/libfoo_bar_profile.dylib # /usr/lib/libSystem.B.dylib -# to test that MachOObjectFile::guessLibraryShortName() is correctly parsing +# to test that MachOObjectFile::guessLibraryShortName() is correctly parsing # them into their short names. test3: 0000000100000000 (__TEXT,__text) [referenced dynamically] external __mh_execute_header test3: (undefined) external _atsPathVersSuffix (from libPathATS) @@ -44,7 +46,9 @@ test3: (undefined) external _fooPathSuffix (from FooPathSuffix) test3: (undefined) external _fooPathVers (from FooPathVers) test3: (undefined) external _fooSuffix (from FooSuffix) test3: (undefined) external _fooVers (from FooVers) -test3: 0000000100000e60 (__TEXT,__text) external _main +test3: (undefined) external _foo_bar (from libfoo_bar) +test3: (undefined) external _foo_barSuffix (from libfoo_barSuffix) +test3: 0000000100000e50 (__TEXT,__text) external _main test3: (undefined) external _qt (from QT) test3: (undefined) external _qtPath (from QTPath) test3: (undefined) external _x (from libx)