106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci#include "ftrace_field_parser.h" 1606f6ba60Sopenharmony_ci#include "logging.h" 1706f6ba60Sopenharmony_ci#include "printk_formats_parser.h" 1806f6ba60Sopenharmony_ci#include "securec.h" 1906f6ba60Sopenharmony_ci 2006f6ba60Sopenharmony_ci#include <cinttypes> 2106f6ba60Sopenharmony_ci#include <cstring> 2206f6ba60Sopenharmony_ci#include <fcntl.h> 2306f6ba60Sopenharmony_ci#include <memory> 2406f6ba60Sopenharmony_ci#include <unistd.h> 2506f6ba60Sopenharmony_ci 2606f6ba60Sopenharmony_ciFTRACE_NS_BEGIN 2706f6ba60Sopenharmony_cinamespace { 2806f6ba60Sopenharmony_ciconstexpr uint32_t DATALOC_OFFSET_MASK = 0xffff; 2906f6ba60Sopenharmony_ciconstexpr uint32_t DATALOC_LENGTH_MASK = 0xffff; 3006f6ba60Sopenharmony_ciconstexpr uint32_t DATALOC_LENGTH_SHIFT = 16; 3106f6ba60Sopenharmony_ci 3206f6ba60Sopenharmony_cistd::string ReadString(const uint8_t start[], const uint8_t end[], int size) 3306f6ba60Sopenharmony_ci{ 3406f6ba60Sopenharmony_ci std::string str; 3506f6ba60Sopenharmony_ci 3606f6ba60Sopenharmony_ci if (end - start < static_cast<ptrdiff_t>(size)) { 3706f6ba60Sopenharmony_ci return str; 3806f6ba60Sopenharmony_ci } 3906f6ba60Sopenharmony_ci 4006f6ba60Sopenharmony_ci const uint8_t* cursor = start; 4106f6ba60Sopenharmony_ci const uint8_t* sectionEnd = start + size; 4206f6ba60Sopenharmony_ci while (*cursor && cursor < sectionEnd) { 4306f6ba60Sopenharmony_ci cursor++; 4406f6ba60Sopenharmony_ci } 4506f6ba60Sopenharmony_ci 4606f6ba60Sopenharmony_ci str.assign(start, cursor); 4706f6ba60Sopenharmony_ci return str; 4806f6ba60Sopenharmony_ci} 4906f6ba60Sopenharmony_ci} // namespace 5006f6ba60Sopenharmony_ci 5106f6ba60Sopenharmony_cibool FtraceFieldParser::ReadData(const uint8_t start[], const uint8_t end[], void* out, size_t size) 5206f6ba60Sopenharmony_ci{ 5306f6ba60Sopenharmony_ci ptrdiff_t memSize = end - start; 5406f6ba60Sopenharmony_ci if (memSize < static_cast<ptrdiff_t>(size)) { 5506f6ba60Sopenharmony_ci return false; 5606f6ba60Sopenharmony_ci } 5706f6ba60Sopenharmony_ci 5806f6ba60Sopenharmony_ci CHECK_TRUE(memcpy_s(out, size, start, size) == EOK, false, "copy %zu byte to memory FAILED!", size); 5906f6ba60Sopenharmony_ci return true; 6006f6ba60Sopenharmony_ci} 6106f6ba60Sopenharmony_ci 6206f6ba60Sopenharmony_cistd::string FtraceFieldParser::ParseStrField(const FieldFormat& format, uint8_t data[], size_t size) 6306f6ba60Sopenharmony_ci{ 6406f6ba60Sopenharmony_ci std::string retval; 6506f6ba60Sopenharmony_ci if ((format.offset + format.size) > size) { 6606f6ba60Sopenharmony_ci return retval; 6706f6ba60Sopenharmony_ci } 6806f6ba60Sopenharmony_ci 6906f6ba60Sopenharmony_ci uint8_t* start = data + format.offset; 7006f6ba60Sopenharmony_ci uint8_t* end = data + size; 7106f6ba60Sopenharmony_ci size_t strSize = 0; 7206f6ba60Sopenharmony_ci uint64_t strPtr = 0; 7306f6ba60Sopenharmony_ci uint32_t dataLoc = 0; 7406f6ba60Sopenharmony_ci uint32_t dataOffset = 0; 7506f6ba60Sopenharmony_ci uint32_t dataLength = 0; 7606f6ba60Sopenharmony_ci 7706f6ba60Sopenharmony_ci switch (format.filedType) { 7806f6ba60Sopenharmony_ci case FIELD_TYPE_FIXEDCSTRING: 7906f6ba60Sopenharmony_ci retval = ReadString(start, end, format.size); 8006f6ba60Sopenharmony_ci break; 8106f6ba60Sopenharmony_ci case FIELD_TYPE_CSTRING: 8206f6ba60Sopenharmony_ci strSize = format.size; 8306f6ba60Sopenharmony_ci if (strSize == 0) { 8406f6ba60Sopenharmony_ci strSize = end - start; 8506f6ba60Sopenharmony_ci retval = ReadString(start, end, strSize); 8606f6ba60Sopenharmony_ci } else { 8706f6ba60Sopenharmony_ci retval = ReadString(start, end, strSize); 8806f6ba60Sopenharmony_ci } 8906f6ba60Sopenharmony_ci break; 9006f6ba60Sopenharmony_ci case FIELD_TYPE_STRINGPTR: 9106f6ba60Sopenharmony_ci strSize = std::min(static_cast<size_t>(format.size), sizeof(strPtr)); 9206f6ba60Sopenharmony_ci CHECK_TRUE(memcpy_s(&strPtr, sizeof(strPtr), start, strSize) == EOK, "", "parse STRINGPTR FAILED!"); 9306f6ba60Sopenharmony_ci retval = PrintkFormatsParser::GetInstance().GetSymbol(strPtr); 9406f6ba60Sopenharmony_ci break; 9506f6ba60Sopenharmony_ci case FIELD_TYPE_DATALOC: 9606f6ba60Sopenharmony_ci dataLoc = 0; 9706f6ba60Sopenharmony_ci ReadData(start, end, &dataLoc, sizeof(dataLoc)); 9806f6ba60Sopenharmony_ci dataOffset = dataLoc & DATALOC_OFFSET_MASK; 9906f6ba60Sopenharmony_ci dataLength = (dataLoc >> DATALOC_LENGTH_SHIFT) & DATALOC_LENGTH_MASK; 10006f6ba60Sopenharmony_ci if (dataOffset > 0 && data + dataOffset + dataLength <= end) { 10106f6ba60Sopenharmony_ci retval = ReadString(data + dataOffset, end, dataLength); 10206f6ba60Sopenharmony_ci } 10306f6ba60Sopenharmony_ci break; 10406f6ba60Sopenharmony_ci default: 10506f6ba60Sopenharmony_ci break; 10606f6ba60Sopenharmony_ci } 10706f6ba60Sopenharmony_ci return retval; 10806f6ba60Sopenharmony_ci} 10906f6ba60Sopenharmony_ciFTRACE_NS_END 110