xref: /aosp_15_r20/trusty/kernel/lib/ubsan/ubsan_value.h (revision 344aa361028b423587d4ef3fa52a23d194628137)
1*344aa361SAndroid Build Coastguard Worker /*
2*344aa361SAndroid Build Coastguard Worker  * Copyright (c) 2019 Google Inc. All rights reserved
3*344aa361SAndroid Build Coastguard Worker  *
4*344aa361SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining
5*344aa361SAndroid Build Coastguard Worker  * a copy of this software and associated documentation files
6*344aa361SAndroid Build Coastguard Worker  * (the "Software"), to deal in the Software without restriction,
7*344aa361SAndroid Build Coastguard Worker  * including without limitation the rights to use, copy, modify, merge,
8*344aa361SAndroid Build Coastguard Worker  * publish, distribute, sublicense, and/or sell copies of the Software,
9*344aa361SAndroid Build Coastguard Worker  * and to permit persons to whom the Software is furnished to do so,
10*344aa361SAndroid Build Coastguard Worker  * subject to the following conditions:
11*344aa361SAndroid Build Coastguard Worker  *
12*344aa361SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be
13*344aa361SAndroid Build Coastguard Worker  * included in all copies or substantial portions of the Software.
14*344aa361SAndroid Build Coastguard Worker  *
15*344aa361SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*344aa361SAndroid Build Coastguard Worker  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*344aa361SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18*344aa361SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19*344aa361SAndroid Build Coastguard Worker  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20*344aa361SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21*344aa361SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*344aa361SAndroid Build Coastguard Worker  */
23*344aa361SAndroid Build Coastguard Worker 
24*344aa361SAndroid Build Coastguard Worker /*
25*344aa361SAndroid Build Coastguard Worker  * For reference, see LLVM's ubsan_value.h
26*344aa361SAndroid Build Coastguard Worker  * These structures and functions are used to access LLVM encoded UBSan
27*344aa361SAndroid Build Coastguard Worker  * values.
28*344aa361SAndroid Build Coastguard Worker  */
29*344aa361SAndroid Build Coastguard Worker #pragma once
30*344aa361SAndroid Build Coastguard Worker 
31*344aa361SAndroid Build Coastguard Worker #include <stdbool.h>
32*344aa361SAndroid Build Coastguard Worker #include <stddef.h>
33*344aa361SAndroid Build Coastguard Worker #include <stdint.h>
34*344aa361SAndroid Build Coastguard Worker 
35*344aa361SAndroid Build Coastguard Worker struct source_location {
36*344aa361SAndroid Build Coastguard Worker     const char* filename;
37*344aa361SAndroid Build Coastguard Worker     uint32_t line;
38*344aa361SAndroid Build Coastguard Worker     uint32_t column;
39*344aa361SAndroid Build Coastguard Worker };
40*344aa361SAndroid Build Coastguard Worker 
location_is_valid(struct source_location loc)41*344aa361SAndroid Build Coastguard Worker static inline bool location_is_valid(struct source_location loc) {
42*344aa361SAndroid Build Coastguard Worker     return !!loc.filename;
43*344aa361SAndroid Build Coastguard Worker }
44*344aa361SAndroid Build Coastguard Worker 
45*344aa361SAndroid Build Coastguard Worker struct type_descriptor {
46*344aa361SAndroid Build Coastguard Worker     uint16_t kind;
47*344aa361SAndroid Build Coastguard Worker     uint16_t info;
48*344aa361SAndroid Build Coastguard Worker     char name[];
49*344aa361SAndroid Build Coastguard Worker };
50*344aa361SAndroid Build Coastguard Worker 
51*344aa361SAndroid Build Coastguard Worker enum type_kind {
52*344aa361SAndroid Build Coastguard Worker     TYPE_KIND_INTEGER = 0x0,
53*344aa361SAndroid Build Coastguard Worker     TYPE_KIND_FLOAT = 0x1,
54*344aa361SAndroid Build Coastguard Worker     TYPE_KIND_UNKNOWN = 0xFFFF,
55*344aa361SAndroid Build Coastguard Worker };
56*344aa361SAndroid Build Coastguard Worker 
57*344aa361SAndroid Build Coastguard Worker typedef uintptr_t value_handle_t;
58*344aa361SAndroid Build Coastguard Worker //#define value_handle_t uintptr_t
59*344aa361SAndroid Build Coastguard Worker 
60*344aa361SAndroid Build Coastguard Worker struct value_t {
61*344aa361SAndroid Build Coastguard Worker     const struct type_descriptor* type;
62*344aa361SAndroid Build Coastguard Worker     value_handle_t val;
63*344aa361SAndroid Build Coastguard Worker };
64*344aa361SAndroid Build Coastguard Worker 
int_typeinfo_is_signed(uint16_t info)65*344aa361SAndroid Build Coastguard Worker static inline bool int_typeinfo_is_signed(uint16_t info) {
66*344aa361SAndroid Build Coastguard Worker     return info & 1;
67*344aa361SAndroid Build Coastguard Worker }
68*344aa361SAndroid Build Coastguard Worker 
int_typeinfo_width_bits(uint16_t info)69*344aa361SAndroid Build Coastguard Worker static inline size_t int_typeinfo_width_bits(uint16_t info) {
70*344aa361SAndroid Build Coastguard Worker     size_t shift = info >> 1;
71*344aa361SAndroid Build Coastguard Worker     return 1U << shift;
72*344aa361SAndroid Build Coastguard Worker }
73*344aa361SAndroid Build Coastguard Worker 
float_typeinfo_width_bits(uint16_t info)74*344aa361SAndroid Build Coastguard Worker static inline size_t float_typeinfo_width_bits(uint16_t info) {
75*344aa361SAndroid Build Coastguard Worker     return info;
76*344aa361SAndroid Build Coastguard Worker }
77*344aa361SAndroid Build Coastguard Worker 
type_is_integer(const struct type_descriptor * type)78*344aa361SAndroid Build Coastguard Worker static inline bool type_is_integer(const struct type_descriptor* type) {
79*344aa361SAndroid Build Coastguard Worker     return (enum type_kind)type->kind == TYPE_KIND_INTEGER;
80*344aa361SAndroid Build Coastguard Worker }
81*344aa361SAndroid Build Coastguard Worker 
type_is_float(const struct type_descriptor * type)82*344aa361SAndroid Build Coastguard Worker static inline bool type_is_float(const struct type_descriptor* type) {
83*344aa361SAndroid Build Coastguard Worker     return (enum type_kind)type->kind == TYPE_KIND_FLOAT;
84*344aa361SAndroid Build Coastguard Worker }
85*344aa361SAndroid Build Coastguard Worker 
type_width_bits(const struct type_descriptor * type)86*344aa361SAndroid Build Coastguard Worker static inline size_t type_width_bits(const struct type_descriptor* type) {
87*344aa361SAndroid Build Coastguard Worker     if (type_is_integer(type)) {
88*344aa361SAndroid Build Coastguard Worker         return int_typeinfo_width_bits(type->info);
89*344aa361SAndroid Build Coastguard Worker     } else {
90*344aa361SAndroid Build Coastguard Worker         return float_typeinfo_width_bits(type->info);
91*344aa361SAndroid Build Coastguard Worker     }
92*344aa361SAndroid Build Coastguard Worker }
93*344aa361SAndroid Build Coastguard Worker 
type_is_inline(const struct type_descriptor * type)94*344aa361SAndroid Build Coastguard Worker static inline bool type_is_inline(const struct type_descriptor* type) {
95*344aa361SAndroid Build Coastguard Worker     return type_width_bits(type) <= sizeof(value_handle_t) * 8;
96*344aa361SAndroid Build Coastguard Worker }
97*344aa361SAndroid Build Coastguard Worker 
type_is_signed_integer(const struct type_descriptor * type)98*344aa361SAndroid Build Coastguard Worker static inline bool type_is_signed_integer(const struct type_descriptor* type) {
99*344aa361SAndroid Build Coastguard Worker     return type_is_integer(type) && int_typeinfo_is_signed(type->info);
100*344aa361SAndroid Build Coastguard Worker }
101*344aa361SAndroid Build Coastguard Worker 
type_is_unsigned_integer(const struct type_descriptor * type)102*344aa361SAndroid Build Coastguard Worker static inline bool type_is_unsigned_integer(
103*344aa361SAndroid Build Coastguard Worker         const struct type_descriptor* type) {
104*344aa361SAndroid Build Coastguard Worker     return type_is_integer(type) && !int_typeinfo_is_signed(type->info);
105*344aa361SAndroid Build Coastguard Worker }
106