summaryrefslogtreecommitdiff
path: root/data.c
diff options
context:
space:
mode:
authorGreg Kurz <groug@kaod.org>2018-08-30 12:01:59 +0200
committerDavid Gibson <david@gibson.dropbear.id.au>2018-08-31 11:13:33 +1000
commit9619c8619c37b9aea98100bcc15c51a5642e877e (patch)
treef07597f86baea4f27d08bb4c47a1a25751da80a7 /data.c
parentac68ff92ae20f7447f7af6c154a95f528df46851 (diff)
downloaddevice-tree-compiler-9619c8619c37b9aea98100bcc15c51a5642e877e.tar.gz
Kill bogus TYPE_BLOB marker type
Since commit 32b9c6130762 "Preserve datatype markers when emitting dts format", we no longer try to guess the value type. Instead, we reuse the type of the datatype markers when they are present, if the type is either TYPE_UINT* or TYPE_STRING. This causes 'dtc -I fs' to crash: Starting program: /root/dtc -q -f -O dts -I fs /proc/device-tree /dts-v1/; / { Program received signal SIGSEGV, Segmentation fault. __strlen_power8 () at ../sysdeps/powerpc/powerpc64/power8/strlen.S:47 47 ld r12,0(r4) /* Load doubleword from memory. */ (gdb) bt #0 __strlen_power8 () at ../sysdeps/powerpc/powerpc64/power8/strlen.S:47 #1 0x00007ffff7de3d10 in __GI__IO_fputs (str=<optimized out>, fp=<optimized out>) at iofputs.c:33 #2 0x000000001000c7a0 in write_propval (prop=0x100525e0, f=0x7ffff7f718a0 <_IO_2_1_stdout_>) at treesource.c:245 The offending line is: fprintf(f, "%s", delim_start[emit_type]); where emit_type is TYPE_BLOB and: static const char *delim_start[] = { [TYPE_UINT8] = "[", [TYPE_UINT16] = "/bits/ 16 <", [TYPE_UINT32] = "<", [TYPE_UINT64] = "/bits/ 64 <", [TYPE_STRING] = "", }; /* Data blobs */ enum markertype { TYPE_NONE, REF_PHANDLE, REF_PATH, LABEL, TYPE_UINT8, TYPE_UINT16, TYPE_UINT32, TYPE_UINT64, TYPE_BLOB, TYPE_STRING, }; Because TYPE_BLOB < TYPE_STRING and delim_start[] is a static array, delim_start[emit_type] is 0x0. The glibc usually prints out "(null)" when one passes 0x0 to %s, but it seems to call fputs() internally if the format is exactly "%s", hence the crash. TYPE_BLOB basically means the data comes from a file and we don't know its type. We don't care for the former, and the latter is TYPE_NONE. So let's drop TYPE_BLOB completely and use TYPE_NONE instead when reading the file. Then, try to guess the data type at emission time, like the code already does for refs and labels. Instead of adding yet another check for TYPE_NONE, an helper is introduced to check if the data marker has type information, ie, >= TYPE_UINT8. Fixes: 32b9c61307629ac76c6ac0bead6f926d579b3d2c Suggested-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Greg Kurz <groug@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'data.c')
-rw-r--r--data.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/data.c b/data.c
index accdfae..4a20414 100644
--- a/data.c
+++ b/data.c
@@ -95,7 +95,7 @@ struct data data_copy_file(FILE *f, size_t maxlen)
{
struct data d = empty_data;
- d = data_add_marker(d, TYPE_BLOB, NULL);
+ d = data_add_marker(d, TYPE_NONE, NULL);
while (!feof(f) && (d.len < maxlen)) {
size_t chunksize, ret;