0001
0002
0003
0004
0005
0006 #include "dtc.h"
0007
0008 void data_free(struct data d)
0009 {
0010 struct marker *m, *nm;
0011
0012 m = d.markers;
0013 while (m) {
0014 nm = m->next;
0015 free(m->ref);
0016 free(m);
0017 m = nm;
0018 }
0019
0020 if (d.val)
0021 free(d.val);
0022 }
0023
0024 struct data data_grow_for(struct data d, unsigned int xlen)
0025 {
0026 struct data nd;
0027 unsigned int newsize;
0028
0029 if (xlen == 0)
0030 return d;
0031
0032 nd = d;
0033
0034 newsize = xlen;
0035
0036 while ((d.len + xlen) > newsize)
0037 newsize *= 2;
0038
0039 nd.val = xrealloc(d.val, newsize);
0040
0041 return nd;
0042 }
0043
0044 struct data data_copy_mem(const char *mem, int len)
0045 {
0046 struct data d;
0047
0048 d = data_grow_for(empty_data, len);
0049
0050 d.len = len;
0051 memcpy(d.val, mem, len);
0052
0053 return d;
0054 }
0055
0056 struct data data_copy_escape_string(const char *s, int len)
0057 {
0058 int i = 0;
0059 struct data d;
0060 char *q;
0061
0062 d = data_add_marker(empty_data, TYPE_STRING, NULL);
0063 d = data_grow_for(d, len + 1);
0064
0065 q = d.val;
0066 while (i < len) {
0067 char c = s[i++];
0068
0069 if (c == '\\')
0070 c = get_escape_char(s, &i);
0071
0072 q[d.len++] = c;
0073 }
0074
0075 q[d.len++] = '\0';
0076 return d;
0077 }
0078
0079 struct data data_copy_file(FILE *f, size_t maxlen)
0080 {
0081 struct data d = empty_data;
0082
0083 d = data_add_marker(d, TYPE_NONE, NULL);
0084 while (!feof(f) && (d.len < maxlen)) {
0085 size_t chunksize, ret;
0086
0087 if (maxlen == (size_t)-1)
0088 chunksize = 4096;
0089 else
0090 chunksize = maxlen - d.len;
0091
0092 d = data_grow_for(d, chunksize);
0093 ret = fread(d.val + d.len, 1, chunksize, f);
0094
0095 if (ferror(f))
0096 die("Error reading file into data: %s", strerror(errno));
0097
0098 if (d.len + ret < d.len)
0099 die("Overflow reading file into data\n");
0100
0101 d.len += ret;
0102 }
0103
0104 return d;
0105 }
0106
0107 struct data data_append_data(struct data d, const void *p, int len)
0108 {
0109 d = data_grow_for(d, len);
0110 memcpy(d.val + d.len, p, len);
0111 d.len += len;
0112 return d;
0113 }
0114
0115 struct data data_insert_at_marker(struct data d, struct marker *m,
0116 const void *p, int len)
0117 {
0118 d = data_grow_for(d, len);
0119 memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
0120 memcpy(d.val + m->offset, p, len);
0121 d.len += len;
0122
0123
0124 m = m->next;
0125 for_each_marker(m)
0126 m->offset += len;
0127 return d;
0128 }
0129
0130 static struct data data_append_markers(struct data d, struct marker *m)
0131 {
0132 struct marker **mp = &d.markers;
0133
0134
0135 while (*mp)
0136 mp = &((*mp)->next);
0137 *mp = m;
0138 return d;
0139 }
0140
0141 struct data data_merge(struct data d1, struct data d2)
0142 {
0143 struct data d;
0144 struct marker *m2 = d2.markers;
0145
0146 d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
0147
0148
0149 for_each_marker(m2)
0150 m2->offset += d1.len;
0151
0152 d2.markers = NULL;
0153 data_free(d2);
0154
0155 return d;
0156 }
0157
0158 struct data data_append_integer(struct data d, uint64_t value, int bits)
0159 {
0160 uint8_t value_8;
0161 fdt16_t value_16;
0162 fdt32_t value_32;
0163 fdt64_t value_64;
0164
0165 switch (bits) {
0166 case 8:
0167 value_8 = value;
0168 return data_append_data(d, &value_8, 1);
0169
0170 case 16:
0171 value_16 = cpu_to_fdt16(value);
0172 return data_append_data(d, &value_16, 2);
0173
0174 case 32:
0175 value_32 = cpu_to_fdt32(value);
0176 return data_append_data(d, &value_32, 4);
0177
0178 case 64:
0179 value_64 = cpu_to_fdt64(value);
0180 return data_append_data(d, &value_64, 8);
0181
0182 default:
0183 die("Invalid literal size (%d)\n", bits);
0184 }
0185 }
0186
0187 struct data data_append_re(struct data d, uint64_t address, uint64_t size)
0188 {
0189 struct fdt_reserve_entry re;
0190
0191 re.address = cpu_to_fdt64(address);
0192 re.size = cpu_to_fdt64(size);
0193
0194 return data_append_data(d, &re, sizeof(re));
0195 }
0196
0197 struct data data_append_cell(struct data d, cell_t word)
0198 {
0199 return data_append_integer(d, word, sizeof(word) * 8);
0200 }
0201
0202 struct data data_append_addr(struct data d, uint64_t addr)
0203 {
0204 return data_append_integer(d, addr, sizeof(addr) * 8);
0205 }
0206
0207 struct data data_append_byte(struct data d, uint8_t byte)
0208 {
0209 return data_append_data(d, &byte, 1);
0210 }
0211
0212 struct data data_append_zeroes(struct data d, int len)
0213 {
0214 d = data_grow_for(d, len);
0215
0216 memset(d.val + d.len, 0, len);
0217 d.len += len;
0218 return d;
0219 }
0220
0221 struct data data_append_align(struct data d, int align)
0222 {
0223 int newlen = ALIGN(d.len, align);
0224 return data_append_zeroes(d, newlen - d.len);
0225 }
0226
0227 struct data data_add_marker(struct data d, enum markertype type, char *ref)
0228 {
0229 struct marker *m;
0230
0231 m = xmalloc(sizeof(*m));
0232 m->offset = d.len;
0233 m->type = type;
0234 m->ref = ref;
0235 m->next = NULL;
0236
0237 return data_append_markers(d, m);
0238 }
0239
0240 bool data_is_one_string(struct data d)
0241 {
0242 int i;
0243 int len = d.len;
0244
0245 if (len == 0)
0246 return false;
0247
0248 for (i = 0; i < len-1; i++)
0249 if (d.val[i] == '\0')
0250 return false;
0251
0252 if (d.val[len-1] != '\0')
0253 return false;
0254
0255 return true;
0256 }