Mercurial > hg > index.cgi
changeset 564:87f904e2b304
Add offset and length operands (optional) to includebin
This addition is based on a patch from Tim Lindner <tlindner@macmess.org>.
While the original logic of the patch was not quite correct, the basic idea
is. So with some edits to the logic, the feature goes in.
author | William Astle <lost@l-w.ca> |
---|---|
date | Thu, 21 Dec 2023 22:14:25 -0700 |
parents | 8c6c3363e18e |
children | fc072f6cde09 |
files | lwasm/instab.c lwasm/lwasm.c lwasm/lwasm.h lwasm/pseudo.c |
diffstat | 4 files changed, 94 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/lwasm/instab.c Fri Dec 01 21:16:54 2023 -0700 +++ b/lwasm/instab.c Thu Dec 21 22:14:25 2023 -0700 @@ -317,7 +317,7 @@ #define pseudo_emit_export NULL PARSEFUNC(pseudo_parse_includebin); -#define pseudo_resolve_includebin NULL +RESOLVEFUNC(pseudo_resolve_includebin); EMITFUNC(pseudo_emit_includebin); PARSEFUNC(pseudo_parse_includestr);
--- a/lwasm/lwasm.c Fri Dec 01 21:16:54 2023 -0700 +++ b/lwasm/lwasm.c Thu Dec 21 22:14:25 2023 -0700 @@ -284,6 +284,8 @@ case E_COMPLEX_INCOMPLETE: return "Incomplete expression too complex"; case E_USER_SPECIFIED: return "User Specified:"; case E_ILL5: return "Illegal 5 bit offset"; + case E_INCLUDEBIN_ILL_START: return "Start value out of range"; + case E_INCLUDEBIN_ILL_LENGTH: return "Length value out of range"; case W_ENDSTRUCT_WITHOUT: return "ENDSTRUCT without STRUCT"; case W_DUPLICATE_SECTION: return "Section flags can only be specified the first time; ignoring duplicate definition";
--- a/lwasm/lwasm.h Fri Dec 01 21:16:54 2023 -0700 +++ b/lwasm/lwasm.h Thu Dec 21 22:14:25 2023 -0700 @@ -216,6 +216,8 @@ E_ORG_NOT_FOUND = 57, E_COMPLEX_INCOMPLETE = 58, E_ILL5 = 59, + E_INCLUDEBIN_ILL_START = 60, + E_INCLUDEBIN_ILL_LENGTH = 61, /* warnings must be 1000 or greater */
--- a/lwasm/pseudo.c Fri Dec 01 21:16:54 2023 -0700 +++ b/lwasm/pseudo.c Thu Dec 21 22:14:25 2023 -0700 @@ -1482,7 +1482,8 @@ FILE *fp; long flen; char *rfn; - + lw_expr_t e, e1; + if (!**p) { lwasm_register_error(as, l, E_FILENAME_MISSING); @@ -1522,12 +1523,94 @@ fclose(fp); l -> len = flen; + + if (**p == ',') + { + (*p)++; + e = lwasm_parse_expr(as, p); + + if (e) + lwasm_save_expr(l, 0, e); + + if (**p == ',') + { + (*p)++; + e1 = lwasm_parse_expr(as, p); + + if (e1) + lwasm_save_expr(l, 1, e1); + } + } +} + +RESOLVEFUNC(pseudo_resolve_includebin) +{ + lw_expr_t e, e1, n; + int i = 0, i1; + + e = lwasm_fetch_expr(l, 0); + e1 = lwasm_fetch_expr(l, 1); + + // if offset and/or length specified, make sure they've resolved + // before we do anything + if (e && !lw_expr_istype(e, lw_expr_type_int)) + return; + if (e1 && !lwexpr_istype(e, lw_expr_type_int)) + return; + if (e != NULL) + { + i = lw_expr_intval(e); + + if (i < 0) + i = l -> len + i; + } + + i1 = l -> len - i; + + e1 = lwasm_fetch_expr(l, 1); + + if (e1 != NULL) + { + i1 = lw_expr_intval(e1); + } + + if( i < 0 ) + { + /* starting before file */ + lwasm_register_error(as, l, E_INCLUDEBIN_ILL_START); + return; + } + + if (i > l -> len) + { + /* starts past end of file */ + lwasm_register_error(as, l, E_INCLUDEBIN_ILL_START); + return; + } + + if (i1 < 0) + { + /* length is negative */ + lwasm_register_error(as, l, E_INCLUDEBIN_ILL_LENGTH); + return; + } + + if (i + i1 > l -> len) + { + /* read past end of file */ + lwasm_register_error(as, l, E_INCLUDEBIN_ILL_LENGTH); + return; + } + + + l -> lint = i; // pass forward offset + l -> len = i1; } EMITFUNC(pseudo_emit_includebin) { FILE *fp; - int c; + int c, i; fp = fopen(l -> lstr, "rb"); if (!fp) @@ -1536,7 +1619,10 @@ return; } - for (;;) + // apply the specified offset + fseek(fp, l -> lint, SEEK_SET); + + for (i=0; i < l -> len; i++) { c = fgetc(fp); if (c == EOF)