1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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_processor.h"
16
17 #include <cinttypes>
18 #include <cstring>
19 #include <fcntl.h>
20 #include <memory>
21 #include <unistd.h>
22 #include "printk_formats_processor.h"
23 #include "securec.h"
24
25 namespace {
26 constexpr uint32_t LOCDATA_LENGTH_SHIFT = 16;
27 constexpr uint32_t LOCDATA_OFFSET_MASK = 0xffff;
28 constexpr uint32_t LOCDATA_LENGTH_MASK = 0xffff;
29
HandleString(const uint8_t * startPos,const uint8_t * endPos,int size)30 std::string HandleString(const uint8_t *startPos, const uint8_t *endPos, int size)
31 {
32 TS_CHECK_TRUE_RET(endPos - startPos >= static_cast<ptrdiff_t>(size), "");
33 std::string curStr;
34 const uint8_t *curCursor = startPos;
35 const uint8_t *sectionEnd = startPos + size;
36 while (*curCursor && curCursor < sectionEnd) {
37 curCursor++;
38 }
39 curStr.assign(startPos, curCursor);
40 return curStr;
41 }
42 } // namespace
43
44 namespace SysTuning {
45 namespace TraceStreamer {
HandleTypeData(const uint8_t * startPos,const uint8_t * endPos,void * out,size_t size)46 bool FtraceFieldProcessor::HandleTypeData(const uint8_t *startPos, const uint8_t *endPos, void *out, size_t size)
47 {
48 ptrdiff_t memSize = endPos - startPos;
49 TS_CHECK_TRUE_RET(memSize >= static_cast<ptrdiff_t>(size), false);
50 TS_CHECK_TRUE(memcpy_s(out, size, startPos, size) == EOK, false, "copy %zu byte to memory region [%p, %p) FAILED!",
51 size, startPos, endPos);
52 return true;
53 }
54
HandleStrField(const FieldFormat & format,uint8_t data[],size_t size)55 std::string FtraceFieldProcessor::HandleStrField(const FieldFormat &format, uint8_t data[], size_t size)
56 {
57 TS_CHECK_TRUE_RET((format.offset + format.size) <= size, "");
58 std::string curStr;
59 uint8_t *startPos = data + format.offset;
60 uint8_t *endPos = data + size;
61 size_t curStrSize = 0;
62 uint64_t curStrPtr = 0;
63 uint32_t curLocData = 0;
64 uint32_t curDataOffset = 0;
65 uint32_t curDataLength = 0;
66
67 switch (format.filedType) {
68 case FIELD_TYPE_FIXEDCSTRING:
69 curStr = HandleString(startPos, endPos, format.size);
70 break;
71 case FIELD_TYPE_CSTRING:
72 curStrSize = format.size;
73 if (curStrSize == 0) {
74 curStrSize = endPos - startPos;
75 curStr = HandleString(startPos, endPos, curStrSize);
76 } else {
77 curStr = HandleString(startPos, endPos, curStrSize);
78 }
79 break;
80 case FIELD_TYPE_STRINGPTR:
81 curStrSize = std::min(static_cast<size_t>(format.size), sizeof(curStrPtr));
82 if (memcpy_s(&curStrPtr, sizeof(curStrPtr), startPos, curStrSize) != EOK) {
83 TS_LOGE("parse STRINGPTR at %" PRIx64 " with %zu size FAILED!", curStrPtr, curStrSize);
84 return "";
85 }
86 curStr = PrintkFormatsProcessor::GetInstance().GetSymbol(curStrPtr);
87 break;
88 case FIELD_TYPE_DATALOC:
89 curLocData = 0;
90 HandleTypeData(startPos, endPos, &curLocData, sizeof(curLocData));
91 curDataOffset = curLocData & LOCDATA_OFFSET_MASK;
92 curDataLength = (curLocData >> LOCDATA_LENGTH_SHIFT) & LOCDATA_LENGTH_MASK;
93 if (curDataOffset > 0 && data + curDataOffset + curDataLength <= endPos) {
94 curStr = HandleString(data + curDataOffset, endPos, curDataLength);
95 }
96 break;
97 default:
98 break;
99 }
100 return curStr;
101 }
102 } // namespace TraceStreamer
103 } // namespace SysTuning
104