Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_tokenizer / tokenize.cc
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 // This file defines the functions that encode tokenized logs at runtime. These
16 // are the only pw_tokenizer functions present in a binary that tokenizes
17 // strings. All other tokenizing code is resolved at compile time.
18
19 #include "pw_tokenizer/tokenize.h"
20
21 #include <cstring>
22
23 #include "pw_tokenizer_private/encode_args.h"
24
25 namespace pw {
26 namespace tokenizer {
27 namespace {
28
29 // Store metadata about this compilation's string tokenization in the ELF.
30 //
31 // The tokenizer metadata will not go into the on-device executable binary code.
32 // This metadata will be present in the ELF file's .pw_tokenizer.info section,
33 // from which the host-side tooling (Python, Java, etc.) can understand how to
34 // decode tokenized strings for the given binary. Only attributes that affect
35 // the decoding process are recorded.
36 //
37 // Tokenizer metadata is stored in an array of key-value pairs. Each Metadata
38 // object is 32 bytes: a 24-byte string and an 8-byte value. Metadata structs
39 // may be parsed in Python with the struct format '24s<Q'.
40 PW_PACKED(struct) Metadata {
41   char name[24];   // name of the metadata field
42   uint64_t value;  // value of the field
43 };
44
45 static_assert(sizeof(Metadata) == 32);
46
47 // Store tokenization metadata in its own section. Mach-O files are not
48 // supported by pw_tokenizer, but a short, Mach-O compatible section name is
49 // used on macOS so that this file can at least compile.
50 #ifdef __APPLE__
51 #define PW_TOKENIZER_INFO_SECTION PW_KEEP_IN_SECTION(".pw_tokenizer")
52 #else
53 #define PW_TOKENIZER_INFO_SECTION PW_KEEP_IN_SECTION(".pw_tokenizer.info")
54 #endif  // __APPLE__
55
56 constexpr Metadata metadata[] PW_TOKENIZER_INFO_SECTION = {
57     {"hash_length_bytes", PW_TOKENIZER_CFG_C_HASH_LENGTH},
58     {"sizeof_long", sizeof(long)},            // %l conversion specifier
59     {"sizeof_intmax_t", sizeof(intmax_t)},    // %j conversion specifier
60     {"sizeof_size_t", sizeof(size_t)},        // %z conversion specifier
61     {"sizeof_ptrdiff_t", sizeof(ptrdiff_t)},  // %t conversion specifier
62 };
63
64 }  // namespace
65
66 extern "C" void _pw_tokenizer_ToBuffer(void* buffer,
67                                        size_t* buffer_size_bytes,
68                                        Token token,
69                                        _pw_tokenizer_ArgTypes types,
70                                        ...) {
71   if (*buffer_size_bytes < sizeof(token)) {
72     *buffer_size_bytes = 0;
73     return;
74   }
75
76   std::memcpy(buffer, &token, sizeof(token));
77
78   va_list args;
79   va_start(args, types);
80   const size_t encoded_bytes = EncodeArgs(
81       types,
82       args,
83       std::span<uint8_t>(static_cast<uint8_t*>(buffer) + sizeof(token),
84                          *buffer_size_bytes - sizeof(token)));
85   va_end(args);
86
87   *buffer_size_bytes = sizeof(token) + encoded_bytes;
88 }
89
90 extern "C" void _pw_tokenizer_ToCallback(
91     void (*callback)(const uint8_t* encoded_message, size_t size_bytes),
92     Token token,
93     _pw_tokenizer_ArgTypes types,
94     ...) {
95   EncodedMessage encoded;
96   encoded.token = token;
97
98   va_list args;
99   va_start(args, types);
100   const size_t encoded_bytes = EncodeArgs(types, args, encoded.args);
101   va_end(args);
102
103   callback(reinterpret_cast<const uint8_t*>(&encoded),
104            sizeof(encoded.token) + encoded_bytes);
105 }
106
107 }  // namespace tokenizer
108 }  // namespace pw