[OpenBIOS] [PATCH] bootinfo_init_program: improve memory allocation efficiency
Cormac O'Brien
i.am.cormac.obrien at gmail.com
Sun Apr 19 23:41:19 CEST 2015
The '\r'->'\n' hack is inserted here:
> while (current < scriptstart + scriptlen) {
> c = base[current++];
>
> if (c == '\r') {
> c = '\n';
> }
>
> if (c == '&') {
On Sun, Apr 19, 2015 at 4:36 PM, Cormac O'Brien
<i.am.cormac.obrien at gmail.com> wrote:
> Here's v2, with the debug macro untouched.
>
> ---
> libopenbios/bootinfo_load.c | 100 +++++++++++++++++++++++++++++---------------
> 1 file changed, 66 insertions(+), 34 deletions(-)
>
> diff --git a/libopenbios/bootinfo_load.c b/libopenbios/bootinfo_load.c
> index fa9e36b..855b5dc 100644
> --- a/libopenbios/bootinfo_load.c
> +++ b/libopenbios/bootinfo_load.c
> @@ -134,12 +134,13 @@ bootinfo_init_program(void)
> char *base;
> int proplen;
> phandle_t chosen;
> - int tag, taglen, script, scriptlen, scriptvalid, entity, chrp;
> + int tag, taglen, script, scriptind, scriptlen, scriptstart, scriptvalid,
> + entity, chrp;
> char tagbuf[128], c;
> char *device, *filename, *directory, *partition;
> int current, size;
> char *bootscript;
> - char *tmp;
> + char *tmp;
> char bootpath[1024];
>
> /* Parse the boot script */
> @@ -158,21 +159,14 @@ bootinfo_init_program(void)
> feval("load-base");
> base = (char*)cell2pointer(POP());
>
> - feval("load-size");
> - size = POP();
> -
> - bootscript = malloc(size);
> - if (bootscript == NULL) {
> - DPRINTF("Can't malloc %d bytes\n", size);
> - return;
> - }
> -
> if (!is_bootinfo(base)) {
> DPRINTF("Not a valid bootinfo memory image\n");
> - free(bootscript);
> return;
> }
>
> + feval("load-size");
> + size = POP();
> +
> chrp = 0;
> tag = 0;
> taglen = 0;
> @@ -198,16 +192,10 @@ bootinfo_init_program(void)
> if (strncasecmp(tagbuf, "boot-script", 11) == 0) {
> script = 1;
> scriptlen = 0;
> + scriptstart = current;
> } else if (strncasecmp(tagbuf, "/boot-script", 12) == 0) {
> -
> script = 0;
> - bootscript[scriptlen] = '\0';
> -
> - DPRINTF("got bootscript %s\n",
> - bootscript);
> -
> scriptvalid = -1;
> -
> break;
> } else if (strncasecmp(tagbuf, "/chrp-boot", 10) == 0)
> break;
> @@ -217,42 +205,86 @@ bootinfo_init_program(void)
> } else if (script && c == '&') {
> entity = 1;
> taglen = 0;
> - } else if (entity && c ==';') {
> + } else if (entity && c == ';') {
> entity = 0;
> tagbuf[taglen] = '\0';
> if (strncasecmp(tagbuf, "lt", 2) == 0) {
> - bootscript[scriptlen++] = '<';
> + scriptlen++;
> } else if (strncasecmp(tagbuf, "gt", 2) == 0) {
> - bootscript[scriptlen++] = '>';
> + scriptlen++;
> } else if (strncasecmp(tagbuf, "device", 6) == 0) {
> - strcpy(bootscript + scriptlen, device);
> scriptlen += strlen(device);
> } else if (strncasecmp(tagbuf, "partition", 9) == 0) {
> - strcpy(bootscript + scriptlen, partition);
> scriptlen += strlen(partition);
> } else if (strncasecmp(tagbuf, "directory", 9) == 0) {
> - strcpy(bootscript + scriptlen, directory);
> scriptlen += strlen(directory);
> } else if (strncasecmp(tagbuf, "filename", 8) == 0) {
> - strcpy(bootscript + scriptlen, filename);
> scriptlen += strlen(filename);
> } else if (strncasecmp(tagbuf, "full-path", 9) == 0) {
> - strcpy(bootscript + scriptlen, bootpath);
> scriptlen += strlen(bootpath);
> - } else { /* unknown, keep it */
> - bootscript[scriptlen] = '&';
> - strcpy(bootscript + scriptlen + 1, tagbuf);
> - scriptlen += taglen + 1;
> - bootscript[scriptlen] = ';';
> - scriptlen++;
> + } else {
> + scriptlen += taglen + 2;
> }
> } else if (entity && taglen < sizeof(tagbuf)) {
> tagbuf[taglen++] = c;
> } else if (script && scriptlen < size) {
> - bootscript[scriptlen++] = c;
> + scriptlen++;
> + }
> + }
> +
> + bootscript = malloc(scriptlen * sizeof *bootscript + 1);
> + if (bootscript == NULL) {
> + DPRINTF("Can't malloc %d bytes\n", size);
> + return;
> + }
> +
> + entity = 0;
> + scriptind = 0;
> + taglen = 0;
> + current = scriptstart;
> + while (current < scriptstart + scriptlen) {
> + c = base[current++];
> +
> + if (c == '&') {
> + entity = 1;
> + taglen = 0;
> + } else if (entity && c == ';') {
> + entity = 0;
> + tagbuf[taglen] = '\0';
> + if (strncasecmp(tagbuf, "lt", 2) == 0) {
> + bootscript[scriptind++] = '<';
> + } else if (strncasecmp(tagbuf, "gt", 2) == 0) {
> + bootscript[scriptind++] = '>';
> + } else if (strncasecmp(tagbuf, "device", 6) == 0) {
> + strcpy(bootscript + scriptind, device);
> + scriptind += strlen(device);
> + } else if (strncasecmp(tagbuf, "partition", 9) == 0) {
> + strcpy(bootscript + scriptind, partition);
> + scriptind += strlen(partition);
> + } else if (strncasecmp(tagbuf, "directory", 9) == 0) {
> + strcpy(bootscript + scriptind, directory);
> + scriptind += strlen(directory);
> + } else if (strncasecmp(tagbuf, "filename", 8) == 0) {
> + strcpy(bootscript + scriptind, filename);
> + scriptlen += strlen(filename);
> + } else if (strncasecmp(tagbuf, "full-path", 9) == 0) {
> + strcpy(bootscript + scriptind, bootpath);
> + scriptlen += strlen(bootscript);
> + } else { /* unknown, keep it */
> + bootscript[scriptind++] = '&';
> + strcpy(bootscript + scriptind, tagbuf);
> + scriptind += taglen;
> + bootscript[scriptind++] = ';';
> + }
> + } else if (entity && taglen < sizeof(tagbuf)) {
> + tagbuf[taglen++] = c;
> + } else {
> + bootscript[scriptind++] = c;
> }
> }
>
> + bootscript[scriptlen] = '\0';
> +
> /* If the payload is bootinfo then we execute it immediately */
> if (scriptvalid) {
> DPRINTF("bootscript: %s\n", bootscript);
> --
> 2.3.5
>
More information about the OpenBIOS
mailing list