+static bool adjust_size(size_t *size, size_t count)
+{
+ const size_t extra = sizeof(struct tal_hdr) + sizeof(struct length)*2;
+
+ /* Multiplication wrap */
+ if (count && unlikely(*size * count / *size != count))
+ goto overflow;
+
+ *size *= count;
+
+ /* Make sure we don't wrap adding header/tailer. */
+ if (*size + extra < extra)
+ goto overflow;
+ return true;
+overflow:
+ call_error("allocation size overflow");
+ return false;
+}
+
+static size_t extra_for_length(size_t size)
+{
+ size_t extra;
+ const size_t align = ALIGNOF(struct length);
+
+ /* Round up size, and add tailer. */
+ extra = ((size + align-1) & ~(align-1)) - size;
+ extra += sizeof(struct length);
+ return extra;
+}
+
+void *tal_alloc_arr_(const tal_t *ctx, size_t size, size_t count, bool clear,
+ bool add_count, const char *label)
+{
+ void *ret;
+
+ if (!adjust_size(&size, count))
+ return NULL;
+
+ if (add_count)
+ size += extra_for_length(size);
+
+ ret = tal_alloc_(ctx, size, clear, label);
+ if (unlikely(!ret))
+ return ret;
+
+ if (add_count) {
+ struct length *lprop;
+ lprop = (struct length *)((char *)ret + size) - 1;
+ init_property(&lprop->hdr, to_tal_hdr(ret), LENGTH);
+ lprop->count = count;
+ }
+ return ret;
+}
+