Skip to content

ShadowStack will bring unneccessary debug location #2704

@JesseCodeBones

Description

@JesseCodeBones

Bug description

As shadow stack will insert stack increase or decrease operations without debug location, but Binaryen debug location strategy is range, that means the offset from previous expression offset to current expression offset, they all be regarded to the debug location of previous expression, here id code from WasmBinaryWriter::writeSourceMapEpilog:

writeBase64VLQ(*sourceMap, int32_t(offset - lastOffset));
writeBase64VLQ(*sourceMap, int32_t(loc->fileIndex - lastLoc.fileIndex));
writeBase64VLQ(*sourceMap, int32_t(loc->lineNumber - lastLoc.lineNumber));
writeBase64VLQ(*sourceMap,
                 int32_t(loc->columnNumber - lastLoc.columnNumber));

so the new inserted shadow stack expressions will attach to previous expression, which will cause Basic Block analysis confusion.

for example:

...
     ;;@ assert.ts:9:6
     (local.set $total
      ;;@ assert.ts:9:15
      (i32.add
       ;;@ assert.ts:9:6
       (local.get $total)
       ;;@ assert.ts:9:15
       (i32.const 1)
      )
     )
    )
   )
  )
  ;;@ assert.ts:9:6
  (global.set $~lib/memory/__stack_pointer
   ;;@ assert.ts:9:6
   (i32.add
    ;;@ assert.ts:9:6
    (global.get $~lib/memory/__stack_pointer)
    ;;@ assert.ts:9:6
    (i32.const 8)
   )
  )
  ;;@ assert.ts:11:2
  (return)
 )

the stack pointer update will be inserted before return instruction, but from debug location, it inherit from another basic block.
I checked from binaryen side, how can prevent this happened, from current solution of Source map of binaryen, it is hard to do that, and from AssemblyScript side, I think if we can add the specific debug location for the stack update expressions?

Steps to reproduce

1, compile as file:

export function test(result: boolean, value: string, key: string): void 
{ 
  let total = 0, failed = 0; 
  if (!result) 
  { failed++; 
    if (value == key) 
    { total += failed; } 
    else 
    { total += 1; } 
  } 
  return; 
} 

2, view debug location with below command:
npx wasm-opt build/debug.wasm -ism build/debug.wasm.map --print

AssemblyScript version

v0.27.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions