diff --git a/Makefile b/Makefile index fa8e7593..a990a06a 100644 --- a/Makefile +++ b/Makefile @@ -723,7 +723,6 @@ TEST_NAMES = \ tests/rollback_index3_tests \ tests/sha_benchmark \ tests/utility_string_tests \ - tests/utility_tests \ tests/vboot_api_devmode_tests \ tests/vboot_api_kernel_tests \ tests/vboot_api_kernel2_tests \ @@ -1375,7 +1374,6 @@ ifeq (${TPM2_MODE},) endif ${RUNTEST} ${BUILD_RUN}/tests/rollback_index3_tests ${RUNTEST} ${BUILD_RUN}/tests/utility_string_tests - ${RUNTEST} ${BUILD_RUN}/tests/utility_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_devmode_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel2_tests diff --git a/firmware/2lib/2gbb.c b/firmware/2lib/2gbb.c index 8a7c57c5..c7f22564 100644 --- a/firmware/2lib/2gbb.c +++ b/firmware/2lib/2gbb.c @@ -39,8 +39,7 @@ static int vb2_gbb_read_key(struct vb2_context *ctx, /* Deal with a zero-size key (used in testing). */ *size = (*keyp)->key_offset + (*keyp)->key_size; - if (*size < sizeof(**keyp)) - *size = sizeof(**keyp); + *size = VB2_MAX(*size, sizeof(**keyp)); /* Now that we know the real size of the key, retrieve the key data, and write it on the workbuf, directly after vb2_packed_key. */ @@ -98,10 +97,8 @@ int vb2api_gbb_read_hwid(struct vb2_context *ctx, return VB2_ERROR_GBB_INVALID; } - if (*size > VB2_GBB_HWID_MAX_SIZE) - *size = VB2_GBB_HWID_MAX_SIZE; - if (*size > gbb->hwid_size) - *size = gbb->hwid_size; + *size = VB2_MIN(*size, VB2_GBB_HWID_MAX_SIZE); + *size = VB2_MIN(*size, gbb->hwid_size); ret = vb2ex_read_resource(ctx, VB2_RES_GBB, gbb->hwid_offset, hwid, *size); diff --git a/firmware/2lib/include/2common.h b/firmware/2lib/include/2common.h index 81f56df5..7cd8c041 100644 --- a/firmware/2lib/include/2common.h +++ b/firmware/2lib/include/2common.h @@ -18,12 +18,19 @@ struct vb2_public_key; /* - * Return the greater of A and B. This is used in macros which calculate the + * Return the min/max of A and B. This is used in macros which calculate the * required buffer size, so can't be turned into a static inline function. */ -#ifndef VB2_MAX -#define VB2_MAX(A, B) ((A) > (B) ? (A) : (B)) -#endif +#define VB2_MIN(a, b) ({ \ + typeof(a) __vb2_min_a = (a); \ + typeof(b) __vb2_min_b = (b); \ + __vb2_min_a < __vb2_min_b ? __vb2_min_a : __vb2_min_b; \ + }) +#define VB2_MAX(a, b) ({ \ + typeof(a) __vb2_max_a = (a); \ + typeof(b) __vb2_max_b = (b); \ + __vb2_max_a > __vb2_max_b ? __vb2_max_a : __vb2_max_b; \ + }) /* Return the number of elements in an array */ #ifndef ARRAY_SIZE diff --git a/firmware/lib/include/utility.h b/firmware/lib/include/utility.h index e5539751..10562a58 100644 --- a/firmware/lib/include/utility.h +++ b/firmware/lib/include/utility.h @@ -22,9 +22,6 @@ #define VbAssert(expr) #endif -/* Return the minimum of (a) or (b). */ -#define Min(a, b) (((a) < (b)) ? (a) : (b)) - /* * Buffer size required to hold the longest possible output of Uint64ToString() * - that is, Uint64ToString(~0, 2). diff --git a/futility/cmd_update.c b/futility/cmd_update.c index d64ed13a..abf1dcab 100644 --- a/futility/cmd_update.c +++ b/futility/cmd_update.c @@ -245,7 +245,7 @@ static int do_update(int argc, char *argv[]) STATUS("Starting firmware updater.\n"); r = update_firmware(cfg); if (r != UPDATE_ERR_DONE) { - r = Min(r, UPDATE_ERR_UNKNOWN); + r = VB2_MIN(r, UPDATE_ERR_UNKNOWN); ERROR("%s\n", updater_error_messages[r]); errorcnt++; } diff --git a/futility/updater.c b/futility/updater.c index 82ee4a44..ef142b8b 100644 --- a/futility/updater.c +++ b/futility/updater.c @@ -814,7 +814,7 @@ static int emulate_write_firmware(const char *filename, } if (!errorcnt) { - size_t to_write = Min(to.size, from.size); + size_t to_write = VB2_MIN(to.size, from.size); assert(from.data && to.data); VB2_DEBUG("Writing %zu bytes\n", to_write); @@ -949,7 +949,7 @@ int preserve_firmware_section(const struct firmware_image *image_from, FMAP_NAMELEN, section_name); } /* Use memmove in case if we need to deal with sections that overlap. */ - memmove(to.data, from.data, Min(from.size, to.size)); + memmove(to.data, from.data, VB2_MIN(from.size, to.size)); return 0; } diff --git a/tests/utility_tests.c b/tests/utility_tests.c deleted file mode 100644 index 5e22339f..00000000 --- a/tests/utility_tests.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Tests for utility functions - */ - -#include -#include -#include -#include - -#include "test_common.h" -#include "utility.h" -#include "vboot_common.h" - -/* Test utility.h and sysincludes.h macros */ -static void MacrosTest(void) -{ - int64_t a = -10, b = -20; - uint64_t u = (0xABCD00000000ULL); - uint64_t v = (0xABCD000000ULL); - - TEST_EQ(Min(1, 2), 1, "Min 1"); - TEST_EQ(Min(4, 3), 3, "Min 2"); - TEST_EQ(Min(5, 5), 5, "Min 5"); - TEST_EQ(Min(a, b), b, "Min uint64 1"); - TEST_EQ(Min(b, a), b, "Min uint64 2"); - TEST_EQ(Min(b, b), b, "Min uint64 same"); - - TEST_EQ(u >> 8, v, "uint64_t >> 8"); - TEST_EQ(u >> 0, u, "uint64_t >> 0"); - TEST_EQ(u >> 36, (uint64_t)0xABC, "uint64_t >> 36"); - - TEST_EQ(v * (uint32_t)0, 0, "uint64_t * uint32_t 0"); - TEST_EQ(v * (uint32_t)1, v, "uint64_t * uint32_t 1"); - TEST_EQ(v * (uint32_t)256, u, "uint64_t * uint32_t 256"); -} - -int main(int argc, char* argv[]) -{ - int error_code = 0; - - MacrosTest(); - - if (!gTestSuccess) - error_code = 255; - - return error_code; -} diff --git a/tests/vb2_common_tests.c b/tests/vb2_common_tests.c index 2b44233b..13a408ea 100644 --- a/tests/vb2_common_tests.c +++ b/tests/vb2_common_tests.c @@ -10,6 +10,56 @@ #include "test_common.h" #include "vboot_struct.h" /* For old struct sizes */ +/* Mock data */ +static int counter_calls_left = 0; + +/* Mock functions */ +static int counter(void) +{ + counter_calls_left--; + return 0; +} + +/* + * Test arithmetic-related macros and operators. + */ +static void test_arithmetic(void) +{ + int64_t a = -10, b = -20; + uint64_t u = (0xabcd00000000ULL); + uint64_t v = (0xabcd000000ULL); + + TEST_EQ(VB2_MIN(1, 2), 1, "MIN 1"); + TEST_EQ(VB2_MIN(4, 3), 3, "MIN 3"); + TEST_EQ(VB2_MIN(5, 5), 5, "MIN 5"); + TEST_EQ(VB2_MIN(a, b), b, "MIN uint64 1"); + TEST_EQ(VB2_MIN(b, a), b, "MIN uint64 2"); + TEST_EQ(VB2_MIN(b, b), b, "MIN uint64 same"); + + counter_calls_left = 2; + VB2_MIN(counter(), counter()); + TEST_EQ(counter_calls_left, 0, "MIN double-evaluation"); + + TEST_EQ(VB2_MAX(1, 2), 2, "MAX 2"); + TEST_EQ(VB2_MAX(4, 3), 4, "MAX 4"); + TEST_EQ(VB2_MAX(5, 5), 5, "MAX 5"); + TEST_EQ(VB2_MAX(a, b), a, "MAX uint64 1"); + TEST_EQ(VB2_MAX(b, a), a, "MAX uint64 2"); + TEST_EQ(VB2_MAX(b, b), b, "MAX uint64 same"); + + counter_calls_left = 2; + VB2_MAX(counter(), counter()); + TEST_EQ(counter_calls_left, 0, "MAX double-evaluation"); + + TEST_EQ(u >> 8, v, "uint64_t >> 8"); + TEST_EQ(u >> 0, u, "uint64_t >> 0"); + TEST_EQ(u >> 36, (uint64_t)0xabc, "uint64_t >> 36"); + + TEST_EQ(v * (uint32_t)0, 0, "uint64_t * uint32_t 0"); + TEST_EQ(v * (uint32_t)1, v, "uint64_t * uint32_t 1"); + TEST_EQ(v * (uint32_t)256, u, "uint64_t * uint32_t 256"); +} + /* * Test array size macro. */ @@ -232,6 +282,7 @@ static void test_helper_functions(void) int main(int argc, char* argv[]) { + test_arithmetic(); test_array_size(); test_struct_packing(); test_memcmp();