summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2021-03-08 10:46:58 +0800
committerCommit Bot <commit-bot@chromium.org>2021-03-10 04:38:44 +0000
commit357ce5349a2e88bed9e9d773719e5119ac76ef49 (patch)
treee814f48733ce2dc4c503a8f64b1896abf5bb49cd
parent819adb4fa98f5d32a373ebd63e668b1c1bc5b121 (diff)
downloadchrome-ec-357ce5349a2e88bed9e9d773719e5119ac76ef49.tar.gz
util/ec_parse_panicinfo: Parse older structures
For devices on older FW branches, we need to be able to parse panicinfo even if the size of the structures don't match. Realign trailer (struct_size and magic) for that purpose. Also, add WARNING/ERROR tags to messages so that we can grep for those in a test. Make a similar change in ectool (use the return value that indicates the size). BUG=b:182087232 TEST=make build/bds/util/ec_parse_panicinfo TEST=build/bds/util/ec_parse_panicinfo < \ ./upload_file_eccrash-857e3693bfce1e1f.eccrash BRANCH=none Change-Id: I97650aa3085e753b0a2256058402e33d11238f52 Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2738577 Reviewed-by: Eric Yilun Lin <yllin@chromium.org>
-rw-r--r--util/ec_panicinfo.c61
-rw-r--r--util/ec_panicinfo.h2
-rw-r--r--util/ec_parse_panicinfo.c30
-rw-r--r--util/ectool.c3
4 files changed, 75 insertions, 21 deletions
diff --git a/util/ec_panicinfo.c b/util/ec_panicinfo.c
index b919cc6df7..ad6867fdc9 100644
--- a/util/ec_panicinfo.c
+++ b/util/ec_panicinfo.c
@@ -5,7 +5,9 @@
#include <stdint.h>
#include <stdio.h>
+#include <string.h>
#include "compile_time_macros.h"
+
#include "ec_panicinfo.h"
static void print_panic_reg(int regnum, const uint32_t *regs, int index)
@@ -123,34 +125,67 @@ static int parse_panic_info_rv32i(const struct panic_data *pdata)
return 0;
}
-int parse_panic_info(const struct panic_data *pdata)
+int parse_panic_info(const char *data, size_t size)
{
+ /* Size of the panic information "header". */
+ const size_t header_size = 4;
+ /* Size of the panic information "trailer" (struct_size and magic). */
+ const size_t trailer_size = sizeof(struct panic_data) -
+ offsetof(struct panic_data, struct_size);
+
+ struct panic_data pdata = { 0 };
+ size_t copy_size;
+
+ if (size < (header_size + trailer_size)) {
+ fprintf(stderr, "ERROR: Panic data too short (%zd).\n", size);
+ return -1;
+ }
+
+ if (size > sizeof(pdata)) {
+ fprintf(stderr, "WARNING: Panic data too large (%zd > %zd). "
+ "Following data may be incorrect!\n",
+ size, sizeof(pdata));
+ copy_size = sizeof(pdata);
+ } else {
+ copy_size = size;
+ }
+ /* Copy the data into pdata, as the struct size may have changed. */
+ memcpy(&pdata, data, copy_size);
+ /* Then copy the trailer in position. */
+ memcpy((char *)&pdata + (sizeof(struct panic_data) - trailer_size),
+ data + (size - trailer_size), trailer_size);
+
/*
* We only understand panic data with version <= 2. Warn the user
* of higher versions.
*/
- if (pdata->struct_version > 2)
- fprintf(stderr,
- "Unknown panic data version (%d). "
+ if (pdata.struct_version > 2)
+ fprintf(stderr, "WARNING: Unknown panic data version (%d). "
"Following data may be incorrect!\n",
- pdata->struct_version);
+ pdata.struct_version);
/* Validate magic number */
- if (pdata->magic != PANIC_DATA_MAGIC)
+ if (pdata.magic != PANIC_DATA_MAGIC)
+ fprintf(stderr, "WARNING: Incorrect panic magic (%d). "
+ "Following data may be incorrect!\n",
+ pdata.magic);
+
+ if (pdata.struct_size != size)
fprintf(stderr,
- "Incorrect panic magic (%d). "
+ "WARNING: Panic struct size inconsistent (%u vs %zd). "
"Following data may be incorrect!\n",
- pdata->magic);
+ pdata.struct_size, size);
- switch (pdata->arch) {
+ switch (pdata.arch) {
case PANIC_ARCH_CORTEX_M:
- return parse_panic_info_cm(pdata);
+ return parse_panic_info_cm(&pdata);
case PANIC_ARCH_NDS32_N8:
- return parse_panic_info_nds32(pdata);
+ return parse_panic_info_nds32(&pdata);
case PANIC_ARCH_RISCV_RV32I:
- return parse_panic_info_rv32i(pdata);
+ return parse_panic_info_rv32i(&pdata);
default:
- fprintf(stderr, "Unknown architecture (%d).\n", pdata->arch);
+ fprintf(stderr, "ERROR: Unknown architecture (%d).\n",
+ pdata.arch);
break;
}
return -1;
diff --git a/util/ec_panicinfo.h b/util/ec_panicinfo.h
index f70c58e59f..c61cf797e6 100644
--- a/util/ec_panicinfo.h
+++ b/util/ec_panicinfo.h
@@ -14,6 +14,6 @@
* @param pdata Panic information to print
* @return 0 if success or non-zero error code if error.
*/
-int parse_panic_info(const struct panic_data *pdata);
+int parse_panic_info(const char *data, size_t size);
#endif /* EC_PANICINFO_H */
diff --git a/util/ec_parse_panicinfo.c b/util/ec_parse_panicinfo.c
index 5db8ed2e05..a3fefcf7b5 100644
--- a/util/ec_parse_panicinfo.c
+++ b/util/ec_parse_panicinfo.c
@@ -7,16 +7,36 @@
#include <stdint.h>
#include <stdio.h>
+#include "compile_time_macros.h"
#include "ec_panicinfo.h"
int main(int argc, char *argv[])
{
- struct panic_data pdata;
+ /*
+ * panic_data size could change with time, as new architecture are
+ * added (or, less likely, removed).
+ */
+ char pdata[4096];
+ size_t size = 0;
+ size_t read;
- if (fread(&pdata, sizeof(pdata), 1, stdin) != 1) {
- fprintf(stderr, "Error reading panicinfo from stdin.\n");
- return 1;
+ BUILD_ASSERT(sizeof(pdata) > sizeof(struct panic_data)*2);
+
+ while (1) {
+ read = fread(&pdata[size], 1, sizeof(pdata)-size, stdin);
+ if (read < 0) {
+ fprintf(stderr, "Cannot read panicinfo from stdin.\n");
+ return 1;
+ }
+ if (read == 0)
+ break;
+
+ size += read;
+ if (size == sizeof(pdata)) {
+ fprintf(stderr, "Too much panicinfo data in stdin.\n");
+ return 1;
+ }
}
- return parse_panic_info(&pdata) ? 1 : 0;
+ return parse_panic_info(pdata, size) ? 1 : 0;
}
diff --git a/util/ectool.c b/util/ectool.c
index a85166ebe7..459a7158b5 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -6448,7 +6448,6 @@ int cmd_keyboard_factory_test(int argc, char *argv[])
int cmd_panic_info(int argc, char *argv[])
{
int rv;
- struct panic_data *pdata = (struct panic_data *)ec_inbuf;
rv = ec_command(EC_CMD_GET_PANIC_INFO, 0, NULL, 0,
ec_inbuf, ec_max_insize);
@@ -6460,7 +6459,7 @@ int cmd_panic_info(int argc, char *argv[])
return 0;
}
- return parse_panic_info(pdata);
+ return parse_panic_info(ec_inbuf, rv);
}