1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
8 void data_free(struct data d
)
10 struct marker
*m
, *nm
;
24 struct data
data_grow_for(struct data d
, int xlen
)
36 while ((d
.len
+ xlen
) > newsize
)
39 nd
.val
= xrealloc(d
.val
, newsize
);
44 struct data
data_copy_mem(const char *mem
, int len
)
48 d
= data_grow_for(empty_data
, len
);
51 memcpy(d
.val
, mem
, len
);
56 struct data
data_copy_escape_string(const char *s
, int len
)
62 d
= data_add_marker(empty_data
, TYPE_STRING
, NULL
);
63 d
= data_grow_for(d
, len
+ 1);
70 c
= get_escape_char(s
, &i
);
79 struct data
data_copy_file(FILE *f
, size_t maxlen
)
81 struct data d
= empty_data
;
83 d
= data_add_marker(d
, TYPE_NONE
, NULL
);
84 while (!feof(f
) && (d
.len
< maxlen
)) {
85 size_t chunksize
, ret
;
90 chunksize
= maxlen
- d
.len
;
92 d
= data_grow_for(d
, chunksize
);
93 ret
= fread(d
.val
+ d
.len
, 1, chunksize
, f
);
96 die("Error reading file into data: %s", strerror(errno
));
98 if (d
.len
+ ret
< d
.len
)
99 die("Overflow reading file into data\n");
107 struct data
data_append_data(struct data d
, const void *p
, int len
)
109 d
= data_grow_for(d
, len
);
110 memcpy(d
.val
+ d
.len
, p
, len
);
115 struct data
data_insert_at_marker(struct data d
, struct marker
*m
,
116 const void *p
, int len
)
118 d
= data_grow_for(d
, len
);
119 memmove(d
.val
+ m
->offset
+ len
, d
.val
+ m
->offset
, d
.len
- m
->offset
);
120 memcpy(d
.val
+ m
->offset
, p
, len
);
123 /* Adjust all markers after the one we're inserting at */
130 static struct data
data_append_markers(struct data d
, struct marker
*m
)
132 struct marker
**mp
= &d
.markers
;
134 /* Find the end of the markerlist */
141 struct data
data_merge(struct data d1
, struct data d2
)
144 struct marker
*m2
= d2
.markers
;
146 d
= data_append_markers(data_append_data(d1
, d2
.val
, d2
.len
), m2
);
148 /* Adjust for the length of d1 */
150 m2
->offset
+= d1
.len
;
152 d2
.markers
= NULL
; /* So data_free() doesn't clobber them */
158 struct data
data_append_integer(struct data d
, uint64_t value
, int bits
)
168 return data_append_data(d
, &value_8
, 1);
171 value_16
= cpu_to_fdt16(value
);
172 return data_append_data(d
, &value_16
, 2);
175 value_32
= cpu_to_fdt32(value
);
176 return data_append_data(d
, &value_32
, 4);
179 value_64
= cpu_to_fdt64(value
);
180 return data_append_data(d
, &value_64
, 8);
183 die("Invalid literal size (%d)\n", bits
);
187 struct data
data_append_re(struct data d
, uint64_t address
, uint64_t size
)
189 struct fdt_reserve_entry re
;
191 re
.address
= cpu_to_fdt64(address
);
192 re
.size
= cpu_to_fdt64(size
);
194 return data_append_data(d
, &re
, sizeof(re
));
197 struct data
data_append_cell(struct data d
, cell_t word
)
199 return data_append_integer(d
, word
, sizeof(word
) * 8);
202 struct data
data_append_addr(struct data d
, uint64_t addr
)
204 return data_append_integer(d
, addr
, sizeof(addr
) * 8);
207 struct data
data_append_byte(struct data d
, uint8_t byte
)
209 return data_append_data(d
, &byte
, 1);
212 struct data
data_append_zeroes(struct data d
, int len
)
214 d
= data_grow_for(d
, len
);
216 memset(d
.val
+ d
.len
, 0, len
);
221 struct data
data_append_align(struct data d
, int align
)
223 int newlen
= ALIGN(d
.len
, align
);
224 return data_append_zeroes(d
, newlen
- d
.len
);
227 struct data
data_add_marker(struct data d
, enum markertype type
, char *ref
)
231 m
= xmalloc(sizeof(*m
));
237 return data_append_markers(d
, m
);
240 bool data_is_one_string(struct data d
)
248 for (i
= 0; i
< len
-1; i
++)
249 if (d
.val
[i
] == '\0')
252 if (d
.val
[len
-1] != '\0')