data.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
  3. *
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  18. * USA
  19. */
  20. #include "dtc.h"
  21. void data_free(struct data d)
  22. {
  23. struct marker *m, *nm;
  24. m = d.markers;
  25. while (m) {
  26. nm = m->next;
  27. free(m->ref);
  28. free(m);
  29. m = nm;
  30. }
  31. if (d.val)
  32. free(d.val);
  33. }
  34. struct data data_grow_for(struct data d, int xlen)
  35. {
  36. struct data nd;
  37. int newsize;
  38. if (xlen == 0)
  39. return d;
  40. nd = d;
  41. newsize = xlen;
  42. while ((d.len + xlen) > newsize)
  43. newsize *= 2;
  44. nd.val = xrealloc(d.val, newsize);
  45. return nd;
  46. }
  47. struct data data_copy_mem(const char *mem, int len)
  48. {
  49. struct data d;
  50. d = data_grow_for(empty_data, len);
  51. d.len = len;
  52. memcpy(d.val, mem, len);
  53. return d;
  54. }
  55. struct data data_copy_escape_string(const char *s, int len)
  56. {
  57. int i = 0;
  58. struct data d;
  59. char *q;
  60. d = data_grow_for(empty_data, len + 1);
  61. q = d.val;
  62. while (i < len) {
  63. char c = s[i++];
  64. if (c == '\\')
  65. c = get_escape_char(s, &i);
  66. q[d.len++] = c;
  67. }
  68. q[d.len++] = '\0';
  69. return d;
  70. }
  71. struct data data_copy_file(FILE *f, size_t maxlen)
  72. {
  73. struct data d = empty_data;
  74. while (!feof(f) && (d.len < maxlen)) {
  75. size_t chunksize, ret;
  76. if (maxlen == -1)
  77. chunksize = 4096;
  78. else
  79. chunksize = maxlen - d.len;
  80. d = data_grow_for(d, chunksize);
  81. ret = fread(d.val + d.len, 1, chunksize, f);
  82. if (ferror(f))
  83. die("Error reading file into data: %s", strerror(errno));
  84. if (d.len + ret < d.len)
  85. die("Overflow reading file into data\n");
  86. d.len += ret;
  87. }
  88. return d;
  89. }
  90. struct data data_append_data(struct data d, const void *p, int len)
  91. {
  92. d = data_grow_for(d, len);
  93. memcpy(d.val + d.len, p, len);
  94. d.len += len;
  95. return d;
  96. }
  97. struct data data_insert_at_marker(struct data d, struct marker *m,
  98. const void *p, int len)
  99. {
  100. d = data_grow_for(d, len);
  101. memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
  102. memcpy(d.val + m->offset, p, len);
  103. d.len += len;
  104. /* Adjust all markers after the one we're inserting at */
  105. m = m->next;
  106. for_each_marker(m)
  107. m->offset += len;
  108. return d;
  109. }
  110. static struct data data_append_markers(struct data d, struct marker *m)
  111. {
  112. struct marker **mp = &d.markers;
  113. /* Find the end of the markerlist */
  114. while (*mp)
  115. mp = &((*mp)->next);
  116. *mp = m;
  117. return d;
  118. }
  119. struct data data_merge(struct data d1, struct data d2)
  120. {
  121. struct data d;
  122. struct marker *m2 = d2.markers;
  123. d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
  124. /* Adjust for the length of d1 */
  125. for_each_marker(m2)
  126. m2->offset += d1.len;
  127. d2.markers = NULL; /* So data_free() doesn't clobber them */
  128. data_free(d2);
  129. return d;
  130. }
  131. struct data data_append_integer(struct data d, uint64_t value, int bits)
  132. {
  133. uint8_t value_8;
  134. fdt16_t value_16;
  135. fdt32_t value_32;
  136. fdt64_t value_64;
  137. switch (bits) {
  138. case 8:
  139. value_8 = value;
  140. return data_append_data(d, &value_8, 1);
  141. case 16:
  142. value_16 = cpu_to_fdt16(value);
  143. return data_append_data(d, &value_16, 2);
  144. case 32:
  145. value_32 = cpu_to_fdt32(value);
  146. return data_append_data(d, &value_32, 4);
  147. case 64:
  148. value_64 = cpu_to_fdt64(value);
  149. return data_append_data(d, &value_64, 8);
  150. default:
  151. die("Invalid literal size (%d)\n", bits);
  152. }
  153. }
  154. struct data data_append_re(struct data d, uint64_t address, uint64_t size)
  155. {
  156. struct fdt_reserve_entry re;
  157. re.address = cpu_to_fdt64(address);
  158. re.size = cpu_to_fdt64(size);
  159. return data_append_data(d, &re, sizeof(re));
  160. }
  161. struct data data_append_cell(struct data d, cell_t word)
  162. {
  163. return data_append_integer(d, word, sizeof(word) * 8);
  164. }
  165. struct data data_append_addr(struct data d, uint64_t addr)
  166. {
  167. return data_append_integer(d, addr, sizeof(addr) * 8);
  168. }
  169. struct data data_append_byte(struct data d, uint8_t byte)
  170. {
  171. return data_append_data(d, &byte, 1);
  172. }
  173. struct data data_append_zeroes(struct data d, int len)
  174. {
  175. d = data_grow_for(d, len);
  176. memset(d.val + d.len, 0, len);
  177. d.len += len;
  178. return d;
  179. }
  180. struct data data_append_align(struct data d, int align)
  181. {
  182. int newlen = ALIGN(d.len, align);
  183. return data_append_zeroes(d, newlen - d.len);
  184. }
  185. struct data data_add_marker(struct data d, enum markertype type, char *ref)
  186. {
  187. struct marker *m;
  188. m = xmalloc(sizeof(*m));
  189. m->offset = d.len;
  190. m->type = type;
  191. m->ref = ref;
  192. m->next = NULL;
  193. return data_append_markers(d, m);
  194. }
  195. bool data_is_one_string(struct data d)
  196. {
  197. int i;
  198. int len = d.len;
  199. if (len == 0)
  200. return false;
  201. for (i = 0; i < len-1; i++)
  202. if (d.val[i] == '\0')
  203. return false;
  204. if (d.val[len-1] != '\0')
  205. return false;
  206. return true;
  207. }