1/* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. 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_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 26FTRACE_NS_BEGIN 27namespace { 28constexpr uint32_t DATALOC_OFFSET_MASK = 0xffff; 29constexpr uint32_t DATALOC_LENGTH_MASK = 0xffff; 30constexpr uint32_t DATALOC_LENGTH_SHIFT = 16; 31 32std::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 51bool 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 CHECK_TRUE(memcpy_s(out, size, start, size) == EOK, false, "copy %zu byte to memory FAILED!", size); 59 return true; 60} 61 62std::string FtraceFieldParser::ParseStrField(const FieldFormat& format, uint8_t data[], size_t size) 63{ 64 std::string retval; 65 if ((format.offset + format.size) > size) { 66 return retval; 67 } 68 69 uint8_t* start = data + format.offset; 70 uint8_t* end = data + size; 71 size_t strSize = 0; 72 uint64_t strPtr = 0; 73 uint32_t dataLoc = 0; 74 uint32_t dataOffset = 0; 75 uint32_t dataLength = 0; 76 77 switch (format.filedType) { 78 case FIELD_TYPE_FIXEDCSTRING: 79 retval = ReadString(start, end, format.size); 80 break; 81 case FIELD_TYPE_CSTRING: 82 strSize = format.size; 83 if (strSize == 0) { 84 strSize = end - start; 85 retval = ReadString(start, end, strSize); 86 } else { 87 retval = ReadString(start, end, strSize); 88 } 89 break; 90 case FIELD_TYPE_STRINGPTR: 91 strSize = std::min(static_cast<size_t>(format.size), sizeof(strPtr)); 92 CHECK_TRUE(memcpy_s(&strPtr, sizeof(strPtr), start, strSize) == EOK, "", "parse STRINGPTR FAILED!"); 93 retval = PrintkFormatsParser::GetInstance().GetSymbol(strPtr); 94 break; 95 case FIELD_TYPE_DATALOC: 96 dataLoc = 0; 97 ReadData(start, end, &dataLoc, sizeof(dataLoc)); 98 dataOffset = dataLoc & DATALOC_OFFSET_MASK; 99 dataLength = (dataLoc >> DATALOC_LENGTH_SHIFT) & DATALOC_LENGTH_MASK; 100 if (dataOffset > 0 && data + dataOffset + dataLength <= end) { 101 retval = ReadString(data + dataOffset, end, dataLength); 102 } 103 break; 104 default: 105 break; 106 } 107 return retval; 108} 109FTRACE_NS_END 110