aboutsummaryrefslogtreecommitdiff
path: root/dtc.h
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2020-04-14 15:02:51 +1000
committerDavid Gibson <david@gibson.dropbear.id.au>2020-04-14 15:02:51 +1000
commitb28464a550c536296439b5785ed8852d1e15b35b (patch)
treef8d72aa136e484629d35f9f5c7e799946367aaf7 /dtc.h
parent87a656ae5ff96c4903e68eb2f999532a3b98e3a7 (diff)
downloaddtc-b28464a550c536296439b5785ed8852d1e15b35b.zip
dtc-b28464a550c536296439b5785ed8852d1e15b35b.tar.gz
dtc-b28464a550c536296439b5785ed8852d1e15b35b.tar.bz2
Fix some potential unaligned accesses in dtc
Because of the convention of packed representations in property layouts, it's not uncommon to have integer values in properties which aren't naturally aligned. Thus, there are several places in the dtc code where we cast a potentially unaligned byte pointer into an integer pointer and load it directly. On a number of architectures (including sparc64 and arm) this won't work and will cause a fault. In some cases it may be trapped and emulated by the kernel, but not always. Therefore, replace such direct unaligned reads with a helper which will handle unaligned data reads (a variant on the fdtXX_ld() functions already used in libfdt). Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'dtc.h')
-rw-r--r--dtc.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/dtc.h b/dtc.h
index 6e74ece..a08f415 100644
--- a/dtc.h
+++ b/dtc.h
@@ -51,6 +51,37 @@ extern int annotate; /* annotate .dts with input source location */
typedef uint32_t cell_t;
+static inline uint16_t dtb_ld16(const void *p)
+{
+ const uint8_t *bp = (const uint8_t *)p;
+
+ return ((uint16_t)bp[0] << 8)
+ | bp[1];
+}
+
+static inline uint32_t dtb_ld32(const void *p)
+{
+ const uint8_t *bp = (const uint8_t *)p;
+
+ return ((uint32_t)bp[0] << 24)
+ | ((uint32_t)bp[1] << 16)
+ | ((uint32_t)bp[2] << 8)
+ | bp[3];
+}
+
+static inline uint64_t dtb_ld64(const void *p)
+{
+ const uint8_t *bp = (const uint8_t *)p;
+
+ return ((uint64_t)bp[0] << 56)
+ | ((uint64_t)bp[1] << 48)
+ | ((uint64_t)bp[2] << 40)
+ | ((uint64_t)bp[3] << 32)
+ | ((uint64_t)bp[4] << 24)
+ | ((uint64_t)bp[5] << 16)
+ | ((uint64_t)bp[6] << 8)
+ | bp[7];
+}
#define streq(a, b) (strcmp((a), (b)) == 0)
#define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0)