diff options
author | Cyrill Gorcunov <gorcunov@gmail.com> | 2018-10-15 22:58:13 +0300 |
---|---|---|
committer | Cyrill Gorcunov <gorcunov@gmail.com> | 2018-10-15 22:58:13 +0300 |
commit | f7b44f6092623df2a84b5db317d0c5217eccd87e (patch) | |
tree | 8489eb0ff19b98281c697b636e00cb70a1a5c681 /asm/parser.c | |
parent | 94adf7d765a06d6608ca3aa317ac69a332c817cf (diff) | |
parent | 28b69e2a633a850e724f309a5ec81bac8638084a (diff) | |
download | nasm-f7b44f6092623df2a84b5db317d0c5217eccd87e.tar.gz |
Merge branch 'nasm-2.14.xx'
* nasm-2.14.xx: (83 commits)
NASM 2.14rc16
doc: Update changes
preproc: expand_smacro -- Fix nil dereference on error path
eval: Eliminate division by zero
doc: Update changes
opflags: Convert is_class and is_reg_class to helpers
preproc: Fix out of range access in expand mmacro
doc: Update changes
parser: Fix sigsegv on certain equ instruction parsing
labels: Make sure nil label is never passed
labels: Don't nil dereference if no label provided
macho: Add warning message in macho_output()
macho/reloc: Fix addr size sensitive conditions
macho/reloc: Fix macho_output() to get the offset adjustments by add_reloc()
macho/reloc: Fixed offset adjustment in add_reloc()
macho/reloc: Allow absolute relocation when forcing a symbol reference
macho/reloc: Adjust SUB relocation information
macho/reloc: Fixed in handling GOT/GOTLOAD/TLV relocations
macho/reloc: Simplified relocation for REL/BRANCH
macho/sym: Record initial symbol number always
...
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Diffstat (limited to 'asm/parser.c')
-rw-r--r-- | asm/parser.c | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/asm/parser.c b/asm/parser.c index d5a45753..78f347fa 100644 --- a/asm/parser.c +++ b/asm/parser.c @@ -486,7 +486,8 @@ restart_parse: * Generally fix things. I think this is right as it is, but * am still not certain. */ - define_label(result->label, location.segment, + define_label(result->label, + in_absolute ? absolute.segment : location.segment, location.offset, true); } } @@ -1027,7 +1028,7 @@ is_expression: op->segment = NO_SEG; /* don't care again */ op->wrt = NO_SEG; /* still don't care */ - if(optimizing >= 0 && !(op->type & STRICT)) { + if(optimizing.level >= 0 && !(op->type & STRICT)) { /* Be optimistic */ op->type |= UNITY | SBYTEWORD | SBYTEDWORD | UDWORD | SDWORD; @@ -1044,7 +1045,7 @@ is_expression: if (is_simple(value)) { if (n == 1) op->type |= UNITY; - if (optimizing >= 0 && !(op->type & STRICT)) { + if (optimizing.level >= 0 && !(op->type & STRICT)) { if ((uint32_t) (n + 128) <= 255) op->type |= SBYTEDWORD; if ((uint16_t) (n + 128) <= 255) @@ -1077,6 +1078,7 @@ is_expression: } } else { /* it's a register */ opflags_t rs; + uint64_t regset_size = 0; if (value->type >= EXPR_SIMPLE || value->value != 1) { nasm_error(ERR_NONFATAL, "invalid operand type"); @@ -1084,13 +1086,32 @@ is_expression: } /* - * check that its only 1 register, not an expression... + * We do not allow any kind of expression, except for + * reg+value in which case it is a register set. */ - for (i = 1; value[i].type; i++) - if (value[i].value) { + for (i = 1; value[i].type; i++) { + if (!value[i].value) + continue; + + switch (value[i].type) { + case EXPR_SIMPLE: + if (!regset_size) { + regset_size = value[i].value + 1; + break; + } + /* fallthrough */ + default: nasm_error(ERR_NONFATAL, "invalid operand type"); goto fail; } + } + + if ((regset_size & (regset_size - 1)) || + regset_size >= (UINT64_C(1) << REGSET_BITS)) { + nasm_error(ERR_NONFATAL | ERR_PASS2, + "invalid register set size"); + regset_size = 0; + } /* clear overrides, except TO which applies to FPU regs */ if (op->type & ~TO) { @@ -1099,12 +1120,31 @@ is_expression: * is different from the register size */ rs = op->type & SIZE_MASK; - } else + } else { rs = 0; + } + + /* + * Make sure we're not out of nasm_reg_flags, still + * probably this should be fixed when we're defining + * the label. + * + * An easy trigger is + * + * e equ 0x80000000:0 + * pshufw word e-0 + * + */ + if (value->type < EXPR_REG_START || + value->type > EXPR_REG_END) { + nasm_error(ERR_NONFATAL, "invalid operand type"); + goto fail; + } op->type &= TO; op->type |= REGISTER; op->type |= nasm_reg_flags[value->type]; + op->type |= (regset_size >> 1) << REGSET_SHIFT; op->decoflags |= brace_flags; op->basereg = value->type; |