aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dtc/libfdt/fdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/dtc/libfdt/fdt.c')
-rw-r--r--scripts/dtc/libfdt/fdt.c61
1 files changed, 41 insertions, 20 deletions
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
index 2acaec5923ae..e56833ae9b6f 100644
--- a/scripts/dtc/libfdt/fdt.c
+++ b/scripts/dtc/libfdt/fdt.c
@@ -74,7 +74,7 @@ int fdt_check_header(const void *fdt)
74 return 0; 74 return 0;
75} 75}
76 76
77const void *fdt_offset_ptr(const void *fdt, int offset, int len) 77const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
78{ 78{
79 const char *p; 79 const char *p;
80 80
@@ -90,42 +90,53 @@ const void *fdt_offset_ptr(const void *fdt, int offset, int len)
90 return p; 90 return p;
91} 91}
92 92
93uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset) 93uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
94{ 94{
95 const uint32_t *tagp, *lenp; 95 const uint32_t *tagp, *lenp;
96 uint32_t tag; 96 uint32_t tag;
97 int offset = startoffset;
97 const char *p; 98 const char *p;
98 99
99 if (offset % FDT_TAGSIZE) 100 *nextoffset = -FDT_ERR_TRUNCATED;
100 return -1;
101
102 tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); 101 tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
103 if (! tagp) 102 if (!tagp)
104 return FDT_END; /* premature end */ 103 return FDT_END; /* premature end */
105 tag = fdt32_to_cpu(*tagp); 104 tag = fdt32_to_cpu(*tagp);
106 offset += FDT_TAGSIZE; 105 offset += FDT_TAGSIZE;
107 106
107 *nextoffset = -FDT_ERR_BADSTRUCTURE;
108 switch (tag) { 108 switch (tag) {
109 case FDT_BEGIN_NODE: 109 case FDT_BEGIN_NODE:
110 /* skip name */ 110 /* skip name */
111 do { 111 do {
112 p = fdt_offset_ptr(fdt, offset++, 1); 112 p = fdt_offset_ptr(fdt, offset++, 1);
113 } while (p && (*p != '\0')); 113 } while (p && (*p != '\0'));
114 if (! p) 114 if (!p)
115 return FDT_END; 115 return FDT_END; /* premature end */
116 break; 116 break;
117
117 case FDT_PROP: 118 case FDT_PROP:
118 lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); 119 lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
119 if (! lenp) 120 if (!lenp)
120 return FDT_END; 121 return FDT_END; /* premature end */
121 /* skip name offset, length and value */ 122 /* skip-name offset, length and value */
122 offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp); 123 offset += sizeof(struct fdt_property) - FDT_TAGSIZE
124 + fdt32_to_cpu(*lenp);
125 break;
126
127 case FDT_END:
128 case FDT_END_NODE:
129 case FDT_NOP:
123 break; 130 break;
131
132 default:
133 return FDT_END;
124 } 134 }
125 135
126 if (nextoffset) 136 if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
127 *nextoffset = FDT_TAGALIGN(offset); 137 return FDT_END; /* premature end */
128 138
139 *nextoffset = FDT_TAGALIGN(offset);
129 return tag; 140 return tag;
130} 141}
131 142
@@ -138,6 +149,15 @@ int _fdt_check_node_offset(const void *fdt, int offset)
138 return offset; 149 return offset;
139} 150}
140 151
152int _fdt_check_prop_offset(const void *fdt, int offset)
153{
154 if ((offset < 0) || (offset % FDT_TAGSIZE)
155 || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
156 return -FDT_ERR_BADOFFSET;
157
158 return offset;
159}
160
141int fdt_next_node(const void *fdt, int offset, int *depth) 161int fdt_next_node(const void *fdt, int offset, int *depth)
142{ 162{
143 int nextoffset = 0; 163 int nextoffset = 0;
@@ -162,15 +182,16 @@ int fdt_next_node(const void *fdt, int offset, int *depth)
162 break; 182 break;
163 183
164 case FDT_END_NODE: 184 case FDT_END_NODE:
165 if (depth) 185 if (depth && ((--(*depth)) < 0))
166 (*depth)--; 186 return nextoffset;
167 break; 187 break;
168 188
169 case FDT_END: 189 case FDT_END:
170 return -FDT_ERR_NOTFOUND; 190 if ((nextoffset >= 0)
171 191 || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
172 default: 192 return -FDT_ERR_NOTFOUND;
173 return -FDT_ERR_BADSTRUCTURE; 193 else
194 return nextoffset;
174 } 195 }
175 } while (tag != FDT_BEGIN_NODE); 196 } while (tag != FDT_BEGIN_NODE);
176 197