GSYMTest.cpp 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302
  1. //===- llvm/unittest/DebugInfo/GSYMTest.cpp -------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/ADT/DenseMap.h"
  10. #include "llvm/ADT/SmallString.h"
  11. #include "llvm/DebugInfo/GSYM/Header.h"
  12. #include "llvm/DebugInfo/GSYM/FileEntry.h"
  13. #include "llvm/DebugInfo/GSYM/FileWriter.h"
  14. #include "llvm/DebugInfo/GSYM/FunctionInfo.h"
  15. #include "llvm/DebugInfo/GSYM/GsymCreator.h"
  16. #include "llvm/DebugInfo/GSYM/GsymReader.h"
  17. #include "llvm/DebugInfo/GSYM/InlineInfo.h"
  18. #include "llvm/DebugInfo/GSYM/Range.h"
  19. #include "llvm/DebugInfo/GSYM/StringTable.h"
  20. #include "llvm/Support/DataExtractor.h"
  21. #include "llvm/Support/Endian.h"
  22. #include "gtest/gtest.h"
  23. #include <string>
  24. using namespace llvm;
  25. using namespace gsym;
  26. void checkError(ArrayRef<std::string> ExpectedMsgs, Error Err) {
  27. ASSERT_TRUE(bool(Err));
  28. size_t WhichMsg = 0;
  29. Error Remaining =
  30. handleErrors(std::move(Err), [&](const ErrorInfoBase &Actual) {
  31. ASSERT_LT(WhichMsg, ExpectedMsgs.size());
  32. // Use .str(), because googletest doesn't visualise a StringRef
  33. // properly.
  34. EXPECT_EQ(Actual.message(), ExpectedMsgs[WhichMsg++]);
  35. });
  36. EXPECT_EQ(WhichMsg, ExpectedMsgs.size());
  37. EXPECT_FALSE(Remaining);
  38. }
  39. void checkError(std::string ExpectedMsg, Error Err) {
  40. checkError(ArrayRef<std::string>{ExpectedMsg}, std::move(Err));
  41. }
  42. TEST(GSYMTest, TestFileEntry) {
  43. // Make sure default constructed GSYM FileEntry has zeroes in the
  44. // directory and basename string table indexes.
  45. FileEntry empty1;
  46. FileEntry empty2;
  47. EXPECT_EQ(empty1.Dir, 0u);
  48. EXPECT_EQ(empty1.Base, 0u);
  49. // Verify equality operator works
  50. FileEntry a1(10, 30);
  51. FileEntry a2(10, 30);
  52. FileEntry b(10, 40);
  53. EXPECT_EQ(empty1, empty2);
  54. EXPECT_EQ(a1, a2);
  55. EXPECT_NE(a1, b);
  56. EXPECT_NE(a1, empty1);
  57. // Test we can use llvm::gsym::FileEntry in llvm::DenseMap.
  58. DenseMap<FileEntry, uint32_t> EntryToIndex;
  59. constexpr uint32_t Index1 = 1;
  60. constexpr uint32_t Index2 = 1;
  61. auto R = EntryToIndex.insert(std::make_pair(a1, Index1));
  62. EXPECT_TRUE(R.second);
  63. EXPECT_EQ(R.first->second, Index1);
  64. R = EntryToIndex.insert(std::make_pair(a1, Index1));
  65. EXPECT_FALSE(R.second);
  66. EXPECT_EQ(R.first->second, Index1);
  67. R = EntryToIndex.insert(std::make_pair(b, Index2));
  68. EXPECT_TRUE(R.second);
  69. EXPECT_EQ(R.first->second, Index2);
  70. R = EntryToIndex.insert(std::make_pair(a1, Index2));
  71. EXPECT_FALSE(R.second);
  72. EXPECT_EQ(R.first->second, Index2);
  73. }
  74. TEST(GSYMTest, TestFunctionInfo) {
  75. // Test GSYM FunctionInfo structs and functionality.
  76. FunctionInfo invalid;
  77. EXPECT_FALSE(invalid.isValid());
  78. EXPECT_FALSE(invalid.hasRichInfo());
  79. const uint64_t StartAddr = 0x1000;
  80. const uint64_t EndAddr = 0x1100;
  81. const uint64_t Size = EndAddr - StartAddr;
  82. const uint32_t NameOffset = 30;
  83. FunctionInfo FI(StartAddr, Size, NameOffset);
  84. EXPECT_TRUE(FI.isValid());
  85. EXPECT_FALSE(FI.hasRichInfo());
  86. EXPECT_EQ(FI.startAddress(), StartAddr);
  87. EXPECT_EQ(FI.endAddress(), EndAddr);
  88. EXPECT_EQ(FI.size(), Size);
  89. const uint32_t FileIdx = 1;
  90. const uint32_t Line = 12;
  91. FI.OptLineTable = LineTable();
  92. FI.OptLineTable->push(LineEntry(StartAddr,FileIdx,Line));
  93. EXPECT_TRUE(FI.hasRichInfo());
  94. FI.clear();
  95. EXPECT_FALSE(FI.isValid());
  96. EXPECT_FALSE(FI.hasRichInfo());
  97. FunctionInfo A1(0x1000, 0x100, NameOffset);
  98. FunctionInfo A2(0x1000, 0x100, NameOffset);
  99. FunctionInfo B;
  100. // Check == operator
  101. EXPECT_EQ(A1, A2);
  102. // Make sure things are not equal if they only differ by start address.
  103. B = A2;
  104. B.setStartAddress(0x2000);
  105. EXPECT_NE(B, A2);
  106. // Make sure things are not equal if they only differ by size.
  107. B = A2;
  108. B.setSize(0x101);
  109. EXPECT_NE(B, A2);
  110. // Make sure things are not equal if they only differ by name.
  111. B = A2;
  112. B.Name = 60;
  113. EXPECT_NE(B, A2);
  114. // Check < operator.
  115. // Check less than where address differs.
  116. B = A2;
  117. B.setStartAddress(A2.startAddress() + 0x1000);
  118. EXPECT_LT(A1, B);
  119. // We use the < operator to take a variety of different FunctionInfo
  120. // structs from a variety of sources: symtab, debug info, runtime info
  121. // and we sort them and want the sorting to allow us to quickly get the
  122. // best version of a function info.
  123. FunctionInfo FISymtab(StartAddr, Size, NameOffset);
  124. FunctionInfo FIWithLines(StartAddr, Size, NameOffset);
  125. FIWithLines.OptLineTable = LineTable();
  126. FIWithLines.OptLineTable->push(LineEntry(StartAddr,FileIdx,Line));
  127. // Test that a FunctionInfo with just a name and size is less than one
  128. // that has name, size and any number of line table entries
  129. EXPECT_LT(FISymtab, FIWithLines);
  130. FunctionInfo FIWithLinesAndInline = FIWithLines;
  131. FIWithLinesAndInline.Inline = InlineInfo();
  132. FIWithLinesAndInline.Inline->Ranges.insert(
  133. AddressRange(StartAddr, StartAddr + 0x10));
  134. // Test that a FunctionInfo with name, size, and line entries is less than
  135. // the same one with valid inline info
  136. EXPECT_LT(FIWithLines, FIWithLinesAndInline);
  137. // Test if we have an entry with lines and one with more lines for the same
  138. // range, the ones with more lines is greater than the one with less.
  139. FunctionInfo FIWithMoreLines = FIWithLines;
  140. FIWithMoreLines.OptLineTable->push(LineEntry(StartAddr,FileIdx,Line+5));
  141. EXPECT_LT(FIWithLines, FIWithMoreLines);
  142. // Test that if we have the same number of lines we compare the line entries
  143. // in the FunctionInfo.OptLineTable.Lines vector.
  144. FunctionInfo FIWithLinesWithHigherAddress = FIWithLines;
  145. FIWithLinesWithHigherAddress.OptLineTable->get(0).Addr += 0x10;
  146. EXPECT_LT(FIWithLines, FIWithLinesWithHigherAddress);
  147. }
  148. static void TestFunctionInfoDecodeError(llvm::support::endianness ByteOrder,
  149. std::string Bytes,
  150. const uint64_t BaseAddr,
  151. std::string ExpectedErrorMsg) {
  152. uint8_t AddressSize = 4;
  153. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  154. llvm::Expected<FunctionInfo> Decoded = FunctionInfo::decode(Data, BaseAddr);
  155. // Make sure decoding fails.
  156. ASSERT_FALSE((bool)Decoded);
  157. // Make sure decoded object is the same as the one we encoded.
  158. checkError(ExpectedErrorMsg, Decoded.takeError());
  159. }
  160. TEST(GSYMTest, TestFunctionInfoDecodeErrors) {
  161. // Test decoding FunctionInfo objects that ensure we report an appropriate
  162. // error message.
  163. const llvm::support::endianness ByteOrder = llvm::support::little;
  164. SmallString<512> Str;
  165. raw_svector_ostream OutStrm(Str);
  166. FileWriter FW(OutStrm, ByteOrder);
  167. const uint64_t BaseAddr = 0x100;
  168. TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  169. "0x00000000: missing FunctionInfo Size");
  170. FW.writeU32(0x100); // Function size.
  171. TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  172. "0x00000004: missing FunctionInfo Name");
  173. // Write out an invalid Name string table offset of zero.
  174. FW.writeU32(0);
  175. TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  176. "0x00000004: invalid FunctionInfo Name value 0x00000000");
  177. // Modify the Name to be 0x00000001, which is a valid value.
  178. FW.fixup32(0x00000001, 4);
  179. TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  180. "0x00000008: missing FunctionInfo InfoType value");
  181. auto FixupOffset = FW.tell();
  182. FW.writeU32(1); // InfoType::LineTableInfo.
  183. TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  184. "0x0000000c: missing FunctionInfo InfoType length");
  185. FW.fixup32(4, FixupOffset); // Write an invalid InfoType enumeration value
  186. FW.writeU32(0); // LineTableInfo InfoType data length.
  187. TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  188. "0x00000008: unsupported InfoType 4");
  189. }
  190. static void TestFunctionInfoEncodeError(llvm::support::endianness ByteOrder,
  191. const FunctionInfo &FI,
  192. std::string ExpectedErrorMsg) {
  193. SmallString<512> Str;
  194. raw_svector_ostream OutStrm(Str);
  195. FileWriter FW(OutStrm, ByteOrder);
  196. Expected<uint64_t> ExpectedOffset = FI.encode(FW);
  197. ASSERT_FALSE(ExpectedOffset);
  198. checkError(ExpectedErrorMsg, ExpectedOffset.takeError());
  199. }
  200. TEST(GSYMTest, TestFunctionInfoEncodeErrors) {
  201. const uint64_t FuncAddr = 0x1000;
  202. const uint64_t FuncSize = 0x100;
  203. const uint32_t InvalidName = 0;
  204. const uint32_t ValidName = 1;
  205. FunctionInfo InvalidNameFI(FuncAddr, FuncSize, InvalidName);
  206. TestFunctionInfoEncodeError(llvm::support::little, InvalidNameFI,
  207. "attempted to encode invalid FunctionInfo object");
  208. FunctionInfo InvalidLineTableFI(FuncAddr, FuncSize, ValidName);
  209. // Empty line tables are not valid. Verify if the encoding of anything
  210. // in our line table fails, that we see get the error propagated.
  211. InvalidLineTableFI.OptLineTable = LineTable();
  212. TestFunctionInfoEncodeError(llvm::support::little, InvalidLineTableFI,
  213. "attempted to encode invalid LineTable object");
  214. FunctionInfo InvalidInlineInfoFI(FuncAddr, FuncSize, ValidName);
  215. // Empty line tables are not valid. Verify if the encoding of anything
  216. // in our line table fails, that we see get the error propagated.
  217. InvalidInlineInfoFI.Inline = InlineInfo();
  218. TestFunctionInfoEncodeError(llvm::support::little, InvalidInlineInfoFI,
  219. "attempted to encode invalid InlineInfo object");
  220. }
  221. static void TestFunctionInfoEncodeDecode(llvm::support::endianness ByteOrder,
  222. const FunctionInfo &FI) {
  223. // Test encoding and decoding FunctionInfo objects.
  224. SmallString<512> Str;
  225. raw_svector_ostream OutStrm(Str);
  226. FileWriter FW(OutStrm, ByteOrder);
  227. llvm::Expected<uint64_t> ExpectedOffset = FI.encode(FW);
  228. ASSERT_TRUE(bool(ExpectedOffset));
  229. // Verify we got the encoded offset back from the encode function.
  230. ASSERT_EQ(ExpectedOffset.get(), 0ULL);
  231. std::string Bytes(OutStrm.str());
  232. uint8_t AddressSize = 4;
  233. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  234. llvm::Expected<FunctionInfo> Decoded = FunctionInfo::decode(Data,
  235. FI.Range.Start);
  236. // Make sure decoding succeeded.
  237. ASSERT_TRUE((bool)Decoded);
  238. // Make sure decoded object is the same as the one we encoded.
  239. EXPECT_EQ(FI, Decoded.get());
  240. }
  241. static void AddLines(uint64_t FuncAddr, uint32_t FileIdx, FunctionInfo &FI) {
  242. FI.OptLineTable = LineTable();
  243. LineEntry Line0(FuncAddr + 0x000, FileIdx, 10);
  244. LineEntry Line1(FuncAddr + 0x010, FileIdx, 11);
  245. LineEntry Line2(FuncAddr + 0x100, FileIdx, 1000);
  246. FI.OptLineTable->push(Line0);
  247. FI.OptLineTable->push(Line1);
  248. FI.OptLineTable->push(Line2);
  249. }
  250. static void AddInline(uint64_t FuncAddr, uint64_t FuncSize, FunctionInfo &FI) {
  251. FI.Inline = InlineInfo();
  252. FI.Inline->Ranges.insert(AddressRange(FuncAddr, FuncAddr + FuncSize));
  253. InlineInfo Inline1;
  254. Inline1.Ranges.insert(AddressRange(FuncAddr + 0x10, FuncAddr + 0x30));
  255. Inline1.Name = 1;
  256. Inline1.CallFile = 1;
  257. Inline1.CallLine = 11;
  258. FI.Inline->Children.push_back(Inline1);
  259. }
  260. TEST(GSYMTest, TestFunctionInfoEncoding) {
  261. constexpr uint64_t FuncAddr = 0x1000;
  262. constexpr uint64_t FuncSize = 0x100;
  263. constexpr uint32_t FuncName = 1;
  264. constexpr uint32_t FileIdx = 1;
  265. // Make sure that we can encode and decode a FunctionInfo with no line table
  266. // or inline info.
  267. FunctionInfo FI(FuncAddr, FuncSize, FuncName);
  268. TestFunctionInfoEncodeDecode(llvm::support::little, FI);
  269. TestFunctionInfoEncodeDecode(llvm::support::big, FI);
  270. // Make sure that we can encode and decode a FunctionInfo with a line table
  271. // and no inline info.
  272. FunctionInfo FILines(FuncAddr, FuncSize, FuncName);
  273. AddLines(FuncAddr, FileIdx, FILines);
  274. TestFunctionInfoEncodeDecode(llvm::support::little, FILines);
  275. TestFunctionInfoEncodeDecode(llvm::support::big, FILines);
  276. // Make sure that we can encode and decode a FunctionInfo with no line table
  277. // and with inline info.
  278. FunctionInfo FIInline(FuncAddr, FuncSize, FuncName);
  279. AddInline(FuncAddr, FuncSize, FIInline);
  280. TestFunctionInfoEncodeDecode(llvm::support::little, FIInline);
  281. TestFunctionInfoEncodeDecode(llvm::support::big, FIInline);
  282. // Make sure that we can encode and decode a FunctionInfo with no line table
  283. // and with inline info.
  284. FunctionInfo FIBoth(FuncAddr, FuncSize, FuncName);
  285. AddLines(FuncAddr, FileIdx, FIBoth);
  286. AddInline(FuncAddr, FuncSize, FIBoth);
  287. TestFunctionInfoEncodeDecode(llvm::support::little, FIBoth);
  288. TestFunctionInfoEncodeDecode(llvm::support::big, FIBoth);
  289. }
  290. static void TestInlineInfoEncodeDecode(llvm::support::endianness ByteOrder,
  291. const InlineInfo &Inline) {
  292. // Test encoding and decoding InlineInfo objects
  293. SmallString<512> Str;
  294. raw_svector_ostream OutStrm(Str);
  295. FileWriter FW(OutStrm, ByteOrder);
  296. const uint64_t BaseAddr = Inline.Ranges[0].Start;
  297. llvm::Error Err = Inline.encode(FW, BaseAddr);
  298. ASSERT_FALSE(Err);
  299. std::string Bytes(OutStrm.str());
  300. uint8_t AddressSize = 4;
  301. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  302. llvm::Expected<InlineInfo> Decoded = InlineInfo::decode(Data, BaseAddr);
  303. // Make sure decoding succeeded.
  304. ASSERT_TRUE((bool)Decoded);
  305. // Make sure decoded object is the same as the one we encoded.
  306. EXPECT_EQ(Inline, Decoded.get());
  307. }
  308. static void TestInlineInfoDecodeError(llvm::support::endianness ByteOrder,
  309. std::string Bytes,
  310. const uint64_t BaseAddr,
  311. std::string ExpectedErrorMsg) {
  312. uint8_t AddressSize = 4;
  313. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  314. llvm::Expected<InlineInfo> Decoded = InlineInfo::decode(Data, BaseAddr);
  315. // Make sure decoding fails.
  316. ASSERT_FALSE((bool)Decoded);
  317. // Make sure decoded object is the same as the one we encoded.
  318. checkError(ExpectedErrorMsg, Decoded.takeError());
  319. }
  320. static void TestInlineInfoEncodeError(llvm::support::endianness ByteOrder,
  321. const InlineInfo &Inline,
  322. std::string ExpectedErrorMsg) {
  323. SmallString<512> Str;
  324. raw_svector_ostream OutStrm(Str);
  325. FileWriter FW(OutStrm, ByteOrder);
  326. const uint64_t BaseAddr = Inline.Ranges.empty() ? 0 : Inline.Ranges[0].Start;
  327. llvm::Error Err = Inline.encode(FW, BaseAddr);
  328. checkError(ExpectedErrorMsg, std::move(Err));
  329. }
  330. TEST(GSYMTest, TestInlineInfo) {
  331. // Test InlineInfo structs.
  332. InlineInfo II;
  333. EXPECT_FALSE(II.isValid());
  334. II.Ranges.insert(AddressRange(0x1000, 0x2000));
  335. // Make sure InlineInfo in valid with just an address range since
  336. // top level InlineInfo objects have ranges with no name, call file
  337. // or call line
  338. EXPECT_TRUE(II.isValid());
  339. // Make sure InlineInfo isn't after being cleared.
  340. II.clear();
  341. EXPECT_FALSE(II.isValid());
  342. // Create an InlineInfo that contains the following data. The
  343. // indentation of the address range indicates the parent child
  344. // relationships of the InlineInfo objects:
  345. //
  346. // Variable Range and values
  347. // =========== ====================================================
  348. // Root [0x100-0x200) (no name, file, or line)
  349. // Inline1 [0x150-0x160) Name = 1, File = 1, Line = 11
  350. // Inline1Sub1 [0x152-0x155) Name = 2, File = 2, Line = 22
  351. // Inline1Sub2 [0x157-0x158) Name = 3, File = 3, Line = 33
  352. InlineInfo Root;
  353. Root.Ranges.insert(AddressRange(0x100, 0x200));
  354. InlineInfo Inline1;
  355. Inline1.Ranges.insert(AddressRange(0x150, 0x160));
  356. Inline1.Name = 1;
  357. Inline1.CallFile = 1;
  358. Inline1.CallLine = 11;
  359. InlineInfo Inline1Sub1;
  360. Inline1Sub1.Ranges.insert(AddressRange(0x152, 0x155));
  361. Inline1Sub1.Name = 2;
  362. Inline1Sub1.CallFile = 2;
  363. Inline1Sub1.CallLine = 22;
  364. InlineInfo Inline1Sub2;
  365. Inline1Sub2.Ranges.insert(AddressRange(0x157, 0x158));
  366. Inline1Sub2.Name = 3;
  367. Inline1Sub2.CallFile = 3;
  368. Inline1Sub2.CallLine = 33;
  369. Inline1.Children.push_back(Inline1Sub1);
  370. Inline1.Children.push_back(Inline1Sub2);
  371. Root.Children.push_back(Inline1);
  372. // Make sure an address that is out of range won't match
  373. EXPECT_FALSE(Root.getInlineStack(0x50));
  374. // Verify that we get no inline stacks for addresses out of [0x100-0x200)
  375. EXPECT_FALSE(Root.getInlineStack(Root.Ranges[0].Start - 1));
  376. EXPECT_FALSE(Root.getInlineStack(Root.Ranges[0].End));
  377. // Verify we get no inline stack entries for addresses that are in
  378. // [0x100-0x200) but not in [0x150-0x160)
  379. EXPECT_FALSE(Root.getInlineStack(Inline1.Ranges[0].Start - 1));
  380. EXPECT_FALSE(Root.getInlineStack(Inline1.Ranges[0].End));
  381. // Verify we get one inline stack entry for addresses that are in
  382. // [[0x150-0x160)) but not in [0x152-0x155) or [0x157-0x158)
  383. auto InlineInfos = Root.getInlineStack(Inline1.Ranges[0].Start);
  384. ASSERT_TRUE(InlineInfos);
  385. ASSERT_EQ(InlineInfos->size(), 1u);
  386. ASSERT_EQ(*InlineInfos->at(0), Inline1);
  387. InlineInfos = Root.getInlineStack(Inline1.Ranges[0].End - 1);
  388. EXPECT_TRUE(InlineInfos);
  389. ASSERT_EQ(InlineInfos->size(), 1u);
  390. ASSERT_EQ(*InlineInfos->at(0), Inline1);
  391. // Verify we get two inline stack entries for addresses that are in
  392. // [0x152-0x155)
  393. InlineInfos = Root.getInlineStack(Inline1Sub1.Ranges[0].Start);
  394. EXPECT_TRUE(InlineInfos);
  395. ASSERT_EQ(InlineInfos->size(), 2u);
  396. ASSERT_EQ(*InlineInfos->at(0), Inline1Sub1);
  397. ASSERT_EQ(*InlineInfos->at(1), Inline1);
  398. InlineInfos = Root.getInlineStack(Inline1Sub1.Ranges[0].End - 1);
  399. EXPECT_TRUE(InlineInfos);
  400. ASSERT_EQ(InlineInfos->size(), 2u);
  401. ASSERT_EQ(*InlineInfos->at(0), Inline1Sub1);
  402. ASSERT_EQ(*InlineInfos->at(1), Inline1);
  403. // Verify we get two inline stack entries for addresses that are in
  404. // [0x157-0x158)
  405. InlineInfos = Root.getInlineStack(Inline1Sub2.Ranges[0].Start);
  406. EXPECT_TRUE(InlineInfos);
  407. ASSERT_EQ(InlineInfos->size(), 2u);
  408. ASSERT_EQ(*InlineInfos->at(0), Inline1Sub2);
  409. ASSERT_EQ(*InlineInfos->at(1), Inline1);
  410. InlineInfos = Root.getInlineStack(Inline1Sub2.Ranges[0].End - 1);
  411. EXPECT_TRUE(InlineInfos);
  412. ASSERT_EQ(InlineInfos->size(), 2u);
  413. ASSERT_EQ(*InlineInfos->at(0), Inline1Sub2);
  414. ASSERT_EQ(*InlineInfos->at(1), Inline1);
  415. // Test encoding and decoding InlineInfo objects
  416. TestInlineInfoEncodeDecode(llvm::support::little, Root);
  417. TestInlineInfoEncodeDecode(llvm::support::big, Root);
  418. }
  419. TEST(GSYMTest, TestInlineInfoEncodeErrors) {
  420. // Test InlineInfo encoding errors.
  421. // Test that we get an error when trying to encode an InlineInfo object
  422. // that has no ranges.
  423. InlineInfo Empty;
  424. std::string EmptyErr("attempted to encode invalid InlineInfo object");
  425. TestInlineInfoEncodeError(llvm::support::little, Empty, EmptyErr);
  426. TestInlineInfoEncodeError(llvm::support::big, Empty, EmptyErr);
  427. // Verify that we get an error trying to encode an InlineInfo object that has
  428. // a child InlineInfo that has no ranges.
  429. InlineInfo ContainsEmpty;
  430. ContainsEmpty.Ranges.insert({0x100,200});
  431. ContainsEmpty.Children.push_back(Empty);
  432. TestInlineInfoEncodeError(llvm::support::little, ContainsEmpty, EmptyErr);
  433. TestInlineInfoEncodeError(llvm::support::big, ContainsEmpty, EmptyErr);
  434. // Verify that we get an error trying to encode an InlineInfo object that has
  435. // a child whose address range is not contained in the parent address range.
  436. InlineInfo ChildNotContained;
  437. std::string ChildNotContainedErr("child range not contained in parent");
  438. ChildNotContained.Ranges.insert({0x100,200});
  439. InlineInfo ChildNotContainedChild;
  440. ChildNotContainedChild.Ranges.insert({0x200,300});
  441. ChildNotContained.Children.push_back(ChildNotContainedChild);
  442. TestInlineInfoEncodeError(llvm::support::little, ChildNotContained,
  443. ChildNotContainedErr);
  444. TestInlineInfoEncodeError(llvm::support::big, ChildNotContained,
  445. ChildNotContainedErr);
  446. }
  447. TEST(GSYMTest, TestInlineInfoDecodeErrors) {
  448. // Test decoding InlineInfo objects that ensure we report an appropriate
  449. // error message.
  450. const llvm::support::endianness ByteOrder = llvm::support::little;
  451. SmallString<512> Str;
  452. raw_svector_ostream OutStrm(Str);
  453. FileWriter FW(OutStrm, ByteOrder);
  454. const uint64_t BaseAddr = 0x100;
  455. TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  456. "0x00000000: missing InlineInfo address ranges data");
  457. AddressRanges Ranges;
  458. Ranges.insert({BaseAddr, BaseAddr+0x100});
  459. Ranges.encode(FW, BaseAddr);
  460. TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  461. "0x00000004: missing InlineInfo uint8_t indicating children");
  462. FW.writeU8(0);
  463. TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  464. "0x00000005: missing InlineInfo uint32_t for name");
  465. FW.writeU32(0);
  466. TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  467. "0x00000009: missing ULEB128 for InlineInfo call file");
  468. FW.writeU8(0);
  469. TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  470. "0x0000000a: missing ULEB128 for InlineInfo call line");
  471. }
  472. TEST(GSYMTest, TestLineEntry) {
  473. // test llvm::gsym::LineEntry structs.
  474. const uint64_t ValidAddr = 0x1000;
  475. const uint64_t InvalidFileIdx = 0;
  476. const uint32_t ValidFileIdx = 1;
  477. const uint32_t ValidLine = 5;
  478. LineEntry Invalid;
  479. EXPECT_FALSE(Invalid.isValid());
  480. // Make sure that an entry is invalid if it has a bad file index.
  481. LineEntry BadFile(ValidAddr, InvalidFileIdx, ValidLine);
  482. EXPECT_FALSE(BadFile.isValid());
  483. // Test operators
  484. LineEntry E1(ValidAddr, ValidFileIdx, ValidLine);
  485. LineEntry E2(ValidAddr, ValidFileIdx, ValidLine);
  486. LineEntry DifferentAddr(ValidAddr + 1, ValidFileIdx, ValidLine);
  487. LineEntry DifferentFile(ValidAddr, ValidFileIdx + 1, ValidLine);
  488. LineEntry DifferentLine(ValidAddr, ValidFileIdx, ValidLine + 1);
  489. EXPECT_TRUE(E1.isValid());
  490. EXPECT_EQ(E1, E2);
  491. EXPECT_NE(E1, DifferentAddr);
  492. EXPECT_NE(E1, DifferentFile);
  493. EXPECT_NE(E1, DifferentLine);
  494. EXPECT_LT(E1, DifferentAddr);
  495. }
  496. TEST(GSYMTest, TestRanges) {
  497. // test llvm::gsym::AddressRange.
  498. const uint64_t StartAddr = 0x1000;
  499. const uint64_t EndAddr = 0x2000;
  500. // Verify constructor and API to ensure it takes start and end address.
  501. const AddressRange Range(StartAddr, EndAddr);
  502. EXPECT_EQ(Range.size(), EndAddr - StartAddr);
  503. // Verify llvm::gsym::AddressRange::contains().
  504. EXPECT_FALSE(Range.contains(0));
  505. EXPECT_FALSE(Range.contains(StartAddr - 1));
  506. EXPECT_TRUE(Range.contains(StartAddr));
  507. EXPECT_TRUE(Range.contains(EndAddr - 1));
  508. EXPECT_FALSE(Range.contains(EndAddr));
  509. EXPECT_FALSE(Range.contains(UINT64_MAX));
  510. const AddressRange RangeSame(StartAddr, EndAddr);
  511. const AddressRange RangeDifferentStart(StartAddr + 1, EndAddr);
  512. const AddressRange RangeDifferentEnd(StartAddr, EndAddr + 1);
  513. const AddressRange RangeDifferentStartEnd(StartAddr + 1, EndAddr + 1);
  514. // Test == and != with values that are the same
  515. EXPECT_EQ(Range, RangeSame);
  516. EXPECT_FALSE(Range != RangeSame);
  517. // Test == and != with values that are the different
  518. EXPECT_NE(Range, RangeDifferentStart);
  519. EXPECT_NE(Range, RangeDifferentEnd);
  520. EXPECT_NE(Range, RangeDifferentStartEnd);
  521. EXPECT_FALSE(Range == RangeDifferentStart);
  522. EXPECT_FALSE(Range == RangeDifferentEnd);
  523. EXPECT_FALSE(Range == RangeDifferentStartEnd);
  524. // Test "bool operator<(const AddressRange &, const AddressRange &)".
  525. EXPECT_FALSE(Range < RangeSame);
  526. EXPECT_FALSE(RangeSame < Range);
  527. EXPECT_LT(Range, RangeDifferentStart);
  528. EXPECT_LT(Range, RangeDifferentEnd);
  529. EXPECT_LT(Range, RangeDifferentStartEnd);
  530. // Test "bool operator<(const AddressRange &, uint64_t)"
  531. EXPECT_LT(Range.Start, StartAddr + 1);
  532. // Test "bool operator<(uint64_t, const AddressRange &)"
  533. EXPECT_LT(StartAddr - 1, Range.Start);
  534. // Verify llvm::gsym::AddressRange::isContiguousWith() and
  535. // llvm::gsym::AddressRange::intersects().
  536. const AddressRange EndsBeforeRangeStart(0, StartAddr - 1);
  537. const AddressRange EndsAtRangeStart(0, StartAddr);
  538. const AddressRange OverlapsRangeStart(StartAddr - 1, StartAddr + 1);
  539. const AddressRange InsideRange(StartAddr + 1, EndAddr - 1);
  540. const AddressRange OverlapsRangeEnd(EndAddr - 1, EndAddr + 1);
  541. const AddressRange StartsAtRangeEnd(EndAddr, EndAddr + 0x100);
  542. const AddressRange StartsAfterRangeEnd(EndAddr + 1, EndAddr + 0x100);
  543. EXPECT_FALSE(Range.intersects(EndsBeforeRangeStart));
  544. EXPECT_FALSE(Range.intersects(EndsAtRangeStart));
  545. EXPECT_TRUE(Range.intersects(OverlapsRangeStart));
  546. EXPECT_TRUE(Range.intersects(InsideRange));
  547. EXPECT_TRUE(Range.intersects(OverlapsRangeEnd));
  548. EXPECT_FALSE(Range.intersects(StartsAtRangeEnd));
  549. EXPECT_FALSE(Range.intersects(StartsAfterRangeEnd));
  550. // Test the functions that maintain GSYM address ranges:
  551. // "bool AddressRange::contains(uint64_t Addr) const;"
  552. // "void AddressRanges::insert(const AddressRange &R);"
  553. AddressRanges Ranges;
  554. Ranges.insert(AddressRange(0x1000, 0x2000));
  555. Ranges.insert(AddressRange(0x2000, 0x3000));
  556. Ranges.insert(AddressRange(0x4000, 0x5000));
  557. EXPECT_FALSE(Ranges.contains(0));
  558. EXPECT_FALSE(Ranges.contains(0x1000 - 1));
  559. EXPECT_TRUE(Ranges.contains(0x1000));
  560. EXPECT_TRUE(Ranges.contains(0x2000));
  561. EXPECT_TRUE(Ranges.contains(0x4000));
  562. EXPECT_TRUE(Ranges.contains(0x2000 - 1));
  563. EXPECT_TRUE(Ranges.contains(0x3000 - 1));
  564. EXPECT_FALSE(Ranges.contains(0x3000 + 1));
  565. EXPECT_TRUE(Ranges.contains(0x5000 - 1));
  566. EXPECT_FALSE(Ranges.contains(0x5000 + 1));
  567. EXPECT_FALSE(Ranges.contains(UINT64_MAX));
  568. EXPECT_FALSE(Ranges.contains(AddressRange()));
  569. EXPECT_FALSE(Ranges.contains(AddressRange(0x1000-1, 0x1000)));
  570. EXPECT_FALSE(Ranges.contains(AddressRange(0x1000, 0x1000)));
  571. EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x1000+1)));
  572. EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x2000)));
  573. EXPECT_FALSE(Ranges.contains(AddressRange(0x1000, 0x2001)));
  574. EXPECT_TRUE(Ranges.contains(AddressRange(0x2000, 0x3000)));
  575. EXPECT_FALSE(Ranges.contains(AddressRange(0x2000, 0x3001)));
  576. EXPECT_FALSE(Ranges.contains(AddressRange(0x3000, 0x3001)));
  577. EXPECT_FALSE(Ranges.contains(AddressRange(0x1500, 0x4500)));
  578. EXPECT_FALSE(Ranges.contains(AddressRange(0x5000, 0x5001)));
  579. // Verify that intersecting ranges get combined
  580. Ranges.clear();
  581. Ranges.insert(AddressRange(0x1100, 0x1F00));
  582. // Verify a wholy contained range that is added doesn't do anything.
  583. Ranges.insert(AddressRange(0x1500, 0x1F00));
  584. EXPECT_EQ(Ranges.size(), 1u);
  585. EXPECT_EQ(Ranges[0], AddressRange(0x1100, 0x1F00));
  586. // Verify a range that starts before and intersects gets combined.
  587. Ranges.insert(AddressRange(0x1000, Ranges[0].Start + 1));
  588. EXPECT_EQ(Ranges.size(), 1u);
  589. EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x1F00));
  590. // Verify a range that starts inside and extends ranges gets combined.
  591. Ranges.insert(AddressRange(Ranges[0].End - 1, 0x2000));
  592. EXPECT_EQ(Ranges.size(), 1u);
  593. EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
  594. // Verify that adjacent ranges don't get combined
  595. Ranges.insert(AddressRange(0x2000, 0x3000));
  596. EXPECT_EQ(Ranges.size(), 2u);
  597. EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
  598. EXPECT_EQ(Ranges[1], AddressRange(0x2000, 0x3000));
  599. // Verify if we add an address range that intersects two ranges
  600. // that they get combined
  601. Ranges.insert(AddressRange(Ranges[0].End - 1, Ranges[1].Start + 1));
  602. EXPECT_EQ(Ranges.size(), 1u);
  603. EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x3000));
  604. Ranges.insert(AddressRange(0x3000, 0x4000));
  605. Ranges.insert(AddressRange(0x4000, 0x5000));
  606. Ranges.insert(AddressRange(0x2000, 0x4500));
  607. EXPECT_EQ(Ranges.size(), 1u);
  608. EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x5000));
  609. }
  610. TEST(GSYMTest, TestStringTable) {
  611. StringTable StrTab(StringRef("\0Hello\0World\0", 13));
  612. // Test extracting strings from a string table.
  613. EXPECT_EQ(StrTab.getString(0), "");
  614. EXPECT_EQ(StrTab.getString(1), "Hello");
  615. EXPECT_EQ(StrTab.getString(7), "World");
  616. EXPECT_EQ(StrTab.getString(8), "orld");
  617. // Test pointing to last NULL terminator gets empty string.
  618. EXPECT_EQ(StrTab.getString(12), "");
  619. // Test pointing to past end gets empty string.
  620. EXPECT_EQ(StrTab.getString(13), "");
  621. }
  622. static void TestFileWriterHelper(llvm::support::endianness ByteOrder) {
  623. SmallString<512> Str;
  624. raw_svector_ostream OutStrm(Str);
  625. FileWriter FW(OutStrm, ByteOrder);
  626. const int64_t MinSLEB = INT64_MIN;
  627. const int64_t MaxSLEB = INT64_MAX;
  628. const uint64_t MinULEB = 0;
  629. const uint64_t MaxULEB = UINT64_MAX;
  630. const uint8_t U8 = 0x10;
  631. const uint16_t U16 = 0x1122;
  632. const uint32_t U32 = 0x12345678;
  633. const uint64_t U64 = 0x33445566778899aa;
  634. const char *Hello = "hello";
  635. FW.writeU8(U8);
  636. FW.writeU16(U16);
  637. FW.writeU32(U32);
  638. FW.writeU64(U64);
  639. FW.alignTo(16);
  640. const off_t FixupOffset = FW.tell();
  641. FW.writeU32(0);
  642. FW.writeSLEB(MinSLEB);
  643. FW.writeSLEB(MaxSLEB);
  644. FW.writeULEB(MinULEB);
  645. FW.writeULEB(MaxULEB);
  646. FW.writeNullTerminated(Hello);
  647. // Test Seek, Tell using Fixup32.
  648. FW.fixup32(U32, FixupOffset);
  649. std::string Bytes(OutStrm.str());
  650. uint8_t AddressSize = 4;
  651. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  652. uint64_t Offset = 0;
  653. EXPECT_EQ(Data.getU8(&Offset), U8);
  654. EXPECT_EQ(Data.getU16(&Offset), U16);
  655. EXPECT_EQ(Data.getU32(&Offset), U32);
  656. EXPECT_EQ(Data.getU64(&Offset), U64);
  657. Offset = alignTo(Offset, 16);
  658. EXPECT_EQ(Data.getU32(&Offset), U32);
  659. EXPECT_EQ(Data.getSLEB128(&Offset), MinSLEB);
  660. EXPECT_EQ(Data.getSLEB128(&Offset), MaxSLEB);
  661. EXPECT_EQ(Data.getULEB128(&Offset), MinULEB);
  662. EXPECT_EQ(Data.getULEB128(&Offset), MaxULEB);
  663. EXPECT_EQ(Data.getCStrRef(&Offset), StringRef(Hello));
  664. }
  665. TEST(GSYMTest, TestFileWriter) {
  666. TestFileWriterHelper(llvm::support::little);
  667. TestFileWriterHelper(llvm::support::big);
  668. }
  669. TEST(GSYMTest, TestAddressRangeEncodeDecode) {
  670. // Test encoding and decoding AddressRange objects. AddressRange objects
  671. // are always stored as offsets from the a base address. The base address
  672. // is the FunctionInfo's base address for function level ranges, and is
  673. // the base address of the parent range for subranges.
  674. SmallString<512> Str;
  675. raw_svector_ostream OutStrm(Str);
  676. const auto ByteOrder = llvm::support::endian::system_endianness();
  677. FileWriter FW(OutStrm, ByteOrder);
  678. const uint64_t BaseAddr = 0x1000;
  679. const AddressRange Range1(0x1000, 0x1010);
  680. const AddressRange Range2(0x1020, 0x1030);
  681. Range1.encode(FW, BaseAddr);
  682. Range2.encode(FW, BaseAddr);
  683. std::string Bytes(OutStrm.str());
  684. uint8_t AddressSize = 4;
  685. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  686. AddressRange DecodedRange1, DecodedRange2;
  687. uint64_t Offset = 0;
  688. DecodedRange1.decode(Data, BaseAddr, Offset);
  689. DecodedRange2.decode(Data, BaseAddr, Offset);
  690. EXPECT_EQ(Range1, DecodedRange1);
  691. EXPECT_EQ(Range2, DecodedRange2);
  692. }
  693. static void TestAddressRangeEncodeDecodeHelper(const AddressRanges &Ranges,
  694. const uint64_t BaseAddr) {
  695. SmallString<512> Str;
  696. raw_svector_ostream OutStrm(Str);
  697. const auto ByteOrder = llvm::support::endian::system_endianness();
  698. FileWriter FW(OutStrm, ByteOrder);
  699. Ranges.encode(FW, BaseAddr);
  700. std::string Bytes(OutStrm.str());
  701. uint8_t AddressSize = 4;
  702. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  703. AddressRanges DecodedRanges;
  704. uint64_t Offset = 0;
  705. DecodedRanges.decode(Data, BaseAddr, Offset);
  706. EXPECT_EQ(Ranges, DecodedRanges);
  707. }
  708. TEST(GSYMTest, TestAddressRangesEncodeDecode) {
  709. // Test encoding and decoding AddressRanges. AddressRanges objects contain
  710. // ranges that are stored as offsets from the a base address. The base address
  711. // is the FunctionInfo's base address for function level ranges, and is the
  712. // base address of the parent range for subranges.
  713. const uint64_t BaseAddr = 0x1000;
  714. // Test encoding and decoding with no ranges.
  715. AddressRanges Ranges;
  716. TestAddressRangeEncodeDecodeHelper(Ranges, BaseAddr);
  717. // Test encoding and decoding with 1 range.
  718. Ranges.insert(AddressRange(0x1000, 0x1010));
  719. TestAddressRangeEncodeDecodeHelper(Ranges, BaseAddr);
  720. // Test encoding and decoding with multiple ranges.
  721. Ranges.insert(AddressRange(0x1020, 0x1030));
  722. Ranges.insert(AddressRange(0x1050, 0x1070));
  723. TestAddressRangeEncodeDecodeHelper(Ranges, BaseAddr);
  724. }
  725. static void TestLineTableHelper(llvm::support::endianness ByteOrder,
  726. const LineTable &LT) {
  727. SmallString<512> Str;
  728. raw_svector_ostream OutStrm(Str);
  729. FileWriter FW(OutStrm, ByteOrder);
  730. const uint64_t BaseAddr = LT[0].Addr;
  731. llvm::Error Err = LT.encode(FW, BaseAddr);
  732. ASSERT_FALSE(Err);
  733. std::string Bytes(OutStrm.str());
  734. uint8_t AddressSize = 4;
  735. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  736. llvm::Expected<LineTable> Decoded = LineTable::decode(Data, BaseAddr);
  737. // Make sure decoding succeeded.
  738. ASSERT_TRUE((bool)Decoded);
  739. // Make sure decoded object is the same as the one we encoded.
  740. EXPECT_EQ(LT, Decoded.get());
  741. }
  742. TEST(GSYMTest, TestLineTable) {
  743. const uint64_t StartAddr = 0x1000;
  744. const uint32_t FileIdx = 1;
  745. LineTable LT;
  746. LineEntry Line0(StartAddr+0x000, FileIdx, 10);
  747. LineEntry Line1(StartAddr+0x010, FileIdx, 11);
  748. LineEntry Line2(StartAddr+0x100, FileIdx, 1000);
  749. ASSERT_TRUE(LT.empty());
  750. ASSERT_EQ(LT.size(), (size_t)0);
  751. LT.push(Line0);
  752. ASSERT_EQ(LT.size(), (size_t)1);
  753. LT.push(Line1);
  754. LT.push(Line2);
  755. LT.push(LineEntry(StartAddr+0x120, FileIdx, 900));
  756. LT.push(LineEntry(StartAddr+0x120, FileIdx, 2000));
  757. LT.push(LineEntry(StartAddr+0x121, FileIdx, 2001));
  758. LT.push(LineEntry(StartAddr+0x122, FileIdx, 2002));
  759. LT.push(LineEntry(StartAddr+0x123, FileIdx, 2003));
  760. ASSERT_FALSE(LT.empty());
  761. ASSERT_EQ(LT.size(), (size_t)8);
  762. // Test operator[].
  763. ASSERT_EQ(LT[0], Line0);
  764. ASSERT_EQ(LT[1], Line1);
  765. ASSERT_EQ(LT[2], Line2);
  766. // Test encoding and decoding line tables.
  767. TestLineTableHelper(llvm::support::little, LT);
  768. TestLineTableHelper(llvm::support::big, LT);
  769. // Verify the clear method works as expected.
  770. LT.clear();
  771. ASSERT_TRUE(LT.empty());
  772. ASSERT_EQ(LT.size(), (size_t)0);
  773. LineTable LT1;
  774. LineTable LT2;
  775. // Test that two empty line tables are equal and neither are less than
  776. // each other.
  777. ASSERT_EQ(LT1, LT2);
  778. ASSERT_FALSE(LT1 < LT2);
  779. ASSERT_FALSE(LT2 < LT2);
  780. // Test that a line table with less number of line entries is less than a
  781. // line table with more line entries and that they are not equal.
  782. LT2.push(Line0);
  783. ASSERT_LT(LT1, LT2);
  784. ASSERT_NE(LT1, LT2);
  785. // Test that two line tables with the same entries are equal.
  786. LT1.push(Line0);
  787. ASSERT_EQ(LT1, LT2);
  788. ASSERT_FALSE(LT1 < LT2);
  789. ASSERT_FALSE(LT2 < LT2);
  790. }
  791. static void TestLineTableDecodeError(llvm::support::endianness ByteOrder,
  792. std::string Bytes,
  793. const uint64_t BaseAddr,
  794. std::string ExpectedErrorMsg) {
  795. uint8_t AddressSize = 4;
  796. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  797. llvm::Expected<LineTable> Decoded = LineTable::decode(Data, BaseAddr);
  798. // Make sure decoding fails.
  799. ASSERT_FALSE((bool)Decoded);
  800. // Make sure decoded object is the same as the one we encoded.
  801. checkError(ExpectedErrorMsg, Decoded.takeError());
  802. }
  803. TEST(GSYMTest, TestLineTableDecodeErrors) {
  804. // Test decoding InlineInfo objects that ensure we report an appropriate
  805. // error message.
  806. const llvm::support::endianness ByteOrder = llvm::support::little;
  807. SmallString<512> Str;
  808. raw_svector_ostream OutStrm(Str);
  809. FileWriter FW(OutStrm, ByteOrder);
  810. const uint64_t BaseAddr = 0x100;
  811. TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  812. "0x00000000: missing LineTable MinDelta");
  813. FW.writeU8(1); // MinDelta (ULEB)
  814. TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  815. "0x00000001: missing LineTable MaxDelta");
  816. FW.writeU8(10); // MaxDelta (ULEB)
  817. TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  818. "0x00000002: missing LineTable FirstLine");
  819. FW.writeU8(20); // FirstLine (ULEB)
  820. TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  821. "0x00000003: EOF found before EndSequence");
  822. // Test a SetFile with the argument missing from the stream
  823. FW.writeU8(1); // SetFile opcode (uint8_t)
  824. TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  825. "0x00000004: EOF found before SetFile value");
  826. FW.writeU8(5); // SetFile value as index (ULEB)
  827. // Test a AdvancePC with the argument missing from the stream
  828. FW.writeU8(2); // AdvancePC opcode (uint8_t)
  829. TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  830. "0x00000006: EOF found before AdvancePC value");
  831. FW.writeU8(20); // AdvancePC value as offset (ULEB)
  832. // Test a AdvancePC with the argument missing from the stream
  833. FW.writeU8(3); // AdvanceLine opcode (uint8_t)
  834. TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
  835. "0x00000008: EOF found before AdvanceLine value");
  836. FW.writeU8(20); // AdvanceLine value as offset (LLEB)
  837. }
  838. TEST(GSYMTest, TestLineTableEncodeErrors) {
  839. const uint64_t BaseAddr = 0x1000;
  840. const uint32_t FileIdx = 1;
  841. const llvm::support::endianness ByteOrder = llvm::support::little;
  842. SmallString<512> Str;
  843. raw_svector_ostream OutStrm(Str);
  844. FileWriter FW(OutStrm, ByteOrder);
  845. LineTable LT;
  846. checkError("attempted to encode invalid LineTable object",
  847. LT.encode(FW, BaseAddr));
  848. // Try to encode a line table where a line entry has an address that is less
  849. // than BaseAddr and verify we get an appropriate error.
  850. LineEntry Line0(BaseAddr+0x000, FileIdx, 10);
  851. LineEntry Line1(BaseAddr+0x010, FileIdx, 11);
  852. LT.push(Line0);
  853. LT.push(Line1);
  854. checkError("LineEntry has address 0x1000 which is less than the function "
  855. "start address 0x1010", LT.encode(FW, BaseAddr+0x10));
  856. LT.clear();
  857. // Try to encode a line table where a line entries has an address that is less
  858. // than BaseAddr and verify we get an appropriate error.
  859. LT.push(Line1);
  860. LT.push(Line0);
  861. checkError("LineEntry in LineTable not in ascending order",
  862. LT.encode(FW, BaseAddr));
  863. LT.clear();
  864. }
  865. static void TestHeaderEncodeError(const Header &H,
  866. std::string ExpectedErrorMsg) {
  867. const support::endianness ByteOrder = llvm::support::little;
  868. SmallString<512> Str;
  869. raw_svector_ostream OutStrm(Str);
  870. FileWriter FW(OutStrm, ByteOrder);
  871. llvm::Error Err = H.encode(FW);
  872. checkError(ExpectedErrorMsg, std::move(Err));
  873. }
  874. static void TestHeaderDecodeError(std::string Bytes,
  875. std::string ExpectedErrorMsg) {
  876. const support::endianness ByteOrder = llvm::support::little;
  877. uint8_t AddressSize = 4;
  878. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  879. llvm::Expected<Header> Decoded = Header::decode(Data);
  880. // Make sure decoding fails.
  881. ASSERT_FALSE((bool)Decoded);
  882. // Make sure decoded object is the same as the one we encoded.
  883. checkError(ExpectedErrorMsg, Decoded.takeError());
  884. }
  885. // Populate a GSYM header with valid values.
  886. static void InitHeader(Header &H) {
  887. H.Magic = GSYM_MAGIC;
  888. H.Version = GSYM_VERSION;
  889. H.AddrOffSize = 4;
  890. H.UUIDSize = 16;
  891. H.BaseAddress = 0x1000;
  892. H.NumAddresses = 1;
  893. H.StrtabOffset= 0x2000;
  894. H.StrtabSize = 0x1000;
  895. for (size_t i=0; i<GSYM_MAX_UUID_SIZE; ++i) {
  896. if (i < H.UUIDSize)
  897. H.UUID[i] = i;
  898. else
  899. H.UUID[i] = 0;
  900. }
  901. }
  902. TEST(GSYMTest, TestHeaderEncodeErrors) {
  903. Header H;
  904. InitHeader(H);
  905. H.Magic = 12;
  906. TestHeaderEncodeError(H, "invalid GSYM magic 0x0000000c");
  907. InitHeader(H);
  908. H.Version = 12;
  909. TestHeaderEncodeError(H, "unsupported GSYM version 12");
  910. InitHeader(H);
  911. H.AddrOffSize = 12;
  912. TestHeaderEncodeError(H, "invalid address offset size 12");
  913. InitHeader(H);
  914. H.UUIDSize = 128;
  915. TestHeaderEncodeError(H, "invalid UUID size 128");
  916. }
  917. TEST(GSYMTest, TestHeaderDecodeErrors) {
  918. const llvm::support::endianness ByteOrder = llvm::support::little;
  919. SmallString<512> Str;
  920. raw_svector_ostream OutStrm(Str);
  921. FileWriter FW(OutStrm, ByteOrder);
  922. Header H;
  923. InitHeader(H);
  924. llvm::Error Err = H.encode(FW);
  925. ASSERT_FALSE(Err);
  926. FW.fixup32(12, offsetof(Header, Magic));
  927. TestHeaderDecodeError(OutStrm.str(), "invalid GSYM magic 0x0000000c");
  928. FW.fixup32(GSYM_MAGIC, offsetof(Header, Magic));
  929. FW.fixup32(12, offsetof(Header, Version));
  930. TestHeaderDecodeError(OutStrm.str(), "unsupported GSYM version 12");
  931. FW.fixup32(GSYM_VERSION, offsetof(Header, Version));
  932. FW.fixup32(12, offsetof(Header, AddrOffSize));
  933. TestHeaderDecodeError(OutStrm.str(), "invalid address offset size 12");
  934. FW.fixup32(4, offsetof(Header, AddrOffSize));
  935. FW.fixup32(128, offsetof(Header, UUIDSize));
  936. TestHeaderDecodeError(OutStrm.str(), "invalid UUID size 128");
  937. }
  938. static void TestHeaderEncodeDecode(const Header &H,
  939. support::endianness ByteOrder) {
  940. uint8_t AddressSize = 4;
  941. SmallString<512> Str;
  942. raw_svector_ostream OutStrm(Str);
  943. FileWriter FW(OutStrm, ByteOrder);
  944. llvm::Error Err = H.encode(FW);
  945. ASSERT_FALSE(Err);
  946. std::string Bytes(OutStrm.str());
  947. DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize);
  948. llvm::Expected<Header> Decoded = Header::decode(Data);
  949. // Make sure decoding succeeded.
  950. ASSERT_TRUE((bool)Decoded);
  951. EXPECT_EQ(H, Decoded.get());
  952. }
  953. TEST(GSYMTest, TestHeaderEncodeDecode) {
  954. Header H;
  955. InitHeader(H);
  956. TestHeaderEncodeDecode(H, llvm::support::little);
  957. TestHeaderEncodeDecode(H, llvm::support::big);
  958. }
  959. static void TestGsymCreatorEncodeError(llvm::support::endianness ByteOrder,
  960. const GsymCreator &GC,
  961. std::string ExpectedErrorMsg) {
  962. SmallString<512> Str;
  963. raw_svector_ostream OutStrm(Str);
  964. FileWriter FW(OutStrm, ByteOrder);
  965. llvm::Error Err = GC.encode(FW);
  966. ASSERT_TRUE(bool(Err));
  967. checkError(ExpectedErrorMsg, std::move(Err));
  968. }
  969. TEST(GSYMTest, TestGsymCreatorEncodeErrors) {
  970. const uint8_t ValidUUID[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
  971. 14, 15, 16};
  972. const uint8_t InvalidUUID[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
  973. 14, 15, 16, 17, 18, 19, 20, 21};
  974. // Verify we get an error when trying to encode an GsymCreator with no
  975. // function infos. We shouldn't be saving a GSYM file in this case since
  976. // there is nothing inside of it.
  977. GsymCreator GC;
  978. TestGsymCreatorEncodeError(llvm::support::little, GC,
  979. "no functions to encode");
  980. const uint64_t FuncAddr = 0x1000;
  981. const uint64_t FuncSize = 0x100;
  982. const uint32_t FuncName = GC.insertString("foo");
  983. // Verify we get an error trying to encode a GsymCreator that isn't
  984. // finalized.
  985. GC.addFunctionInfo(FunctionInfo(FuncAddr, FuncSize, FuncName));
  986. TestGsymCreatorEncodeError(llvm::support::little, GC,
  987. "GsymCreator wasn't finalized prior to encoding");
  988. std::string finalizeIssues;
  989. raw_string_ostream OS(finalizeIssues);
  990. llvm::Error finalizeErr = GC.finalize(OS);
  991. ASSERT_FALSE(bool(finalizeErr));
  992. finalizeErr = GC.finalize(OS);
  993. ASSERT_TRUE(bool(finalizeErr));
  994. checkError("already finalized", std::move(finalizeErr));
  995. // Verify we get an error trying to encode a GsymCreator with a UUID that is
  996. // too long.
  997. GC.setUUID(InvalidUUID);
  998. TestGsymCreatorEncodeError(llvm::support::little, GC,
  999. "invalid UUID size 21");
  1000. GC.setUUID(ValidUUID);
  1001. // Verify errors are propagated when we try to encoding an invalid line
  1002. // table.
  1003. GC.forEachFunctionInfo([](FunctionInfo &FI) -> bool {
  1004. FI.OptLineTable = LineTable(); // Invalid line table.
  1005. return false; // Stop iterating
  1006. });
  1007. TestGsymCreatorEncodeError(llvm::support::little, GC,
  1008. "attempted to encode invalid LineTable object");
  1009. // Verify errors are propagated when we try to encoding an invalid inline
  1010. // info.
  1011. GC.forEachFunctionInfo([](FunctionInfo &FI) -> bool {
  1012. FI.OptLineTable = llvm::None;
  1013. FI.Inline = InlineInfo(); // Invalid InlineInfo.
  1014. return false; // Stop iterating
  1015. });
  1016. TestGsymCreatorEncodeError(llvm::support::little, GC,
  1017. "attempted to encode invalid InlineInfo object");
  1018. }
  1019. static void Compare(const GsymCreator &GC, const GsymReader &GR) {
  1020. // Verify that all of the data in a GsymCreator is correctly decoded from
  1021. // a GsymReader. To do this, we iterator over
  1022. GC.forEachFunctionInfo([&](const FunctionInfo &FI) -> bool {
  1023. auto DecodedFI = GR.getFunctionInfo(FI.Range.Start);
  1024. EXPECT_TRUE(bool(DecodedFI));
  1025. EXPECT_EQ(FI, *DecodedFI);
  1026. return true; // Keep iterating over all FunctionInfo objects.
  1027. });
  1028. }
  1029. static void TestEncodeDecode(const GsymCreator &GC,
  1030. support::endianness ByteOrder, uint16_t Version,
  1031. uint8_t AddrOffSize, uint64_t BaseAddress,
  1032. uint32_t NumAddresses, ArrayRef<uint8_t> UUID) {
  1033. SmallString<512> Str;
  1034. raw_svector_ostream OutStrm(Str);
  1035. FileWriter FW(OutStrm, ByteOrder);
  1036. llvm::Error Err = GC.encode(FW);
  1037. ASSERT_FALSE((bool)Err);
  1038. Expected<GsymReader> GR = GsymReader::copyBuffer(OutStrm.str());
  1039. ASSERT_TRUE(bool(GR));
  1040. const Header &Hdr = GR->getHeader();
  1041. EXPECT_EQ(Hdr.Version, Version);
  1042. EXPECT_EQ(Hdr.AddrOffSize, AddrOffSize);
  1043. EXPECT_EQ(Hdr.UUIDSize, UUID.size());
  1044. EXPECT_EQ(Hdr.BaseAddress, BaseAddress);
  1045. EXPECT_EQ(Hdr.NumAddresses, NumAddresses);
  1046. EXPECT_EQ(ArrayRef<uint8_t>(Hdr.UUID, Hdr.UUIDSize), UUID);
  1047. Compare(GC, GR.get());
  1048. }
  1049. TEST(GSYMTest, TestGsymCreator1ByteAddrOffsets) {
  1050. uint8_t UUID[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
  1051. GsymCreator GC;
  1052. GC.setUUID(UUID);
  1053. constexpr uint64_t BaseAddr = 0x1000;
  1054. constexpr uint8_t AddrOffSize = 1;
  1055. const uint32_t Func1Name = GC.insertString("foo");
  1056. const uint32_t Func2Name = GC.insertString("bar");
  1057. GC.addFunctionInfo(FunctionInfo(BaseAddr+0x00, 0x10, Func1Name));
  1058. GC.addFunctionInfo(FunctionInfo(BaseAddr+0x20, 0x10, Func2Name));
  1059. Error Err = GC.finalize(llvm::nulls());
  1060. ASSERT_FALSE(Err);
  1061. TestEncodeDecode(GC, llvm::support::little,
  1062. GSYM_VERSION,
  1063. AddrOffSize,
  1064. BaseAddr,
  1065. 2, // NumAddresses
  1066. ArrayRef<uint8_t>(UUID));
  1067. TestEncodeDecode(GC, llvm::support::big,
  1068. GSYM_VERSION,
  1069. AddrOffSize,
  1070. BaseAddr,
  1071. 2, // NumAddresses
  1072. ArrayRef<uint8_t>(UUID));
  1073. }
  1074. TEST(GSYMTest, TestGsymCreator2ByteAddrOffsets) {
  1075. uint8_t UUID[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
  1076. GsymCreator GC;
  1077. GC.setUUID(UUID);
  1078. constexpr uint64_t BaseAddr = 0x1000;
  1079. constexpr uint8_t AddrOffSize = 2;
  1080. const uint32_t Func1Name = GC.insertString("foo");
  1081. const uint32_t Func2Name = GC.insertString("bar");
  1082. GC.addFunctionInfo(FunctionInfo(BaseAddr+0x000, 0x100, Func1Name));
  1083. GC.addFunctionInfo(FunctionInfo(BaseAddr+0x200, 0x100, Func2Name));
  1084. Error Err = GC.finalize(llvm::nulls());
  1085. ASSERT_FALSE(Err);
  1086. TestEncodeDecode(GC, llvm::support::little,
  1087. GSYM_VERSION,
  1088. AddrOffSize,
  1089. BaseAddr,
  1090. 2, // NumAddresses
  1091. ArrayRef<uint8_t>(UUID));
  1092. TestEncodeDecode(GC, llvm::support::big,
  1093. GSYM_VERSION,
  1094. AddrOffSize,
  1095. BaseAddr,
  1096. 2, // NumAddresses
  1097. ArrayRef<uint8_t>(UUID));
  1098. }
  1099. TEST(GSYMTest, TestGsymCreator4ByteAddrOffsets) {
  1100. uint8_t UUID[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
  1101. GsymCreator GC;
  1102. GC.setUUID(UUID);
  1103. constexpr uint64_t BaseAddr = 0x1000;
  1104. constexpr uint8_t AddrOffSize = 4;
  1105. const uint32_t Func1Name = GC.insertString("foo");
  1106. const uint32_t Func2Name = GC.insertString("bar");
  1107. GC.addFunctionInfo(FunctionInfo(BaseAddr+0x000, 0x100, Func1Name));
  1108. GC.addFunctionInfo(FunctionInfo(BaseAddr+0x20000, 0x100, Func2Name));
  1109. Error Err = GC.finalize(llvm::nulls());
  1110. ASSERT_FALSE(Err);
  1111. TestEncodeDecode(GC, llvm::support::little,
  1112. GSYM_VERSION,
  1113. AddrOffSize,
  1114. BaseAddr,
  1115. 2, // NumAddresses
  1116. ArrayRef<uint8_t>(UUID));
  1117. TestEncodeDecode(GC, llvm::support::big,
  1118. GSYM_VERSION,
  1119. AddrOffSize,
  1120. BaseAddr,
  1121. 2, // NumAddresses
  1122. ArrayRef<uint8_t>(UUID));
  1123. }
  1124. TEST(GSYMTest, TestGsymCreator8ByteAddrOffsets) {
  1125. uint8_t UUID[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
  1126. GsymCreator GC;
  1127. GC.setUUID(UUID);
  1128. constexpr uint64_t BaseAddr = 0x1000;
  1129. constexpr uint8_t AddrOffSize = 8;
  1130. const uint32_t Func1Name = GC.insertString("foo");
  1131. const uint32_t Func2Name = GC.insertString("bar");
  1132. GC.addFunctionInfo(FunctionInfo(BaseAddr+0x000, 0x100, Func1Name));
  1133. GC.addFunctionInfo(FunctionInfo(BaseAddr+0x100000000, 0x100, Func2Name));
  1134. Error Err = GC.finalize(llvm::nulls());
  1135. ASSERT_FALSE(Err);
  1136. TestEncodeDecode(GC, llvm::support::little,
  1137. GSYM_VERSION,
  1138. AddrOffSize,
  1139. BaseAddr,
  1140. 2, // NumAddresses
  1141. ArrayRef<uint8_t>(UUID));
  1142. TestEncodeDecode(GC, llvm::support::big,
  1143. GSYM_VERSION,
  1144. AddrOffSize,
  1145. BaseAddr,
  1146. 2, // NumAddresses
  1147. ArrayRef<uint8_t>(UUID));
  1148. }
  1149. static void VerifyFunctionInfo(const GsymReader &GR, uint64_t Addr,
  1150. const FunctionInfo &FI) {
  1151. auto ExpFI = GR.getFunctionInfo(Addr);
  1152. ASSERT_TRUE(bool(ExpFI));
  1153. ASSERT_EQ(FI, ExpFI.get());
  1154. }
  1155. static void VerifyFunctionInfoError(const GsymReader &GR, uint64_t Addr,
  1156. std::string ErrMessage) {
  1157. auto ExpFI = GR.getFunctionInfo(Addr);
  1158. ASSERT_FALSE(bool(ExpFI));
  1159. checkError(ErrMessage, ExpFI.takeError());
  1160. }
  1161. TEST(GSYMTest, TestGsymReader) {
  1162. uint8_t UUID[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
  1163. GsymCreator GC;
  1164. GC.setUUID(UUID);
  1165. constexpr uint64_t BaseAddr = 0x1000;
  1166. constexpr uint64_t Func1Addr = BaseAddr;
  1167. constexpr uint64_t Func2Addr = BaseAddr+0x20;
  1168. constexpr uint64_t FuncSize = 0x10;
  1169. const uint32_t Func1Name = GC.insertString("foo");
  1170. const uint32_t Func2Name = GC.insertString("bar");
  1171. const auto ByteOrder = support::endian::system_endianness();
  1172. GC.addFunctionInfo(FunctionInfo(Func1Addr, FuncSize, Func1Name));
  1173. GC.addFunctionInfo(FunctionInfo(Func2Addr, FuncSize, Func2Name));
  1174. Error FinalizeErr = GC.finalize(llvm::nulls());
  1175. ASSERT_FALSE(FinalizeErr);
  1176. SmallString<512> Str;
  1177. raw_svector_ostream OutStrm(Str);
  1178. FileWriter FW(OutStrm, ByteOrder);
  1179. llvm::Error Err = GC.encode(FW);
  1180. ASSERT_FALSE((bool)Err);
  1181. if (auto ExpectedGR = GsymReader::copyBuffer(OutStrm.str())) {
  1182. const GsymReader &GR = ExpectedGR.get();
  1183. VerifyFunctionInfoError(GR, Func1Addr-1, "address 0xfff not in GSYM");
  1184. FunctionInfo Func1(Func1Addr, FuncSize, Func1Name);
  1185. VerifyFunctionInfo(GR, Func1Addr, Func1);
  1186. VerifyFunctionInfo(GR, Func1Addr+1, Func1);
  1187. VerifyFunctionInfo(GR, Func1Addr+FuncSize-1, Func1);
  1188. VerifyFunctionInfoError(GR, Func1Addr+FuncSize,
  1189. "address 0x1010 not in GSYM");
  1190. VerifyFunctionInfoError(GR, Func2Addr-1, "address 0x101f not in GSYM");
  1191. FunctionInfo Func2(Func2Addr, FuncSize, Func2Name);
  1192. VerifyFunctionInfo(GR, Func2Addr, Func2);
  1193. VerifyFunctionInfo(GR, Func2Addr+1, Func2);
  1194. VerifyFunctionInfo(GR, Func2Addr+FuncSize-1, Func2);
  1195. VerifyFunctionInfoError(GR, Func2Addr+FuncSize,
  1196. "address 0x1030 not in GSYM");
  1197. }
  1198. }