summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Green <evgreen@chromium.org>2019-08-01 11:20:14 -0700
committerCommit Bot <commit-bot@chromium.org>2019-10-05 00:47:41 +0000
commitb63e2a87a75dce8941d087c8736c5a35544ab3b0 (patch)
tree32a4bfe24554a38c6ad30dcb38911796d2acea50
parent60d66714d3b41d69942652650672fd5259815538 (diff)
downloadchrome-ec-b63e2a87a75dce8941d087c8736c5a35544ab3b0.tar.gz
printf: Convert %h to %ph
In order to make printf more standard, use %ph. Pass a pointer to a struct describing the buffer, including its size. Add a convenience macro so that conversion between the old style and new style is purely mechanical. The old style of %h cannot be converted directly to %ph as-is because the C standard doesn't allow flags, precision, or field width on %p. Ultimately the goal is to enable compile-time printf format checking. This gets us one step closer to that. BUG=chromium:984041 TEST=make -j buildall BRANCH=None Cq-Depend:chrome-internal:1559798,chrome-internal:1560598 Change-Id: I9c0ca124a048314c9b62d64bd55b36be55034e0e Signed-off-by: Evan Green <evgreen@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1730605
-rw-r--r--board/cr50/usb_spi.c4
-rw-r--r--chip/g/dcrypto/app_cipher.c6
-rw-r--r--chip/g/dcrypto/dcrypto_bn.c4
-rw-r--r--chip/g/dcrypto/hmac_drbg.c2
-rw-r--r--chip/g/loader/launch.c6
-rw-r--r--chip/g/loader/verify.c6
-rw-r--r--chip/it83xx/i2c_slave.c5
-rw-r--r--chip/stm32/trng.c2
-rw-r--r--common/ccd_config.c2
-rw-r--r--common/host_command.c12
-rw-r--r--common/i2c_master.c2
-rw-r--r--common/peci.c2
-rw-r--r--common/printf.c118
-rw-r--r--common/spi_commands.c2
-rw-r--r--common/vboot_hash.c4
-rw-r--r--driver/touchpad_st.c21
-rw-r--r--fuzz/host_command_fuzz.c4
-rw-r--r--include/console.h16
-rw-r--r--include/printf.h7
-rw-r--r--test/printf.c8
20 files changed, 139 insertions, 94 deletions
diff --git a/board/cr50/usb_spi.c b/board/cr50/usb_spi.c
index 9392bec8f7..66083de4b1 100644
--- a/board/cr50/usb_spi.c
+++ b/board/cr50/usb_spi.c
@@ -754,9 +754,9 @@ static int hash_command_wrapper(int argc, char *argv[])
rv = EC_SUCCESS;
if (req.subcmd == SPI_HASH_SUBCMD_DUMP)
- ccprintf("data: %.*h\n", req.size, p);
+ ccprintf("data: %ph\n", HEX_BUF(p, req.size));
else if (req.subcmd == SPI_HASH_SUBCMD_SHA256)
- ccprintf("hash: %.32h\n", p);
+ ccprintf("hash: %ph\n", HEX_BUF(p, 32));
}
return rv;
diff --git a/chip/g/dcrypto/app_cipher.c b/chip/g/dcrypto/app_cipher.c
index 2d95173c8f..e465598718 100644
--- a/chip/g/dcrypto/app_cipher.c
+++ b/chip/g/dcrypto/app_cipher.c
@@ -282,7 +282,7 @@ static int basic_check(struct test_info *pinfo)
int i;
uint32_t *p;
- ccprintf("original data %.16h\n", pinfo->p);
+ ccprintf("original data %ph\n", HEX_BUF(pinfo->p, 16));
half = (pinfo->test_blob_size/2) & ~3;
if (!DCRYPTO_app_cipher(NVMEM, pinfo->p, pinfo->p,
@@ -301,7 +301,7 @@ static int basic_check(struct test_info *pinfo)
return EC_ERROR_UNKNOWN;
}
- ccprintf("hashed data %.16h\n", pinfo->p);
+ ccprintf("hashed data %ph\n", HEX_BUF(pinfo->p, 16));
return EC_SUCCESS;
}
@@ -407,7 +407,7 @@ static void run_cipher_cmd(void)
report_stats("Encryption", &info.enc_stats);
report_stats("Decryption", &info.dec_stats);
} else if (info.p) {
- ccprintf("current data %.16h\n", info.p);
+ ccprintf("current data %ph\n", HEX_BUF(info.p, 16));
}
if (info.p)
diff --git a/chip/g/dcrypto/dcrypto_bn.c b/chip/g/dcrypto/dcrypto_bn.c
index cae54e6adf..2696d37669 100644
--- a/chip/g/dcrypto/dcrypto_bn.c
+++ b/chip/g/dcrypto/dcrypto_bn.c
@@ -1484,8 +1484,8 @@ static int command_genp(int argc, char **argv)
result = call_on_bigger_stack(genp_core);
if (result == EC_SUCCESS) {
- ccprintf("prime: %.*h (lsb first)\n", sizeof(prime_buf),
- prime_buf);
+ ccprintf("prime: %ph (lsb first)\n",
+ HEX_BUF(prime_buf, sizeof(prime_buf));
ccprintf("μs : %lu\n", genp_end.val - genp_start.val);
}
diff --git a/chip/g/dcrypto/hmac_drbg.c b/chip/g/dcrypto/hmac_drbg.c
index 64b47a13f5..bf49103e93 100644
--- a/chip/g/dcrypto/hmac_drbg.c
+++ b/chip/g/dcrypto/hmac_drbg.c
@@ -202,7 +202,7 @@ static int cmd_rfc6979(int argc, char **argv)
hmac_drbg_init_rfc6979(&drbg, x, &h1);
do {
hmac_drbg_generate_p256(&drbg, &k);
- ccprintf("K = %.32h\n", &k);
+ ccprintf("K = %ph\n", HEX_BUF(&k, 32));
} while (p256_cmp(&SECP256r1_nMin2, &k) < 0);
drbg_exit(&drbg);
result = p256_cmp(&k, reference_k);
diff --git a/chip/g/loader/launch.c b/chip/g/loader/launch.c
index cf701a21cb..823e29489b 100644
--- a/chip/g/loader/launch.c
+++ b/chip/g/loader/launch.c
@@ -79,7 +79,7 @@ void tryLaunch(uint32_t adr, size_t max_size)
hdr->image_size - offsetof(struct SignedHeader, tag),
(uint8_t *) hashes.img_hash);
- VERBOSE("img_hash : %.32h\n", hashes.img_hash);
+ VERBOSE("img_hash : %ph\n", HEX_BUF(hashes.img_hash, 32));
/* Sense fuses into RAM array; hash array. */
/* TODO: is this glitch resistant enough? Certainly is simple.. */
@@ -104,7 +104,7 @@ void tryLaunch(uint32_t adr, size_t max_size)
DCRYPTO_SHA256_hash((uint8_t *) fuses, sizeof(fuses),
(uint8_t *) hashes.fuses_hash);
- VERBOSE("fuses_hash: %.32h\n", hashes.fuses_hash);
+ VERBOSE("fuses_hash: %ph\n", HEX_BUF(hashes.fuses_hash, 32));
/* Sense info into RAM array; hash array. */
for (i = 0; i < INFO_MAX; ++i)
@@ -122,7 +122,7 @@ void tryLaunch(uint32_t adr, size_t max_size)
DCRYPTO_SHA256_hash((uint8_t *) info, sizeof(info),
(uint8_t *) hashes.info_hash);
- VERBOSE("info_hash : %.32h\n", hashes.info_hash);
+ VERBOSE("info_hash : %ph\n", HEX_BUF(hashes.info_hash, 32));
/* Hash our set of hashes to get final hash. */
DCRYPTO_SHA256_hash((uint8_t *) &hashes, sizeof(hashes),
diff --git a/chip/g/loader/verify.c b/chip/g/loader/verify.c
index 41b1c6cddd..54be724f10 100644
--- a/chip/g/loader/verify.c
+++ b/chip/g/loader/verify.c
@@ -103,7 +103,7 @@ void LOADERKEY_verify(const uint32_t *key, const uint32_t *signature,
int i;
modpow3(key, signature, buf);
- VERBOSE("sig %.384h\n", buf);
+ VERBOSE("sig %ph\n", HEX_BUF(buf, 384));
/*
* If key was not 3Kb, assume 2Kb and expand for subsequent
@@ -142,12 +142,12 @@ void LOADERKEY_verify(const uint32_t *key, const uint32_t *signature,
offset = (offset + step) % SHA256_DIGEST_WORDS;
}
- VERBOSE("\nsig^ %.384h\n\n", buf);
+ VERBOSE("\nsig^ %ph\n\n", HEX_BUF(buf, 384));
/* Hash resulting buffer. */
DCRYPTO_SHA256_hash((uint8_t *) buf, RSA_NUM_BYTES, (uint8_t *) hash);
- VERBOSE("hash %.32h\n", hash);
+ VERBOSE("hash %ph\n", HEX_BUF(hash, 32));
/*
* Write computed hash to unlock register to unlock execution, iff
diff --git a/chip/it83xx/i2c_slave.c b/chip/it83xx/i2c_slave.c
index 1902285959..adfa794d77 100644
--- a/chip/it83xx/i2c_slave.c
+++ b/chip/it83xx/i2c_slave.c
@@ -173,8 +173,9 @@ void i2c_slave_read_write_data(int port)
* TODO(b:129360157): Handle master write
* data by "in_data" array.
*/
- CPRINTS("WData: %.*h",
- I2C_MAX_BUFFER_SIZE, in_data[idx]);
+ CPRINTS("WData: %ph",
+ HEX_BUF(in_data[idx],
+ I2C_MAX_BUFFER_SIZE));
wr_done[idx] = 0;
}
}
diff --git a/chip/stm32/trng.c b/chip/stm32/trng.c
index fcc0f5432e..eff3ca0181 100644
--- a/chip/stm32/trng.c
+++ b/chip/stm32/trng.c
@@ -111,7 +111,7 @@ static int command_rand(int argc, char **argv)
rand_bytes(data, sizeof(data));
exit_trng();
- ccprintf("rand %.*h\n", sizeof(data), data);
+ ccprintf("rand %ph\n", HEX_BUF(data, sizeof(data)));
return EC_SUCCESS;
}
diff --git a/common/ccd_config.c b/common/ccd_config.c
index fc9409a13f..91232df295 100644
--- a/common/ccd_config.c
+++ b/common/ccd_config.c
@@ -714,7 +714,7 @@ static int command_ccd_info(void)
ccprintf("Password: %s\n", raw_has_password() ? "set" : "none");
ccprintf("Flags: 0x%06x\n", raw_get_flags());
- ccprintf("Capabilities: %.8h\n", config.capabilities);
+ ccprintf("Capabilities: %ph\n", HEX_BUF(config.capabilities, 8));
for (i = 0; i < CCD_CAP_COUNT; i++) {
int c = raw_get_cap(i, 0);
diff --git a/common/host_command.c b/common/host_command.c
index be178f7b6c..eff1fac56b 100644
--- a/common/host_command.c
+++ b/common/host_command.c
@@ -666,8 +666,9 @@ static void host_command_debug_request(struct host_cmd_handler_args *args)
}
if (hcdebug >= HCDEBUG_PARAMS && args->params_size)
- CPRINTS("HC 0x%02x.%d:%.*h", args->command,
- args->version, args->params_size, args->params);
+ CPRINTS("HC 0x%02x.%d:%ph", args->command,
+ args->version,
+ HEX_BUF(args->params, args->params_size));
else
CPRINTS("HC 0x%02x", args->command);
}
@@ -711,8 +712,8 @@ uint16_t host_command_process(struct host_cmd_handler_args *args)
CPRINTS("HC 0x%02x err %d", args->command, rv);
if (hcdebug >= HCDEBUG_PARAMS && args->response_size)
- CPRINTS("HC resp:%.*h", args->response_size,
- args->response);
+ CPRINTS("HC resp:%ph",
+ HEX_BUF(args->response, args->response_size));
return rv;
}
@@ -892,7 +893,8 @@ static int command_host_command(int argc, char **argv)
if (res != EC_RES_SUCCESS)
ccprintf("Command returned %d\n", res);
else if (args.response_size)
- ccprintf("Response: %.*h\n", args.response_size, cmd_params);
+ ccprintf("Response: %ph\n",
+ HEX_BUF(cmd_params, args.response_size));
else
ccprintf("Command succeeded; no response.\n");
diff --git a/common/i2c_master.c b/common/i2c_master.c
index ea33b6f533..091ea7f423 100644
--- a/common/i2c_master.c
+++ b/common/i2c_master.c
@@ -1145,7 +1145,7 @@ static int command_i2cxfer(int argc, char **argv)
(uint8_t *)&offset, 1, data, v);
if (!rv)
- ccprintf("Data: %.*h\n", v, data);
+ ccprintf("Data: %ph\n", HEX_BUF(data, v));
} else if (strcasecmp(argv[1], "w") == 0) {
/* 8-bit write */
diff --git a/common/peci.c b/common/peci.c
index b4422de05e..e0f03c95dd 100644
--- a/common/peci.c
+++ b/common/peci.c
@@ -140,7 +140,7 @@ static int peci_cmd(int argc, char **argv)
ccprintf("PECI transaction error\n");
return EC_ERROR_UNKNOWN;
}
- ccprintf("PECI read data: %.*h\n", peci.r_len, r_buf);
+ ccprintf("PECI read data: %ph\n", HEX_BUF(r_buf, peci.r_len));
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(peci, peci_cmd,
diff --git a/common/printf.c b/common/printf.c
index 89ee004452..777c78b471 100644
--- a/common/printf.c
+++ b/common/printf.c
@@ -5,6 +5,7 @@
/* Printf-like functionality for Chrome EC */
+#include "console.h"
#include "printf.h"
#include "timer.h"
#include "util.h"
@@ -18,6 +19,7 @@ static inline int divmod(uint64_t *n, int d)
{
return uint64divmod(n, d);
}
+
#else /* CONFIG_DEBUG_PRINTF */
/* if we are optimizing for size, remove the 64-bit support */
#define NO_UINT64_SUPPORT
@@ -48,7 +50,55 @@ static int hexdigit(int c)
#define PF_LEFT BIT(0) /* Left-justify */
#define PF_PADZERO BIT(1) /* Pad with 0's not spaces */
#define PF_SIGN BIT(2) /* Add sign (+) for a positive number */
+
+/* Deactivate the PF_64BIT flag is 64-bit support is disabled. */
+#ifdef NO_UINT64_SUPPORT
+#define PF_64BIT 0
+#else
#define PF_64BIT BIT(3) /* Number is 64-bit */
+#endif
+
+/*
+ * Print the buffer as a string of bytes in hex.
+ * Returns 0 on success or an error on failure.
+ */
+static int print_hex_buffer(int (*addchar)(void *context, int c),
+ void *context, const char *vstr, int precision,
+ int pad_width, int flags)
+
+{
+
+ /*
+ * Divide pad_width instead of multiplying precision to avoid overflow
+ * error in the condition. The "/2" and "2*" can be optimized by
+ * the compiler.
+ */
+
+ if ((pad_width / 2) >= precision)
+ pad_width -= 2 * precision;
+ else
+ pad_width = 0;
+
+ while (pad_width > 0 && !(flags & PF_LEFT)) {
+ if (addchar(context, flags & PF_PADZERO ? '0' : ' '))
+ return EC_ERROR_OVERFLOW;
+ pad_width--;
+ }
+
+ for (; precision; precision--, vstr++) {
+ if (addchar(context, hexdigit(*vstr >> 4)) ||
+ addchar(context, hexdigit(*vstr)))
+ return EC_ERROR_OVERFLOW;
+ }
+
+ while (pad_width > 0 && (flags & PF_LEFT)) {
+ if (addchar(context, ' '))
+ return EC_ERROR_OVERFLOW;
+ pad_width--;
+ }
+
+ return EC_SUCCESS;
+}
int vfnprintf(int (*addchar)(void *context, int c), void *context,
const char *format, va_list args)
@@ -162,54 +212,14 @@ int vfnprintf(int (*addchar)(void *context, int c), void *context,
vstr = va_arg(args, char *);
if (vstr == NULL)
vstr = "(NULL)";
- } else if (c == 'h') {
- /* Hex dump output */
- vstr = va_arg(args, char *);
-
- if (precision < 0) {
- /* Hex dump requires precision */
- format = error_str;
- continue;
- }
-
- /*
- * Divide pad_width instead of multiplying
- * precision to avoid overflow error
- * in the condition.
- * The "/2" and "2*" can be optimized by
- * the compiler.
- */
- if ((pad_width/2) >= precision)
- pad_width -= 2*precision;
- else
- pad_width = 0;
-
- while (pad_width > 0 && !(flags & PF_LEFT)) {
- if (addchar(context,
- flags & PF_PADZERO ? '0' : ' '))
- return EC_ERROR_OVERFLOW;
- pad_width--;
- }
- for (; precision; precision--, vstr++) {
- if (addchar(context, hexdigit(*vstr >> 4)) ||
- addchar(context, hexdigit(*vstr)))
- return EC_ERROR_OVERFLOW;
- }
- while (pad_width > 0 && (flags & PF_LEFT)) {
- if (addchar(context, ' '))
- return EC_ERROR_OVERFLOW;
- pad_width--;
- }
- continue;
} else {
int base = 10;
#ifdef NO_UINT64_SUPPORT
uint32_t v;
-
- v = va_arg(args, uint32_t);
-#else /* NO_UINT64_SUPPORT */
+#else
uint64_t v;
+#endif
int ptrspec;
void *ptrval;
@@ -223,7 +233,8 @@ int vfnprintf(int (*addchar)(void *context, int c), void *context,
ptrspec = *format++;
ptrval = va_arg(args, void *);
/* %pT - print a timestamp. */
- if (ptrspec == 'T') {
+ if (ptrspec == 'T' &&
+ !IS_ENABLED(NO_UINT64_SUPPORT)) {
flags |= PF_64BIT;
/* NULL uses the current time. */
if (ptrval == NULL)
@@ -239,8 +250,26 @@ int vfnprintf(int (*addchar)(void *context, int c), void *context,
v /= 1000;
}
+ } else if (ptrspec == 'h') {
+ /* %ph - Print a hex byte buffer. */
+ struct hex_buffer_params *hexbuf =
+ ptrval;
+ int rc;
+
+ rc = print_hex_buffer(addchar,
+ context,
+ hexbuf->buffer,
+ hexbuf->size,
+ 0,
+ 0);
+
+ if (rc != EC_SUCCESS)
+ return rc;
+
+ continue;
+
} else if (ptrspec == 'P') {
- /* Print a raw pointer. */
+ /* %pP - Print a raw pointer. */
v = (unsigned long)ptrval;
if (sizeof(unsigned long) ==
sizeof(uint64_t))
@@ -255,7 +284,6 @@ int vfnprintf(int (*addchar)(void *context, int c), void *context,
} else {
v = va_arg(args, uint32_t);
}
-#endif
switch (c) {
#ifdef CONFIG_PRINTF_LEGACY_LI_FORMAT
diff --git a/common/spi_commands.c b/common/spi_commands.c
index 9fdc721d40..1a70a5be82 100644
--- a/common/spi_commands.c
+++ b/common/spi_commands.c
@@ -46,7 +46,7 @@ static int command_spixfer(int argc, char **argv)
rv = spi_transaction(&spi_devices[dev_id], &cmd, 1, data, v);
if (!rv)
- ccprintf("Data: %.*h\n", v, data);
+ ccprintf("Data: %ph\n", HEX_BUF(data, v));
} else if (strcasecmp(argv[1], "w") == 0) {
/* 8-bit write */
diff --git a/common/vboot_hash.c b/common/vboot_hash.c
index 4d12af7c7b..0642e09e3c 100644
--- a/common/vboot_hash.c
+++ b/common/vboot_hash.c
@@ -141,7 +141,7 @@ static void vboot_hash_next_chunk(void)
if (curr_pos >= data_size) {
/* Store the final hash */
hash = SHA256_final(&ctx);
- CPRINTS("hash done %.*h", SHA256_PRINT_SIZE, hash);
+ CPRINTS("hash done %ph", HEX_BUF(hash, SHA256_PRINT_SIZE));
in_progress = 0;
@@ -331,7 +331,7 @@ static int command_hash(int argc, char **argv)
else if (in_progress)
ccprintf("(in progress)\n");
else if (hash)
- ccprintf("%.*h\n", SHA256_DIGEST_SIZE, hash);
+ ccprintf("%ph\n", HEX_BUF(hash, SHA256_DIGEST_SIZE));
else
ccprintf("(invalid)\n");
diff --git a/driver/touchpad_st.c b/driver/touchpad_st.c
index 5fbeeb45ea..d3381bd92c 100644
--- a/driver/touchpad_st.c
+++ b/driver/touchpad_st.c
@@ -600,15 +600,16 @@ static void dump_memory(void)
(uint8_t *)&rx_buf, rx_len);
for (i = 0; i < rx_len - ST_TP_DUMMY_BYTE; i += 32) {
- CPRINTF("%.4h %.4h %.4h %.4h %.4h %.4h %.4h %.4h\n",
- rx_buf.bytes + i + 4 * 0,
- rx_buf.bytes + i + 4 * 1,
- rx_buf.bytes + i + 4 * 2,
- rx_buf.bytes + i + 4 * 3,
- rx_buf.bytes + i + 4 * 4,
- rx_buf.bytes + i + 4 * 5,
- rx_buf.bytes + i + 4 * 6,
- rx_buf.bytes + i + 4 * 7);
+ CPRINTF("%ph %ph %ph %ph "
+ "%ph %ph %ph %ph\n",
+ HEX_BUF(rx_buf.bytes + i + 4 * 0, 4),
+ HEX_BUF(rx_buf.bytes + i + 4 * 1, 4),
+ HEX_BUF(rx_buf.bytes + i + 4 * 2, 4),
+ HEX_BUF(rx_buf.bytes + i + 4 * 3, 4),
+ HEX_BUF(rx_buf.bytes + i + 4 * 4, 4),
+ HEX_BUF(rx_buf.bytes + i + 4 * 5, 4),
+ HEX_BUF(rx_buf.bytes + i + 4 * 6, 4),
+ HEX_BUF(rx_buf.bytes + i + 4 * 7, 4));
msleep(8);
}
}
@@ -1264,7 +1265,7 @@ int touchpad_debug(const uint8_t *param, unsigned int param_size,
*data_size = 8;
st_tp_read_host_buffer_header();
memcpy(buf, rx_buf.bytes, *data_size);
- CPRINTS("header: %.*h", *data_size, buf);
+ CPRINTS("header: %ph", HEX_BUF(buf, *data_size));
return EC_SUCCESS;
case ST_TP_DEBUG_CMD_READ_EVENTS:
num_events = st_tp_read_all_events(0);
diff --git a/fuzz/host_command_fuzz.c b/fuzz/host_command_fuzz.c
index 9ac7955aed..5d490bc192 100644
--- a/fuzz/host_command_fuzz.c
+++ b/fuzz/host_command_fuzz.c
@@ -113,8 +113,8 @@ static int hostcmd_fill(const uint8_t *data, size_t size)
* issues.
*/
if (first) {
- ccprintf("Request: cmd=%04x data=%.*h\n",
- req->command, req_size, req_buf);
+ ccprintf("Request: cmd=%04x data=%ph\n",
+ req->command, HEX_BUF(req_buf, req_size));
first = 0;
}
diff --git a/include/console.h b/include/console.h
index 73e9d9094c..dc15e5b6d3 100644
--- a/include/console.h
+++ b/include/console.h
@@ -10,6 +10,22 @@
#include "common.h"
+/*
+ * The EC code base has been using %h to print a hex buffer. Encode the
+ * parameters to do that in a pointer to a structure that's passed as the
+ * printf argument. This is done rather than something like %.123ph because
+ * the C standard doesn't allow flags, precision, and field width on %p.
+ */
+struct hex_buffer_params {
+ const void *buffer;
+ uint16_t size;
+};
+
+#define HEX_BUF(_buffer, _size) (&(const struct hex_buffer_params){ \
+ .buffer = (_buffer), \
+ .size = (_size) \
+})
+
#define PRINTF_TIMESTAMP_NOW NULL
/* Console command; used by DECLARE_CONSOLE_COMMAND macro. */
diff --git a/include/printf.h b/include/printf.h
index c55c8f7d2b..6e245a3f2a 100644
--- a/include/printf.h
+++ b/include/printf.h
@@ -40,10 +40,6 @@
* Type may be:
* - 'c' - character
* - 's' - null-terminated ASCII string
- * - 'h' - binary data, print as hex; precision is length of data in bytes.
- * So "%.8h" prints 8 bytes of binary data
- * - 'pP'- raw pointer. %p followed by another character represents a %p
- * extension.
* - 'd' - signed integer
* - 'i' - signed integer if CONFIG_PRINTF_LEGACY_LI_FORMAT is set (ignore l)
* - 'u' - unsigned integer
@@ -52,6 +48,9 @@
* - 'b' - unsigned integer, print as binary
*
* Special format codes:
+ * - '%ph' - binary data, print as hex; Use HEX_BUF(buffer, size) to encode
+ * parameters.
+ * - '%pP' - raw pointer.
* - "%pT" - current time in seconds - interpreted as "%.6T" for precision.
* Supply PRINTF_TIMESTAMP_NOW to use the current time, or supply a
* pointer to a 64-bit timestamp to print.
diff --git a/test/printf.c b/test/printf.c
index cf20be7b31..c758d9bccb 100644
--- a/test/printf.c
+++ b/test/printf.c
@@ -253,11 +253,9 @@ test_static int test_vsnprintf_hexdump(void)
{
const char bytes[] = {0x00, 0x5E};
- T(expect_success(err_str, "%h", bytes));
- T(expect_success("005e", "%.*h", 2, bytes));
- T(expect_success("", "%.*h", 0, bytes));
- T(expect_success(" 005e", "%5.*h", 2, bytes));
- T(expect_success("00", "%0*.*h", 2, 0, bytes));
+ T(expect_success("005e", "%ph", HEX_BUF(bytes, 2)));
+ T(expect_success("", "%ph", HEX_BUF(bytes, 0)));
+ T(expect_success("00", "%ph", HEX_BUF(bytes, 1)));
return EC_SUCCESS;
}