1 /*
2 * Copyright (c) 2021 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 #include "ftrace_field_parser.h"
16 #include "logging.h"
17 #include "printk_formats_parser.h"
18 #include "securec.h"
19
20 #include <cinttypes>
21 #include <cstring>
22 #include <fcntl.h>
23 #include <memory>
24 #include <unistd.h>
25
26 FTRACE_NS_BEGIN
27 namespace {
28 constexpr uint32_t DATALOC_OFFSET_MASK = 0xffff;
29 constexpr uint32_t DATALOC_LENGTH_MASK = 0xffff;
30 constexpr uint32_t DATALOC_LENGTH_SHIFT = 16;
31
ReadString(const uint8_t start[],const uint8_t end[],int size)32 std::string ReadString(const uint8_t start[], const uint8_t end[], int size)
33 {
34 std::string str;
35
36 if (end - start < static_cast<ptrdiff_t>(size)) {
37 return str;
38 }
39
40 const uint8_t* cursor = start;
41 const uint8_t* sectionEnd = start + size;
42 while (*cursor && cursor < sectionEnd) {
43 cursor++;
44 }
45
46 str.assign(start, cursor);
47 return str;
48 }
49 } // namespace
50
ReadData(const uint8_t start[],const uint8_t end[],void * out,size_t size)51 bool FtraceFieldParser::ReadData(const uint8_t start[], const uint8_t end[], void* out, size_t size)
52 {
53 ptrdiff_t memSize = end - start;
54 if (memSize < static_cast<ptrdiff_t>(size)) {
55 return false;
56 }
57
58 if (memcpy_s(out, size, start, size) != EOK) {
59 HILOG_ERROR(LOG_CORE, "copy %zu byte to memory region [%p, %p) FAILED!", size, start, end);
60 return false;
61 }
62 return true;
63 }
64
ParseStrField(const FieldFormat & format,uint8_t data[],size_t size)65 std::string FtraceFieldParser::ParseStrField(const FieldFormat& format, uint8_t data[], size_t size)
66 {
67 std::string retval;
68 if ((format.offset + format.size) > size) {
69 return retval;
70 }
71
72 uint8_t* start = data + format.offset;
73 uint8_t* end = data + size;
74 size_t strSize = 0;
75 uint64_t strPtr = 0;
76 uint32_t dataLoc = 0;
77 uint32_t dataOffset = 0;
78 uint32_t dataLength = 0;
79
80 switch (format.filedType) {
81 case FIELD_TYPE_FIXEDCSTRING:
82 retval = ReadString(start, end, format.size);
83 break;
84 case FIELD_TYPE_CSTRING:
85 strSize = format.size;
86 if (strSize == 0) {
87 strSize = end - start;
88 retval = ReadString(start, end, strSize);
89 } else {
90 retval = ReadString(start, end, strSize);
91 }
92 break;
93 case FIELD_TYPE_STRINGPTR:
94 strSize = std::min(static_cast<size_t>(format.size), sizeof(strPtr));
95 if (memcpy_s(&strPtr, sizeof(strPtr), start, strSize) != EOK) {
96 HILOG_ERROR(LOG_CORE, "parse STRINGPTR at %" PRIx64 " with %zu size FAILED!", strPtr, strSize);
97 return "";
98 }
99 retval = PrintkFormatsParser::GetInstance().GetSymbol(strPtr);
100 break;
101 case FIELD_TYPE_DATALOC:
102 dataLoc = 0;
103 ReadData(start, end, &dataLoc, sizeof(dataLoc));
104 dataOffset = dataLoc & DATALOC_OFFSET_MASK;
105 dataLength = (dataLoc >> DATALOC_LENGTH_SHIFT) & DATALOC_LENGTH_MASK;
106 if (dataOffset > 0 && data + dataOffset + dataLength <= end) {
107 retval = ReadString(data + dataOffset, end, dataLength);
108 }
109 break;
110 default:
111 break;
112 }
113 return retval;
114 }
115 FTRACE_NS_END
116