From ed0a9e113bcf6a1fe0c4333602e765a02037c52c Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Thu, 20 Jul 2017 23:08:41 +0000 Subject: [PATCH] Add error handling to the dyld compact export entries in libObject. lld needs a matching change for this will be my next commit. Expect it to fail build until that matching commit is picked up by the bots. Like the changes in r296527 for dyld bind entires and the changes in r298883 for lazy bind, weak bind and rebase entries the export entries are the last of the dyld compact info to have error handling added. This follows the model of iterators that can fail that Lang Hanes designed when fixing the problem for bad archives r275316 (or r275361). So that iterating through the exports now terminates if there is an error and returns an llvm::Error with an error message in all cases for malformed input. This change provides the plumbing for the error handling, all the needed testing of error conditions and test cases for all of the unique error messages. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308690 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/MachO.h | 27 ++- lib/Object/MachOObjectFile.cpp | 176 +++++++++++++++--- .../Inputs/macho-inconsistant-export | Bin 0 -> 8752 bytes ...cho-trie-bad-export-info-malformed-uleb128 | Bin 0 -> 8760 bytes ...-bad-export-info-malformed-uleb128_too_big | Bin 0 -> 8768 bytes .../llvm-objdump/Inputs/macho-trie-bad-kind | Bin 0 -> 8752 bytes .../Inputs/macho-trie-bad-library-ordinal | Bin 0 -> 8752 bytes .../Inputs/macho-trie-children-count-byte | Bin 0 -> 8752 bytes .../Inputs/macho-trie-edge-string-end | Bin 0 -> 8912 bytes .../macho-trie-export-info-size-too-big | Bin 0 -> 8752 bytes .../Inputs/macho-trie-import-name-end | Bin 0 -> 8752 bytes .../Inputs/macho-trie-import-name-start | Bin 0 -> 8752 bytes .../llvm-objdump/Inputs/macho-trie-node-loop | Bin 0 -> 8752 bytes .../Inputs/macho-trie-not-export-node | Bin 0 -> 8756 bytes test/tools/llvm-objdump/macho-bad-trie.test | 35 ++++ tools/llvm-nm/llvm-nm.cpp | 6 +- tools/llvm-objdump/MachODump.cpp | 5 +- 17 files changed, 218 insertions(+), 31 deletions(-) create mode 100755 test/tools/llvm-objdump/Inputs/macho-inconsistant-export create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-bad-export-info-malformed-uleb128 create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-bad-export-info-malformed-uleb128_too_big create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-bad-kind create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-bad-library-ordinal create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-children-count-byte create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-edge-string-end create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-export-info-size-too-big create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-import-name-end create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-import-name-start create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-node-loop create mode 100755 test/tools/llvm-objdump/Inputs/macho-trie-not-export-node create mode 100644 test/tools/llvm-objdump/macho-bad-trie.test diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 2c3c89d1054..f2b273c82a9 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -66,11 +66,13 @@ using dice_iterator = content_iterator; /// ExportEntry encapsulates the current-state-of-the-walk used when doing a /// non-recursive walk of the trie data structure. This allows you to iterate /// across all exported symbols using: -/// for (const llvm::object::ExportEntry &AnExport : Obj->exports()) { +/// Error Err; +/// for (const llvm::object::ExportEntry &AnExport : Obj->exports(&Err)) { /// } +/// if (Err) { report error ... class ExportEntry { public: - ExportEntry(ArrayRef Trie); + ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef Trie); StringRef name() const; uint64_t flags() const; @@ -88,7 +90,7 @@ private: void moveToFirst(); void moveToEnd(); - uint64_t readULEB128(const uint8_t *&p); + uint64_t readULEB128(const uint8_t *&p, const char **error); void pushDownUntilBottom(); void pushNode(uint64_t Offset); @@ -107,12 +109,19 @@ private: unsigned ParentStringLength = 0; bool IsExportNode = false; }; + using NodeList = SmallVector; + using node_iterator = NodeList::const_iterator; + Error *E; + const MachOObjectFile *O; ArrayRef Trie; SmallString<256> CumulativeString; - SmallVector Stack; - bool Malformed = false; + NodeList Stack; bool Done = false; + + iterator_range nodes() const { + return make_range(Stack.begin(), Stack.end()); + } }; using export_iterator = content_iterator; @@ -356,10 +365,14 @@ public: iterator_range load_commands() const; /// For use iterating over all exported symbols. - iterator_range exports() const; + iterator_range exports(Error &Err, + const MachOObjectFile *O) const; /// For use examining a trie not in a MachOObjectFile. - static iterator_range exports(ArrayRef Trie); + static iterator_range exports(Error &Err, + ArrayRef Trie, + const MachOObjectFile *O = + nullptr); /// For use iterating over all rebase table entries. iterator_range rebaseTable(Error &Err); diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 2e4da9f15aa..8b85049ea63 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -2607,10 +2607,14 @@ dice_iterator MachOObjectFile::end_dices() const { return dice_iterator(DiceRef(DRI, this)); } -ExportEntry::ExportEntry(ArrayRef T) : Trie(T) {} +ExportEntry::ExportEntry(Error *E, const MachOObjectFile *O, + ArrayRef T) : E(E), O(O), Trie(T) {} void ExportEntry::moveToFirst() { + ErrorAsOutParameter ErrAsOutParam(E); pushNode(0); + if (*E) + return; pushDownUntilBottom(); } @@ -2637,14 +2641,12 @@ bool ExportEntry::operator==(const ExportEntry &Other) const { return true; } -uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr) { +uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr, const char **error) { unsigned Count; - uint64_t Result = decodeULEB128(Ptr, &Count); + uint64_t Result = decodeULEB128(Ptr, &Count, Trie.end(), error); Ptr += Count; - if (Ptr > Trie.end()) { + if (Ptr > Trie.end()) Ptr = Trie.end(); - Malformed = true; - } return Result; } @@ -2679,22 +2681,119 @@ ExportEntry::NodeState::NodeState(const uint8_t *Ptr) : Start(Ptr), Current(Ptr) {} void ExportEntry::pushNode(uint64_t offset) { + ErrorAsOutParameter ErrAsOutParam(E); const uint8_t *Ptr = Trie.begin() + offset; NodeState State(Ptr); - uint64_t ExportInfoSize = readULEB128(State.Current); + const char *error; + uint64_t ExportInfoSize = readULEB128(State.Current, &error); + if (error) { + *E = malformedError("export info size " + Twine(error) + " in export trie " + "data at node: 0x" + utohexstr(offset)); + moveToEnd(); + return; + } State.IsExportNode = (ExportInfoSize != 0); const uint8_t* Children = State.Current + ExportInfoSize; + if (Children > Trie.end()) { + *E = malformedError("export info size: 0x" + utohexstr(ExportInfoSize) + + " in export trie data at node: 0x" + utohexstr(offset) + + " too big and extends past end of trie data"); + moveToEnd(); + return; + } if (State.IsExportNode) { - State.Flags = readULEB128(State.Current); + const uint8_t *ExportStart = State.Current; + State.Flags = readULEB128(State.Current, &error); + if (error) { + *E = malformedError("flags " + Twine(error) + " in export trie data at " + "node: 0x" + utohexstr(offset)); + moveToEnd(); + return; + } + uint64_t Kind = State.Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK; + if (State.Flags != 0 && + (Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR && + Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE && + Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL)) { + *E = malformedError("unsupported exported symbol kind: " + + Twine((int)Kind) + " in flags: 0x" + utohexstr(State.Flags) + + " in export trie data at node: 0x" + utohexstr(offset)); + moveToEnd(); + return; + } if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) { State.Address = 0; - State.Other = readULEB128(State.Current); // dylib ordinal + State.Other = readULEB128(State.Current, &error); // dylib ordinal + if (error) { + *E = malformedError("dylib ordinal of re-export " + Twine(error) + + " in export trie data at node: 0x" + utohexstr(offset)); + moveToEnd(); + return; + } + if (O != nullptr) { + if (State.Other > O->getLibraryCount()) { + *E = malformedError("bad library ordinal: " + Twine((int)State.Other) + + " (max " + Twine((int)O->getLibraryCount()) + ") in export " + "trie data at node: 0x" + utohexstr(offset)); + moveToEnd(); + return; + } + } State.ImportName = reinterpret_cast(State.Current); + if (*State.ImportName == '\0') { + State.Current++; + } else { + const uint8_t *End = State.Current + 1; + if (End >= Trie.end()) { + *E = malformedError("import name of re-export in export trie data at " + "node: 0x" + utohexstr(offset) + " starts past end of trie " + "data"); + moveToEnd(); + return; + } + while(*End != '\0' && End < Trie.end()) + End++; + if (*End != '\0') { + *E = malformedError("import name of re-export in export trie data at " + "node: 0x" + utohexstr(offset) + " extends past end of trie " + "data"); + moveToEnd(); + return; + } + State.Current = End + 1; + } } else { - State.Address = readULEB128(State.Current); - if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) - State.Other = readULEB128(State.Current); + State.Address = readULEB128(State.Current, &error); + if (error) { + *E = malformedError("address " + Twine(error) + " in export trie data " + "at node: 0x" + utohexstr(offset)); + moveToEnd(); + return; + } + if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) { + State.Other = readULEB128(State.Current, &error); + if (error) { + *E = malformedError("resolver of stub and resolver " + Twine(error) + + " in export trie data at node: 0x" + utohexstr(offset)); + moveToEnd(); + return; + } + } } + if(ExportStart + ExportInfoSize != State.Current) { + *E = malformedError("inconsistant export info size: 0x" + + utohexstr(ExportInfoSize) + " where actual size was: 0x" + + utohexstr(State.Current - ExportStart) + " in export trie data " + "at node: 0x" + utohexstr(offset)); + moveToEnd(); + return; + } + } + if (Children + 1 >= Trie.end()) { + *E = malformedError("byte for count of childern in export trie data at " + "node: 0x" + utohexstr(offset) + " extends past end of trie data"); + moveToEnd(); + return; } State.ChildCount = *Children; State.Current = Children + 1; @@ -2704,21 +2803,50 @@ void ExportEntry::pushNode(uint64_t offset) { } void ExportEntry::pushDownUntilBottom() { + ErrorAsOutParameter ErrAsOutParam(E); + const char *error; while (Stack.back().NextChildIndex < Stack.back().ChildCount) { NodeState &Top = Stack.back(); CumulativeString.resize(Top.ParentStringLength); - for (;*Top.Current != 0; Top.Current++) { + for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) { char C = *Top.Current; CumulativeString.push_back(C); } + if (Top.Current >= Trie.end()) { + *E = malformedError("edge sub-string in export trie data at node: 0x" + + utohexstr(Top.Start - Trie.begin()) + " for child #" + + Twine((int)Top.NextChildIndex) + " extends past end of trie data"); + moveToEnd(); + return; + } Top.Current += 1; - uint64_t childNodeIndex = readULEB128(Top.Current); + uint64_t childNodeIndex = readULEB128(Top.Current, &error); + if (error) { + *E = malformedError("child node offset " + Twine(error) + + " in export trie data at node: 0x" + + utohexstr(Top.Start - Trie.begin())); + moveToEnd(); + return; + } + for (const NodeState &node : nodes()) { + if (node.Start == Trie.begin() + childNodeIndex){ + *E = malformedError("loop in childern in export trie data at node: 0x" + + utohexstr(Top.Start - Trie.begin()) + " back to node: 0x" + + utohexstr(childNodeIndex)); + moveToEnd(); + return; + } + } Top.NextChildIndex += 1; pushNode(childNodeIndex); + if (*E) + return; } if (!Stack.back().IsExportNode) { - Malformed = true; + *E = malformedError("node is not an export node in export trie data at " + "node: 0x" + utohexstr(Stack.back().Start - Trie.begin())); moveToEnd(); + return; } } @@ -2738,8 +2866,10 @@ void ExportEntry::pushDownUntilBottom() { // stack ivar. If there is no more ways down, it pops up one and tries to go // down a sibling path until a childless node is reached. void ExportEntry::moveNext() { - if (Stack.empty() || !Stack.back().IsExportNode) { - Malformed = true; + assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack"); + if (!Stack.back().IsExportNode) { + *E = malformedError("node is not an export node in export trie data at " + "node: 0x" + utohexstr(Stack.back().Start - Trie.begin())); moveToEnd(); return; } @@ -2764,21 +2894,23 @@ void ExportEntry::moveNext() { } iterator_range -MachOObjectFile::exports(ArrayRef Trie) { - ExportEntry Start(Trie); +MachOObjectFile::exports(Error &E, ArrayRef Trie, + const MachOObjectFile *O) { + ExportEntry Start(&E, O, Trie); if (Trie.empty()) Start.moveToEnd(); else Start.moveToFirst(); - ExportEntry Finish(Trie); + ExportEntry Finish(&E, O, Trie); Finish.moveToEnd(); return make_range(export_iterator(Start), export_iterator(Finish)); } -iterator_range MachOObjectFile::exports() const { - return exports(getDyldInfoExportsTrie()); +iterator_range MachOObjectFile::exports(Error &Err, + const MachOObjectFile *O) const { + return exports(Err, getDyldInfoExportsTrie(), O); } MachORebaseEntry::MachORebaseEntry(Error *E, const MachOObjectFile *O, diff --git a/test/tools/llvm-objdump/Inputs/macho-inconsistant-export b/test/tools/llvm-objdump/Inputs/macho-inconsistant-export new file mode 100755 index 0000000000000000000000000000000000000000..da137800a8d6a025086f900b0473282703f13eca GIT binary patch literal 8752 zcmeHN&1)M+6n`7pjpDe`h7_89SlKjon=h0&F~#7fSRnzKh9Z9?wGHlg70Fnz(mK-m zs}K;Rg_>YcZ#|X%0X^jCTTRoHkV{X69D6Awkd|BuA&08JH#;M*HgTc!RG0@(Z{EzC z-^~2pF6{2p&(DAVYcG+NAfi{GDQLc%=!?czXc4^ueP|I0F?D%*N_KVr*qtsZAD9Ff zsT?6hP+AMP6-pd$`#{(~r^eauQf+Cvs1bFAs0Yi1db=x*m*#^&dP76(;}~s8Dm*?j zONb{HOWsncCjHLyo>q7t%4j0?_o%isFYIr*x>~LlMY+1*zXZ=ycsYf^eg|F@Th1>n ziiMh6DTM>^^KQlP*yo(?CY;wVWnM33r?QbKozGn?=aq4FZiJ|MqP|`!_?}n_YT)tZ zcp8qckLbRb|LD1e@Z5jGvlWoWV?T<=`_p?vldrqQTFEVn6}QG$OMHKh0y@mW5bcK^ z(IMSXwvAVG0~dX9ykUi>_rQMidF4?!X#mbVMk$ksl2lDu=DVFImW#25b+v! zjsgI7KQs?z;TTrVC1dh^zngrG`TCxV#=HfG*LiSl>-n+t$ot>@Idtyid&fum(I+X` z--AVa=%n^xS@{0e=jJ_V!Ep<2ZRgw^$LHoXWSq5zmPKcl>$NioX1#vuRAx|3;rQW5 zyw&pnDea7(T(1YEO6KCuDn##M4)1r{3As3-eCE%HVZbn87%&VN1`Gp+0mHz5XW(jX z-F0-cXvTbCUxX<3C`nN{J=MNx5*;oZ#}Vd8#kZjZr^GnA7zPXjh5^HXVZbn87%&VN1`GrL z69x_*wI_J1helD^^j1W{_k(&+bC+oRhSMBH-LNPt?V^BUHY($dhxn8s#cJ|AOq;E) zR=6qU#$g~;T+j2blMJu~>Ve&;K@QQ0Ff`+OWw$O+o;y$H@jFNt0=k%>?LJC$J?*1p z(h3JDk>qb3dscl>E7g5(1?x}J>^}RObTdr}>strkP5K-gM%MJwi2hamkAUl=2lkyVI9?K>obRUbe7$X0*3S`JV;mKhKcT0{Q$caVhS XULXz=cZiIqTLsIk=mfryeWJes;S@V2 literal 0 HcmV?d00001 diff --git a/test/tools/llvm-objdump/Inputs/macho-trie-bad-export-info-malformed-uleb128 b/test/tools/llvm-objdump/Inputs/macho-trie-bad-export-info-malformed-uleb128 new file mode 100755 index 0000000000000000000000000000000000000000..57ae7bd6c07420ba7986702efaa2cf8bdd5a9159 GIT binary patch literal 8760 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 Xdx1Di+~F~vZWS!Eq7(RB_KE%mAtgKV literal 0 HcmV?d00001 diff --git a/test/tools/llvm-objdump/Inputs/macho-trie-import-name-end b/test/tools/llvm-objdump/Inputs/macho-trie-import-name-end new file mode 100755 index 0000000000000000000000000000000000000000..f1d8f67ade0d61b601fadd2ec36ea790a389a1b1 GIT binary patch literal 8752 zcmeHN&1)M+6n`7pjq14Zh7_89SW#NL%@#6h)=pjenYMQ2$TzV?x*h?XSq~uZvIaK}qW@qh{5*JEOg?aGw=FPnM z&CKuZ!tOr(^6c?ndqtdth`a>tf{wO}d{O%fEs@uu_Z<aOM=x7iir15*H_ zl@Uq>h1GzqP+IY}_J{qmW}JSTX=~FawYaNPHCW13x4T;LQalKxGc-aU$Jmyn!Q+`J zA)cBq_=|;#_M6Xp(%^llqebZNF>P(0+uu@YrC7?VVrj1Y0zBW~Weo=XCcHSdo?n<( za}{r)5Dv7Sce4eLK6AR8Ft1!1;BRP=n#V;kso>@ z2cw3u+jw~|@X*(aH)!ypJU@qfiQCsLUlXdEf6QUt@lB&&6Zjgu`|2UDt7tiLYN=W|g<$Hn6DRum%@oED#^Rlh zdq`<>{KQ%{C@l1y-&sZEUCiNrx6&aO$Ba+@tXKvt1C{~HfMvikU>UFs{C5T}XV-tv zZk)U9h%{ciC9`+twDffy{#=7|e3K7+vv=wg9e?wYn_a*0G<)mD(+7t!mc99-8z0|j zzuRau(9`IBgyBZ-9~$e@M)$91WF{KDcVX+JpIjLq%Zz5m9{hyx?0Wn69G%WgP0xI) zrW(Ds;m$+l;SU%OpUdB(4~biDkMFw!u+-??m2JM;bmFq@)Ip_q-zc7PP;I=rk6tWZ{~jltdH)088ti> z;~=c#b~!b9V#eQq&l)D{b(E7(`m~fY&@SLb|4U#kunWb_w80xPNp+KORp8<39J#{jd%R8IJt4s9>dxpB`kZr&uZmC>`qzs2HswfBfwirMXv# V!^9mTThncVbylJTK9_xwzX2goI`#kn literal 0 HcmV?d00001 diff --git a/test/tools/llvm-objdump/Inputs/macho-trie-import-name-start b/test/tools/llvm-objdump/Inputs/macho-trie-import-name-start new file mode 100755 index 0000000000000000000000000000000000000000..4f7e93c4fc05497f418d0a5d71eca0880d12e5b5 GIT binary patch literal 8752 zcmeHN&1)M+6n|@3jq143h7_89SWz0g%@<0Xm|$>ItdM|ALyuLQOEJx1LJ>fF5%6t)^*8$fc)3j=2O9NJ}n-kVDnqo1KwYo462iD$IkYH*e<6 zZ)SdP7k2mQ_ve59vx~@z5z!maBs3o<`lj(6T14+c?^{GdOkJ3sl3krYcBf0q2POeV zDn|(6msWjl1ro*E+7tB8sd4tZRa=^FYJ^=O>i$xp-tLOxrT8F_-oOz1I7V9%3Xjjs z65xr2lDk-{Nx$>F#}(eEGMb3}F4dOih5ap6SIX6*C|Bpbm*BYyFQ+ir@4yRV%lV}R zF<)~krC=a>-pvRe`<&CAg!B5X%+56?9}*biS940fcA4RMEik9 zv`;sbZQ~Uk-$7p#Z&=~!J+L1>-`)rw=Yg*QAuf)6{@I1|WBMLTt3ZWE%0H>V_?$>z zTi!zJFqF>`?sv)z+hUTFx9K*`FWK6#AcarZhU*B`#nD^oEI`=MbK0lNiIrG!sL#K{@e0ZcEeUgIR zJy^7dj%pv4h3{{DZr+0y9Jk=qw$IIRd~RMt##yUqS#)BlUORzc)~m;kWd_w0jvo%i zTRr!X($4tFwYp!bWX^4`Li7>l@P4<_0T)M<&-@uN3>XFs1BL;^fMLKeU>JCP1}^2+ zALcgBUb2W<@7$!h+w)Q~$pc?Ya30^}2fn%6O%@q{Yoqt${nR&HNXaC&sh+?D(VK5T09)|IDK^+3A_t zFU53g;1=8kC_VlK!+>GHFkl!k3>XFs1BL;^fMLKeU>GnA7zX|) z4D3Bcit$3nVs(bD-)}N%=xcx(_nWC8WV;bL0`qDOxtm&l?{XqSXfa{}s-b4+L zi*XRH<0h>JJyqlH!RHz#*Xvl0L)mA`atfLRp8j6~*8-C$Zl)F9h#I%mcakyq2yd67 zX96ExfryCDW&ChFGZ^-H|GXcrLqbNipC;k2c=+i@w))G}vX9cS%zy~d8t})zgCr#P W0&$qQO=L9PDp+PkC-8;r6a5R}-#YRD literal 0 HcmV?d00001 diff --git a/test/tools/llvm-objdump/Inputs/macho-trie-node-loop b/test/tools/llvm-objdump/Inputs/macho-trie-node-loop new file mode 100755 index 0000000000000000000000000000000000000000..b94dfa2610e9f0fae275dc1cef46563d1b695cf6 GIT binary patch literal 8752 zcmeHN&1)M+6n`68jq143h7_89SlP68n=h0&F~#7fSRnzKh9Z9?wFB;W70Fnz(mK-m zs}K;Rg_>YcZ#|X%0X^jCTTRoHl1op89D6Awkd#~sA&08JH#;M*HgTc!RG0@(Z{EzC z-^~2pF6{2pFV7zTwU@|B5YbD}G_;T;`l9(2T12ly?^{GdOkbRtmR;RHcDGB)2POeV zDn|$rl-B}og%Zcx-XHeQsd4suR9l)JYDQfl8o_e0(dmlgW%wYFzR(c+I7UZO3Xjjs z65@%)vbR*OOTYWPCl%g@GMb3}J*q9ubNgGatyXF!QK>EXFTnE@US46a--Q>&mh;Pt zVxjI<%i%!$yjw9m_Bp4!3Fq}onb!-s>0BgA=W`d!d1YLk8zE|*XslO@z9*J~I(U3B zo`&P=Bf2lq&=Yg*QAuf%7{L#e=u7NB+eFRN+;E6eFe%s(*fCgMs-WyV>^yv4jxm3Bh(d-%Y;8e0|SFW8Q?r>)gAt_3WL@==A3b`S@{0e=jJ_V!EuXjedpX9$LHoXWSq5zmPMzQ8}(BNX1#XeM0Q9`;rNkA zyw!UTDeaD*T5km9YWDojDn##M4)1r{3As3?eCE%HVZbn87%&VN1`Gp+0mHz5XW(*v zDv^y>m6P~vlB_k` zvitU?S{V7a{Tfu;57c|)yt2AKZt*Z|#4unOFbo(53GHFkl!k3>XFs1BQYB z2?Ga?*ps}~gJY;{dMl#n`#~e9yGt~2-D!=XZdj6)c2Ptz8VZkrAcyH#7@BpxirWw<&z+^S_#L8i0i93Kc0VP0p7c{H zWrc&3Nb$FhJ*&Q`mm9vfg7v2;nY6#jv@(>izIE{3q~Eb&WKA!F=-<@;2)I7F|7Fzh zxEKfFI&Ru((i1iQ27Inza=nh_B$R!&EN7r;;OYM*a4j&6;-;hUM%B2jzLSi@M|h_c zJsbMy3Pr?xF5^eznZc;f`{(^|9TGC8eTPJ_>f>hs*&3+SDgjEzG6Nz)Yseq}4v~=D W3&dgK4w3P6t6-TGoxta^PxLojN;=H| literal 0 HcmV?d00001 diff --git a/test/tools/llvm-objdump/Inputs/macho-trie-not-export-node b/test/tools/llvm-objdump/Inputs/macho-trie-not-export-node new file mode 100755 index 0000000000000000000000000000000000000000..38882762cf0fb94f985ca33ec3e7a9931b46378c GIT binary patch literal 8756 zcmeHNO=}xR7=Aal8`W{+4JkDJu%k3~n=h0)F~#7fSRnzKh9Z9?wGHlM70FnzmKsZ_ zJTvpmF6`>n&(D7UYp;mYCL%APbfaWDM7~)63N?|}Q64xVN=;szn$%6r7q=OT!Qd3o z=)wr4g2HORT4=3&+xx@zS<_G4ZtB{#%X%CtRSlMM)kae*UoSTT>k6F^V;c=i7(VWq z7V@e2g1=a(XxzNtQ-<$D9W6q<$JDiZZhcFom0~Hcilw>o3;2A)moXf~O?+`~J-#rn z<|^JoA?#?~?^X*RG0${2rAMtfj|M*{kqwX4z(ZRr-;m*p)<7KJ-+>lBo&)azr7n$r{L#e=qtP>#G=YXs3?4LO+$WB& zVXvTe42AoMxBJE1T)CXeuc5-=w?)?9VXms;u!>;q$6|f3e1*`&Af&Z?+<;=!! znay*T9g+HLw`BJAoVHZ=;mesX1eES*h{J^TsbnT?Jg*gKt`nx6So zP1XCq1Dr>ZM?a!Jd@p~C7#86|f3e1*`&Af&YmD z2adSoT4#{j}#@8R}i)-vs6ZyOH2b8opuE@0#CAMu8FDNJmeH zn0wHsa0O`KLWmpjR53oD>*soyi-e6tI4LSvDdW@5+E7DY2SjQ8 X72+^(N6gkEH^KU3qC&1 | FileCheck -check-prefix BAD_KIND %s +BAD_KIND: macho-trie-bad-kind': truncated or malformed object (unsupported exported symbol kind: 3 in flags: 0x13 in export trie data at node: 0x53) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-trie-bad-export-info-malformed-uleb128 2>&1 | FileCheck -check-prefix MALFORMED_ULEB128 %s +MALFORMED_ULEB128: macho-trie-bad-export-info-malformed-uleb128': truncated or malformed object (export info size malformed uleb128, extends past end in export trie data at node: 0x5A) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-trie-bad-export-info-malformed-uleb128_too_big 2>&1 | FileCheck -check-prefix MALFORMED_ULEB128_TOO_BIG %s +MALFORMED_ULEB128_TOO_BIG: macho-trie-bad-export-info-malformed-uleb128_too_big': truncated or malformed object (export info size uleb128 too big for uint64 in export trie data at node: 0x5A) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-trie-export-info-size-too-big 2>&1 | FileCheck -check-prefix EXPORT_INFO_SIZE_TOO_BIG %s +EXPORT_INFO_SIZE_TOO_BIG: macho-trie-export-info-size-too-big': truncated or malformed object (export info size: 0x1234 in export trie data at node: 0x33 too big and extends past end of trie data) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-trie-children-count-byte 2>&1 | FileCheck -check-prefix CHILDREN_COUNT_BYTE %s +CHILDREN_COUNT_BYTE: macho-trie-children-count-byte': truncated or malformed object (byte for count of childern in export trie data at node: 0x5 extends past end of trie data) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-trie-import-name-start 2>&1 | FileCheck -check-prefix IMPORT_NAME_START %s +IMPORT_NAME_START: macho-trie-import-name-start': truncated or malformed object (import name of re-export in export trie data at node: 0x33 starts past end of trie data) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-trie-import-name-end 2>&1 | FileCheck -check-prefix IMPORT_NAME_END %s +IMPORT_NAME_END: macho-trie-import-name-end': truncated or malformed object (import name of re-export in export trie data at node: 0x33 extends past end of trie data) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-trie-edge-string-end 2>&1 | FileCheck -check-prefix EDGE_STRING_END %s +EDGE_STRING_END: macho-trie-edge-string-end': truncated or malformed object (edge sub-string in export trie data at node: 0x42 for child #0 extends past end of trie data) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-trie-not-export-node 2>&1 | FileCheck -check-prefix NOT_EXPORT_NODE %s +NOT_EXPORT_NODE: macho-trie-not-export-node': truncated or malformed object (node is not an export node in export trie data at node: 0x5A) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-trie-node-loop 2>&1 | FileCheck -check-prefix LOOP_OF_CHILDERN %s +LOOP_OF_CHILDERN: macho-trie-node-loop': truncated or malformed object (loop in childern in export trie data at node: 0x42 back to node: 0x5) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-trie-bad-library-ordinal 2>&1 | FileCheck -check-prefix BAD_LIBRARY_ORDINAL %s +BAD_LIBRARY_ORDINAL: macho-trie-bad-library-ordinal': truncated or malformed object (bad library ordinal: 69 (max 3) in export trie data at node: 0x33) + +RUN: not llvm-objdump -macho -exports-trie %p/Inputs/macho-inconsistant-export 2>&1 | FileCheck -check-prefix INCONSISTANT_EXPORT_SIZE %s +INCONSISTANT_EXPORT_SIZE: macho-inconsistant-export': truncated or malformed object (inconsistant export info size: 0x9 where actual size was: 0x5 in export trie data at node: 0x53) diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index ea47891250f..e6378a74306 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -1226,7 +1226,9 @@ dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, if (DyldInfoOnly || AddDyldInfo || HFlags & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) { unsigned ExportsAdded = 0; - for (const llvm::object::ExportEntry &Entry : MachO->exports()) { + Error Err = Error::success(); + for (const llvm::object::ExportEntry &Entry : MachO->exports(Err, + MachO)) { bool found = false; bool ReExport = false; if (!DyldInfoOnly) { @@ -1362,6 +1364,8 @@ dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, } } } + if (Err) + error(std::move(Err), MachO->getFileName()); // Set the symbol names and indirect names for the added symbols. if (ExportsAdded) { EOS.flush(); diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 3bab94d681a..31a3f66b1d3 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -9402,7 +9402,8 @@ void llvm::printMachOExportsTrie(const object::MachOObjectFile *Obj) { } } } - for (const llvm::object::ExportEntry &Entry : Obj->exports()) { + Error Err = Error::success(); + for (const llvm::object::ExportEntry &Entry : Obj->exports(Err, Obj)) { uint64_t Flags = Entry.flags(); bool ReExport = (Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT); bool WeakDef = (Flags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION); @@ -9455,6 +9456,8 @@ void llvm::printMachOExportsTrie(const object::MachOObjectFile *Obj) { } outs() << "\n"; } + if (Err) + report_error(Obj->getFileName(), std::move(Err)); } //===----------------------------------------------------------------------===// -- 2.50.1