memory.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*############################################################################
  2. # Copyright 2016-2017 Intel Corporation
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. ############################################################################*/
  16. /*!
  17. * \file
  18. * \brief Memory access implementation.
  19. */
  20. #include "epid/common/src/memory.h"
  21. #include <stdint.h>
  22. #include <string.h>
  23. /// Maximum size of the destination buffer
  24. #ifndef RSIZE_MAX
  25. #define RSIZE_MAX ((SIZE_MAX) >> 1)
  26. #endif
  27. #ifndef MIN
  28. /// Evaluate to minimum of two values
  29. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  30. #endif // MIN
  31. /// Copies count of character from dest to src
  32. /*! \note Implementation follows C11 memcpy_s but with checks always enabled
  33. */
  34. int memcpy_S(void* dest, size_t destsz, void const* src, size_t count) {
  35. size_t i;
  36. if (!dest || destsz > RSIZE_MAX) return -1;
  37. if (!src || count > RSIZE_MAX || count > destsz ||
  38. count > (dest > src ? ((uintptr_t)dest - (uintptr_t)src)
  39. : ((uintptr_t)src - (uintptr_t)dest))) {
  40. // zero out dest if error detected
  41. memset(dest, 0, destsz);
  42. return -1;
  43. }
  44. for (i = 0; i < count; i++) ((uint8_t*)dest)[i] = ((uint8_t*)src)[i];
  45. return 0;
  46. }
  47. void EpidZeroMemory(void* ptr, size_t size) { memset(ptr, 0, size); }
  48. #if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  49. #if !defined(EPID_ALLOC_ALIGN)
  50. /// Alignment constant for EpidAlloc, must be a power of two
  51. #define EPID_ALLOC_ALIGN sizeof(size_t)
  52. #endif // !defined(EPID_ALLOC_ALIGN)
  53. #pragma pack(1)
  54. /// Allocated memory block information
  55. typedef struct EpidAllocHeader {
  56. size_t length; ///< number of bytes memory block is allocated for
  57. void* ptr; ///< pointer to whole memory block including EpidAllocHeader
  58. } EpidAllocHeader;
  59. #pragma pack()
  60. #endif // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  61. void* EpidAlloc(size_t size) {
  62. #if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  63. void* ptr = NULL;
  64. if (size <= 0) return NULL;
  65. // Allocate memory enough to store size bytes and EpidAllocHeader
  66. ptr = calloc(1, size + EPID_ALLOC_ALIGN - 1 + sizeof(EpidAllocHeader));
  67. if (ptr) {
  68. void* aligned_pointer = (void*)(((uintptr_t)ptr + EPID_ALLOC_ALIGN +
  69. sizeof(EpidAllocHeader) - 1) &
  70. (~(EPID_ALLOC_ALIGN - 1)));
  71. ((EpidAllocHeader*)aligned_pointer)[-1].length = size;
  72. ((EpidAllocHeader*)aligned_pointer)[-1].ptr = ptr;
  73. return aligned_pointer;
  74. }
  75. return NULL;
  76. #else // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  77. return calloc(1, size);
  78. #endif // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  79. }
  80. void* EpidRealloc(void* ptr, size_t new_size) {
  81. #if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  82. void* new_ptr = EpidAlloc(new_size);
  83. if (!new_ptr) return NULL;
  84. if (ptr) {
  85. // Memory copy is used to copy a buffer of variable length
  86. if (0 != memcpy_S(new_ptr, ((EpidAllocHeader*)new_ptr)[-1].length, ptr,
  87. MIN(((EpidAllocHeader*)ptr)[-1].length,
  88. ((EpidAllocHeader*)new_ptr)[-1].length))) {
  89. EpidFree(new_ptr);
  90. return NULL;
  91. }
  92. EpidFree(ptr);
  93. }
  94. return new_ptr;
  95. #else // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  96. return realloc(ptr, new_size);
  97. #endif // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  98. }
  99. void EpidFree(void* ptr) {
  100. #if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  101. if (ptr) {
  102. EpidZeroMemory(ptr, ((EpidAllocHeader*)ptr)[-1].length);
  103. free(((EpidAllocHeader*)ptr)[-1].ptr);
  104. }
  105. #else // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  106. free(ptr);
  107. #endif // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
  108. }