• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <iostream>
17 #include <regex>
18 #include <string>
19 
20 #include <gtest/gtest.h>
21 #include "disassembler.h"
22 #include "assembly-parser.h"
23 
ExtractFuncBody(const std::string & text,const std::string & header)24 static inline std::string ExtractFuncBody(const std::string &text, const std::string &header)
25 {
26     auto beg = text.find(header);
27     auto end = text.find('}', beg);
28 
29     ASSERT(beg != std::string::npos);
30     ASSERT(end != std::string::npos);
31 
32     return text.substr(beg + header.length(), end - (beg + header.length()));
33 }
34 
35 namespace ark::disasm::test {
36 
TEST(TestDebugInfo,TestDebugInfo)37 TEST(TestDebugInfo, TestDebugInfo)
38 {
39     auto program = ark::pandasm::Parser().Parse(R"(
40 .record A {
41     u1 fld
42 }
43 
44 .function A A.init() {
45     newobj v0, A
46     lda.obj v0
47 
48     return.obj
49 }
50 
51 .function u1 g() {
52     mov v0, v1
53     mov.64 v2, v3
54     mov.obj v4, v5
55 
56     movi v0, -1
57     movi.64 v0, 2
58     fmovi.64 v0, 3.01
59 
60     lda v1
61     lda.64 v0
62     lda.obj v1
63 }
64     )");
65     ASSERT(program);
66     auto pf = ark::pandasm::AsmEmitter::Emit(program.Value());
67     ASSERT(pf);
68 
69     ark::disasm::Disassembler d {};
70     std::stringstream ss {};
71 
72     d.Disassemble(pf);
73     d.CollectInfo();
74     d.Serialize(ss, true, true);
75 
76     std::string bodyG = ExtractFuncBody(ss.str(), "g() <static> {");
77 
78     ASSERT_NE(bodyG.find("#   LINE_NUMBER_TABLE:"), std::string::npos);
79     ASSERT_NE(bodyG.find("#\tline 14: 0\n"), std::string::npos);
80 
81     size_t codeStart = bodyG.find("#   CODE:\n");
82     ASSERT_NE(codeStart, std::string::npos) << "Code section in function g not found";
83     size_t codeEnd = bodyG.find("\n\n");  // First gap in function body is code section end
84     ASSERT_NE(codeEnd, std::string::npos) << "Gap after code section in function g not found";
85     ASSERT_LT(codeStart, codeEnd);
86     std::string instructions =
87         bodyG.substr(codeStart + strlen("#   CODE:\n"), codeEnd + 1 - (codeStart + strlen("#   CODE:\n")));
88 
89     std::regex const instRegex("# offset: ");
90     std::ptrdiff_t const instructionCount(std::distance(
91         std::sregex_iterator(instructions.begin(), instructions.end(), instRegex), std::sregex_iterator()));
92 
93     const ark::disasm::ProgInfo &progInfo = d.GetProgInfo();
94     auto gIt = progInfo.methodsStaticInfo.find("g:()");
95     ASSERT_NE(gIt, progInfo.methodsStaticInfo.end());
96     // In case of pandasm the table should contain entry on each instruction
97     ASSERT_EQ(gIt->second.lineNumberTable.size(), instructionCount);
98 
99     // There should be no local variables for panda assembler
100     ASSERT_EQ(bodyG.find("#   LOCAL_VARIABLE_TABLE:"), std::string::npos);
101 }
102 
103 }  // namespace ark::disasm::test
104