1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-27 23:22:37 +02:00

layout: Use linked list for struct romentry

This gets rid of the entry limit and hopefully makes future layout
handling easier. We start by making `struct flashrom_layout` private
to `layout.c`.

Change-Id: I60a0aa1007ebcd5eb401db116f835d129b3e9732
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/33521
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Nico Huber 2019-06-15 21:41:21 +02:00
parent a1afc84156
commit 953c5ad440
3 changed files with 51 additions and 71 deletions

106
layout.c
View File

@ -25,12 +25,17 @@
#include "programmer.h" #include "programmer.h"
#include "layout.h" #include "layout.h"
static struct romentry entries[MAX_ROMLAYOUT]; struct flashrom_layout {
static struct flashrom_layout global_layout = { entries, MAX_ROMLAYOUT, 0 }; struct romentry *head;
};
static struct flashrom_layout *global_layout;
struct flashrom_layout *get_global_layout(void) struct flashrom_layout *get_global_layout(void)
{ {
return &global_layout; if (!global_layout)
flashrom_layout_new(&global_layout, 0);
return global_layout;
} }
const struct flashrom_layout *get_default_layout(const struct flashrom_flashctx *const flashctx) const struct flashrom_layout *get_default_layout(const struct flashrom_flashctx *const flashctx)
@ -40,7 +45,7 @@ const struct flashrom_layout *get_default_layout(const struct flashrom_flashctx
const struct flashrom_layout *get_layout(const struct flashrom_flashctx *const flashctx) const struct flashrom_layout *get_layout(const struct flashrom_flashctx *const flashctx)
{ {
if (flashctx->layout && flashctx->layout->num_entries) if (flashctx->layout)
return flashctx->layout; return flashctx->layout;
else else
return get_default_layout(flashctx); return get_default_layout(flashctx);
@ -49,16 +54,7 @@ const struct flashrom_layout *get_layout(const struct flashrom_flashctx *const f
static struct romentry *mutable_layout_next( static struct romentry *mutable_layout_next(
const struct flashrom_layout *const layout, struct romentry *iterator) const struct flashrom_layout *const layout, struct romentry *iterator)
{ {
const struct romentry *const end = layout->entries + layout->num_entries; return iterator ? iterator->next : layout->head;
if (iterator)
++iterator;
else
iterator = &layout->entries[0];
if (iterator < end)
return iterator;
return NULL;
} }
static struct romentry *_layout_entry_by_name( static struct romentry *_layout_entry_by_name(
@ -91,11 +87,6 @@ int read_romlayout(const char *name)
while (!feof(romlayout)) { while (!feof(romlayout)) {
char *tstr1, *tstr2; char *tstr1, *tstr2;
if (layout->num_entries >= layout->capacity) {
msg_gerr("Maximum number of ROM images (%zu) in layout "
"file reached.\n", layout->capacity);
goto _close_ret;
}
if (2 != fscanf(romlayout, "%255s %255s\n", tempstr, tempname)) if (2 != fscanf(romlayout, "%255s %255s\n", tempstr, tempname))
continue; continue;
#if 0 #if 0
@ -186,7 +177,7 @@ static int include_region(struct flashrom_layout *const l, const char *name,
/* returns -1 if an entry is not found, 0 if found. */ /* returns -1 if an entry is not found, 0 if found. */
static int find_romentry(struct flashrom_layout *const l, char *name, char *file) static int find_romentry(struct flashrom_layout *const l, char *name, char *file)
{ {
if (l->num_entries == 0) if (!l->head)
return -1; return -1;
msg_gspew("Looking for region \"%s\"... ", name); msg_gspew("Looking for region \"%s\"... ", name);
@ -222,7 +213,7 @@ int process_include_args(struct flashrom_layout *l, const struct layout_include_
return 0; return 0;
/* User has specified an include argument, but no layout is loaded. */ /* User has specified an include argument, but no layout is loaded. */
if (l->num_entries == 0) { if (!l->head) {
msg_gerr("Region requested (with -i \"%s\"), " msg_gerr("Region requested (with -i \"%s\"), "
"but no layout data is available.\n", "but no layout data is available.\n",
args->name); args->name);
@ -287,7 +278,6 @@ int included_regions_overlap(const struct flashrom_layout *const l)
void layout_cleanup(struct layout_include_args **args) void layout_cleanup(struct layout_include_args **args)
{ {
struct flashrom_layout *const layout = get_global_layout(); struct flashrom_layout *const layout = get_global_layout();
unsigned int i;
struct layout_include_args *tmp; struct layout_include_args *tmp;
while (*args) { while (*args) {
@ -298,12 +288,8 @@ void layout_cleanup(struct layout_include_args **args)
*args = tmp; *args = tmp;
} }
for (i = 0; i < layout->num_entries; i++) { global_layout = NULL;
free(layout->entries[i].name); flashrom_layout_release(layout);
free(layout->entries[i].file);
layout->entries[i].included = false;
}
layout->num_entries = 0;
} }
/* Validate and - if needed - normalize layout entries. */ /* Validate and - if needed - normalize layout entries. */
@ -380,7 +366,7 @@ const struct romentry *layout_next_included(
const struct romentry *layout_next( const struct romentry *layout_next(
const struct flashrom_layout *const layout, const struct romentry *iterator) const struct flashrom_layout *const layout, const struct romentry *iterator)
{ {
return mutable_layout_next(layout, (struct romentry *)iterator); return iterator ? iterator->next : layout->head;
} }
/** /**
@ -399,17 +385,13 @@ const struct romentry *layout_next(
*/ */
int flashrom_layout_new(struct flashrom_layout **const layout, const unsigned int count) int flashrom_layout_new(struct flashrom_layout **const layout, const unsigned int count)
{ {
*layout = malloc(sizeof(**layout) + count * sizeof(struct romentry)); *layout = malloc(sizeof(**layout));
if (!*layout) { if (!*layout) {
msg_gerr("Error creating layout: %s\n", strerror(errno)); msg_gerr("Error creating layout: %s\n", strerror(errno));
return 1; return 1;
} }
const struct flashrom_layout tmp = { const struct flashrom_layout tmp = { 0 };
.entries = (void *)((char *)*layout + sizeof(**layout)),
.capacity = count,
.num_entries = 0,
};
**layout = tmp; **layout = tmp;
return 0; return 0;
} }
@ -423,32 +405,36 @@ int flashrom_layout_new(struct flashrom_layout **const layout, const unsigned in
* @param name Name of the region. * @param name Name of the region.
* *
* @return 0 on success, * @return 0 on success,
* 1 if out of memory, * 1 if out of memory.
* 2 if the layout is full already.
*/ */
int flashrom_layout_add_region( int flashrom_layout_add_region(
struct flashrom_layout *const layout, struct flashrom_layout *const layout,
const size_t start, const size_t end, const char *const name) const size_t start, const size_t end, const char *const name)
{ {
if (layout->num_entries >= layout->capacity) { struct romentry *const entry = malloc(sizeof(*entry));
msg_gerr("Error adding layout entry: No space left\n"); if (!entry)
return 2; goto _err_ret;
}
struct romentry *const entry = &layout->entries[layout->num_entries]; const struct romentry tmp = {
entry->start = start; .next = layout->head,
entry->end = end; .start = start,
entry->included = false; .end = end,
entry->name = strdup(name); .included = false,
entry->file = NULL; .name = strdup(name),
if (!entry->name) { .file = NULL,
msg_gerr("Error adding layout entry: %s\n", strerror(errno)); };
return 1; *entry = tmp;
} if (!entry->name)
goto _err_ret;
msg_gdbg("Added layout entry %08zx - %08zx named %s\n", start, end, name); msg_gdbg("Added layout entry %08zx - %08zx named %s\n", start, end, name);
++layout->num_entries; layout->head = entry;
return 0; return 0;
_err_ret:
msg_gerr("Error adding layout entry: %s\n", strerror(errno));
free(entry);
return 1;
} }
/** /**
@ -472,14 +458,18 @@ int flashrom_layout_include_region(struct flashrom_layout *const layout, const c
*/ */
void flashrom_layout_release(struct flashrom_layout *const layout) void flashrom_layout_release(struct flashrom_layout *const layout)
{ {
unsigned int i; if (layout == global_layout)
if (!layout || layout == get_global_layout())
return; return;
for (i = 0; i < layout->num_entries; ++i) { if (!layout)
free(layout->entries[i].name); return;
free(layout->entries[i].file);
while (layout->head) {
struct romentry *const entry = layout->head;
layout->head = entry->next;
free(entry->file);
free(entry->name);
free(entry);
} }
free(layout); free(layout);
} }

View File

@ -36,6 +36,8 @@ typedef uint32_t chipsize_t; /* Able to store the number of bytes of any support
#define MAX_ROMLAYOUT 128 #define MAX_ROMLAYOUT 128
struct romentry { struct romentry {
struct romentry *next;
chipoff_t start; chipoff_t start;
chipoff_t end; chipoff_t end;
bool included; bool included;
@ -43,14 +45,7 @@ struct romentry {
char *file; char *file;
}; };
struct flashrom_layout { struct flashrom_layout;
/* entries store the entries specified in a layout file and associated run-time data */
struct romentry *entries;
/* the maximum number of entries */
size_t capacity;
/* the number of successfully parsed entries */
size_t num_entries;
};
struct layout_include_args { struct layout_include_args {
char *name; char *name;

View File

@ -505,11 +505,6 @@ static int flashrom_layout_parse_fmap(struct flashrom_layout **layout,
if (!fmap || !l) if (!fmap || !l)
return 1; return 1;
if (l->num_entries + fmap->nareas > l->capacity) {
msg_gerr("Cannot add fmap entries to layout - Too many entries.\n");
return 1;
}
for (i = 0, area = fmap->areas; i < fmap->nareas; i++, area++) { for (i = 0, area = fmap->areas; i < fmap->nareas; i++, area++) {
snprintf(name, sizeof(name), "%s", area->name); snprintf(name, sizeof(name), "%s", area->name);
if (flashrom_layout_add_region(l, area->offset, area->offset + area->size - 1, name)) if (flashrom_layout_add_region(l, area->offset, area->offset + area->size - 1, name))