emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.79k stars 3.31k forks source link

Wasm2wat Unexpect Opcode #22347

Closed Chrischenny closed 2 months ago

Chrischenny commented 2 months ago

Emscripten Version

3.1.64

FFmpeg Version Tag

release/7.0

Build Command

echo "Beginning Build:"
rm -r ffmpeg
mkdir -p ffmpeg
cd ../ffmpeg
make clean
emconfigure ./configure --cc="emcc" --cxx="em++" --ar="emar" \
  --ranlib=emranlib --prefix=$(pwd)/../decoder_wasm/ffmpeg \
  --enable-cross-compile --target-os=none --arch=x86_32 --cpu=generic \
  --enable-gpl --enable-version3 --disable-avdevice --enable-avformat \
  --disable-swresample --disable-postproc \
  --disable-programs --disable-everything \
  --enable-filter=v360 \
  --disable-ffplay --disable-ffprobe --disable-asm \
  --disable-doc --disable-devices --disable-network \
  --disable-hwaccels --disable-parsers --disable-bsfs \
  --disable-debug --disable-protocols --disable-indevs --disable-outdevs \
    --enable-decoder=h264  --enable-parser=h264 --enable-protocol=file --enable-demuxer=mov
make
make install
cd ../decoder_wasm
rm -rf dist/libffmpeg_$1.wasm dist/libffmpeg_$1.js
export TOTAL_MEMORY=67108864
export EXPORTED_FUNCTIONS="[ \
        '_openDecoder', \
    '_flushDecoder', \
        '_closeDecoder', \
    '_decodeData', \
    '_main'
]"

echo "Running Emscripten..."
emcc decode_video.c ffmpeg/lib/libavcodec.a ffmpeg/lib/libavutil.a ffmpeg/lib/libswscale.a ffmpeg/lib/libavfilter.a \
    -O2 \
    -I "ffmpeg/include" \
    -s WASM=1 \
    -s TOTAL_MEMORY=${TOTAL_MEMORY} \
    -s EXPORTED_FUNCTIONS="${EXPORTED_FUNCTIONS}" \
    -s EXTRA_EXPORTED_RUNTIME_METHODS="['addFunction']" \
        -s RESERVED_FUNCTION_POINTERS=14 \
        -s FORCE_FILESYSTEM=1 \
    -o dist/libffmpeg_$1.js

echo "Finished Build"

Detail

When I use wasm2wat to analyze the detail of the binary file, the wasm2wat tool report an error:

0006c2d: error: unexpected opcode: 0xfe 0x17

Then I use binaryReader to read the wasm file, I found that an unexpected externed varible was packaged in __indirect_function_table section. This varible is externed by /ffmpeg/libavcodec/cabac.h, the code block is:

#ifndef AVCODEC_CABAC_H
#define AVCODEC_CABAC_H

#include <stdint.h>

extern const uint8_t ff_h264_cabac_tables[512 + 4*2*64 + 4*64 + 63];
#define H264_NORM_SHIFT_OFFSET 0
#define H264_LPS_RANGE_OFFSET 512
#define H264_MLPS_STATE_OFFSET 1024
#define H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET 1280

#define CABAC_BITS 16
#define CABAC_MASK ((1<<CABAC_BITS)-1)

typedef struct CABACContext{
    int low;
    int range;
    const uint8_t *bytestream_start;
    const uint8_t *bytestream;
    const uint8_t *bytestream_end;
}CABACContext;

int ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);

the binary file is: a.zip

brendandahl commented 2 months ago

Is this a regression?

Chrischenny commented 2 months ago

Is this a regression?

no, just h264 decoder

Chrischenny commented 2 months ago

Is this a regression?

I use this wasm in browser kernel to decode avc live stream by software, but in some case,it will cuase the kernel crush down.

Chrischenny commented 2 months ago

Is this a regression?

it works on version 1.38.45 i tried on 2.0.x,it didn't work

kripken commented 2 months ago

0xfe 0x17

Looks like that is a 32-bit atomic store. If wasm2wat can't parse it then I suggest filing an issue on the wabt repo, where that tool comes from. Though, perhaps check first if you aren't missing the flag to enable threads, --enable-threads (it's possible that without that flag, it treats atomic opcodes as errors).

sbc100 commented 2 months ago

Yup, looks like you need --enable-threads (or --enable-all)