From 6fda2e68f2a8a5289e28f1ca893111b918556f32 Mon Sep 17 00:00:00 2001 From: Michael Trent Date: Thu, 24 Jan 2019 20:59:44 +0000 Subject: [PATCH] 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 --- lib/Object/MachOObjectFile.cpp | 21 +++++++++++++++--- .../Object/Inputs/darwin-m-test3.macho-x86-64 | Bin 9216 -> 9180 bytes test/Object/nm-darwin-m.test | 12 ++++++---- 3 files changed, 26 insertions(+), 7 deletions(-) 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 18960c4f6aab699718a7dbe54620eb7c41786efc..bf72b59a2358dae863dc6ee498593da30a6b5bf9 100755 GIT binary patch literal 9180 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 GKI}gtEJ_Uk 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) -- 2.50.1