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