Asylo
primitive_status.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2019 Asylo authors
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef ASYLO_PLATFORM_PRIMITIVES_PRIMITIVE_STATUS_H_
20 #define ASYLO_PLATFORM_PRIMITIVES_PRIMITIVE_STATUS_H_
21 
22 #include <algorithm>
23 #include <cstddef>
24 #include <cstdint>
25 #include <cstring>
26 #include <string>
27 #include <type_traits>
28 
29 #include "asylo/util/error_codes.h" // IWYU pragma: export
30 
31 namespace asylo {
32 namespace primitives {
33 
34 // This file declares types shared between between trusted and untrusted code.
35 //
36 // Trusted and untrusted components may be built with different compilers and be
37 // linked against different implementations of the C++ runtime. In general,
38 // these versions are not binary compatible. For example:
39 //
40 // * Types with a virtual function table will be initialized differently
41 // depending on where they were initialized, and an object passed to trusted
42 // code from the untrusted application may try to invoke a untrusted code when
43 // a virtual method is called or visa-versa.
44 //
45 // * Types which do memory allocation in their destructor may attempt to free
46 // themselves from the wrong heap.
47 //
48 // * Types which depend on the implementation of standard types like std::string
49 // may have completely incompatible runtime representation.
50 //
51 // These requirements exist because enclave code is linked against our own
52 // custom C++ runtime. The are not related to SGX per se and hold even for the
53 // simulator and RPC implementations.
54 
55 // Ensure common width for implementation-defined types.
56 static_assert(sizeof(size_t) == 8, "Unexpected size for type size_t");
57 
58 /// \class PrimitiveStatus primitive_status.h @primitive_status
59 /// Shared representation of a status code across the enclave boundary.
60 ///
61 /// PrimitiveStatus does not include an error space and always refers to a
62 /// google::GoogleError value.
64  public:
65  /// Maximum error string length in characters.
66  static constexpr size_t kMessageMax = 1024;
67 
68  /// Builds an OK status.
70 
71  /// Builds a status with an error code and an empty message.
72  ///
73  /// \param code An error code that is interpreted as a google::GoogleError
74  /// value.
75  explicit PrimitiveStatus(int code) : error_code_(code) { message_[0] = '\0'; }
76 
77  /// Builds a status with an error code and error message.
78  ///
79  /// \param code An error code that is interpreted as a google::GoogleError
80  /// value.
81  /// \param message A message string that is truncated if longer than
82  /// `kMessageMax - 1` characters. The length is computed with strlen.
83  PrimitiveStatus(int code, const char *message)
85 
86  /// Builds a status with an error code and a message of size `message_size`.
87  ///
88  /// \param code An error code that is interpreted as a google::GoogleError
89  /// value.
90  /// \param message A message string that is truncated if longer than
91  /// `kMessageMax - 1` characters.
92  /// \param message_size The size of the `message` to copy, which will not
93  /// exceed `kMessageMax - 1` characters.
94  PrimitiveStatus(int code, const char *message, size_t message_size)
95  : error_code_(code) {
96  message_size = std::min(message_size, kMessageMax - 1);
97  memcpy(message_, message, message_size);
98  message_[message_size] = '\0';
99  }
100 
101  /// Builds a status with an error code and a message in string format.
102  PrimitiveStatus(int code, const std::string &message)
104 
105  /// Copy constructor.
106  ///
107  /// \param other The status to copy. Strings are memcpy'd.
110 
112  error_code_ = other.error_code_;
113  size_t size = std::min(strlen(other.message_), kMessageMax - 1);
114  memcpy(message_, other.message_, size);
115  message_[size] = '\0';
116  return *this;
117  }
118 
119  /// PrimitiveStatus::OkStatus() is the canonical name for an OK status.
120  /// \returns An OK status object.
122 
123  /// Getter for this object's error code.
124  ///
125  /// \returns The integer error code for this object.
126  int error_code() const { return error_code_; }
127 
128  /// Getter for this object's error message.
129  ///
130  /// returns The string error message for this object.
131  const char *error_message() const { return message_; }
132 
133  /// Predicate for non-error status.
134  ///
135  /// \returns True if and only if this object is OK (indicates no error).
136  bool ok() const { return error_code_ == error::GoogleError::OK; }
137 
138  private:
139  // This method is not intended to be called, it is defined only to provide a
140  // scope where offsetof may be applied to private members and PrimitiveStatus
141  // is a complete type.
142  static void CheckLayout() {
143  static_assert(std::is_standard_layout<PrimitiveStatus>::value,
144  "PrimitiveStatus must satisfy std::is_standard_layout");
145  static_assert(offsetof(PrimitiveStatus, error_code_) == 0x0,
146  "Unexpected layout for field PrimitiveStatus::error_code_");
147  static_assert(offsetof(PrimitiveStatus, message_) == sizeof(uint32_t),
148  "Unexpected layout for field PrimitiveStatus::message_");
149  }
150 
151  int32_t error_code_; // An error::GoogleError condition code.
152  char message_[kMessageMax]; // An associated error string.
153 };
154 
155 } // namespace primitives
156 } // namespace asylo
157 
158 #endif // ASYLO_PLATFORM_PRIMITIVES_PRIMITIVE_STATUS_H_
static constexpr size_t kMessageMax
Maximum error string length in characters.
Definition: primitive_status.h:66
const char * error_message() const
Getter for this object&#39;s error message.
Definition: primitive_status.h:131
PrimitiveStatus(int code, const char *message, size_t message_size)
Builds a status with an error code and a message of size message_size.
Definition: primitive_status.h:94
Shared representation of a status code across the enclave boundary.
Definition: primitive_status.h:63
PrimitiveStatus & operator=(const PrimitiveStatus &other)
Definition: primitive_status.h:111
int error_code() const
Getter for this object&#39;s error code.
Definition: primitive_status.h:126
ABSL_CONST_INIT const char kStatusMoveAssignmentMsg[]
PrimitiveStatus(int code, const std::string &message)
Builds a status with an error code and a message in string format.
Definition: primitive_status.h:102
static PrimitiveStatus OkStatus()
PrimitiveStatus::OkStatus() is the canonical name for an OK status.
Definition: primitive_status.h:121
bool ok() const
Predicate for non-error status.
Definition: primitive_status.h:136
PrimitiveStatus(int code)
Builds a status with an error code and an empty message.
Definition: primitive_status.h:75
PrimitiveStatus(const PrimitiveStatus &other)
Copy constructor.
Definition: primitive_status.h:108
PrimitiveStatus(int code, const char *message)
Builds a status with an error code and error message.
Definition: primitive_status.h:83
PrimitiveStatus()
Builds an OK status.
Definition: primitive_status.h:69
Definition: extent.h:29