| /* |
| * fmap_sections.c, track which sections of the image will contain CBFSes |
| * |
| * Copyright (C) 2015 Google, Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; version 2 of the License. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA |
| */ |
| |
| #include "cbfs_sections.h" |
| |
| #include <assert.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| struct descriptor_node { |
| const struct flashmap_descriptor *val; |
| struct descriptor_node *next; |
| }; |
| |
| static struct descriptor_list { |
| struct descriptor_node *head; |
| struct descriptor_node *tail; |
| } cbfs_sections; |
| |
| static bool seen_primary_section = false; |
| |
| static void descriptor_list_prepend(struct descriptor_list *list, |
| struct descriptor_node *new_head) |
| { |
| assert(list); |
| assert(new_head); |
| |
| new_head->next = list->head; |
| list->head = new_head; |
| if (!list->tail) |
| list->tail = new_head; |
| } |
| |
| static void descriptor_list_append(struct descriptor_list *list, |
| struct descriptor_node *new_tail) |
| { |
| assert(list); |
| assert(new_tail); |
| |
| if (list->tail) |
| list->tail->next = new_tail; |
| list->tail = new_tail; |
| if (!list->head) |
| list->head = new_tail; |
| } |
| |
| /* Implementation of cbfs module's callback; invoked during fmd file parsing */ |
| bool fmd_process_annotation_impl(const struct flashmap_descriptor *node, |
| const char *annotation) |
| { |
| if (strcmp(annotation, SECTION_ANNOTATION_CBFS) == 0 && |
| node->list_len == 0) { |
| struct descriptor_node *list_node = malloc(sizeof(*list_node)); |
| list_node->val = node; |
| list_node->next = NULL; |
| |
| if (strcmp(node->name, SECTION_NAME_PRIMARY_CBFS) == 0) { |
| descriptor_list_prepend(&cbfs_sections, list_node); |
| seen_primary_section = true; |
| } else { |
| descriptor_list_append(&cbfs_sections, list_node); |
| } |
| |
| return true; |
| } |
| |
| return false; |
| } |
| |
| cbfs_section_iterator_t cbfs_sections_iterator(void) |
| { |
| return cbfs_sections.head; |
| } |
| |
| bool cbfs_sections_iterator_advance(cbfs_section_iterator_t *it) |
| { |
| assert(it); |
| if (!*it) |
| return false; |
| |
| *it = (*it)->next; |
| return true; |
| } |
| |
| const struct flashmap_descriptor *cbfs_sections_iterator_deref( |
| cbfs_section_iterator_t it) |
| { |
| assert(it); |
| return it->val; |
| } |
| |
| bool cbfs_sections_primary_cbfs_accounted_for(void) |
| { |
| return seen_primary_section; |
| } |
| |
| void cbfs_sections_cleanup(void) |
| { |
| for (struct descriptor_node *cur = cbfs_sections.head, *next = NULL; |
| cur; cur = next) { |
| next = cur->next; |
| free(cur); |
| } |
| cbfs_sections.head = NULL; |
| cbfs_sections.tail = NULL; |
| } |