# HG changeset patch # User William Astle # Date 1703222065 25200 # Node ID 87f904e2b304830827789d2f99d0c07bdb06182e # Parent 8c6c3363e18ed9db25eff8825dbfcdb4f8f7e434 Add offset and length operands (optional) to includebin This addition is based on a patch from Tim Lindner . 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. diff -r 8c6c3363e18e -r 87f904e2b304 lwasm/instab.c --- 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); diff -r 8c6c3363e18e -r 87f904e2b304 lwasm/lwasm.c --- 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"; diff -r 8c6c3363e18e -r 87f904e2b304 lwasm/lwasm.h --- 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 */ diff -r 8c6c3363e18e -r 87f904e2b304 lwasm/pseudo.c --- 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)