| 149 | } |
| 150 | |
| 151 | static int parse_header(void *addr, int len) |
| 152 | { |
| 153 | struct cb_header *header; |
| 154 | unsigned char *ptr = (unsigned char *)addr; |
| 155 | int i; |
| 156 | |
| 157 | for (i = 0; i < len; i += 16, ptr += 16) { |
| 158 | header = (struct cb_header *)ptr; |
| 159 | |
| 160 | if (!strncmp((const char *)header->signature, "LBIO", 4)) |
| 161 | break; |
| 162 | } |
| 163 | |
| 164 | /* We walked the entire space and didn't find anything. */ |
| 165 | if (i >= len) |
| 166 | return -1; |
| 167 | |
| 168 | if (!header->table_bytes) |
| 169 | return 0; |
| 170 | |
| 171 | /* FIXME: Check the checksum. */ |
| 172 | |
| 173 | if (cb_checksum(header, sizeof(*header))) |
| 174 | return -1; |
| 175 | |
| 176 | if (cb_checksum((ptr + sizeof(*header)), header->table_bytes) |
| 177 | != header->table_checksum) |
| 178 | return -1; |
| 179 | |
| 180 | /* Now, walk the tables. */ |
| 181 | ptr += header->header_bytes; |
| 182 | |
| 183 | for (u32 j = 0; j < header->table_entries; j++) { |
| 184 | struct cb_record *rec = (struct cb_record *)ptr; |
| 185 | |
| 186 | switch (rec->tag) { |
| 187 | case CB_TAG_FORWARD: |
| 188 | return parse_header((void *)(unsigned long)((struct cb_forward *)rec)->forward, 1); |
| 189 | case CB_TAG_MEMORY: |
| 190 | parse_memory(ptr); |
| 191 | break; |
| 192 | case CB_TAG_MAINBOARD: |
| 193 | parse_mainboard(ptr); |
| 194 | break; |
| 195 | case CB_TAG_VERSION: |
| 196 | case CB_TAG_EXTRA_VERSION: |
| 197 | case CB_TAG_BUILD: |
| 198 | case CB_TAG_COMPILE_TIME: |
| 199 | case CB_TAG_COMPILE_BY: |
| 200 | case CB_TAG_COMPILE_HOST: |
| 201 | case CB_TAG_COMPILE_DOMAIN: |
| 202 | case CB_TAG_COMPILER: |
| 203 | case CB_TAG_LINKER: |
| 204 | case CB_TAG_ASSEMBLER: |
| 205 | parse_strings(ptr); |
| 206 | break; |
| 207 | case CB_TAG_SERIAL: |
| 208 | parse_serial(ptr); |
no test coverage detected