Why golang limit the symbol number to 65535 while compile wasm target?

Viewed 169

I'm trying to compile a golang project to wasm, the compiler complains something like non-pc-relative relocation address for github.com/xxx/yyy/zzz.SomeSymbol is too big: 0x1079a0000.

Then I try to read the compiler code and found that the golang compiler will left shift the address with 16 bits so that there are only 16 bits symbol address (65536 symbols) can be used with wasm32: https://github.com/golang/go/blob/dev.boringcrypto.go1.16/src/cmd/link/internal/wasm/asm.go#L74

func assignAddress(ldr *loader.Loader, sect *sym.Section, n int, s loader.Sym, va uint64, isTramp bool) (*sym.Section, int, uint64) {
    // WebAssembly functions do not live in the same address space as the linear memory.
    // Instead, WebAssembly automatically assigns indices. Imported functions (section "import")
    // have indices 0 to n. They are followed by native functions (sections "function" and "code")
    // with indices n+1 and following.
    //
    // The following rules describe how wasm handles function indices and addresses:
    //   PC_F = funcValueOffset + WebAssembly function index (not including the imports)
    //   s.Value = PC = PC_F<<16 + PC_B
    //
    // The funcValueOffset is necessary to avoid conflicts with expectations
    // that the Go runtime has about function addresses.
    // The field "s.Value" corresponds to the concept of PC at runtime.
    // However, there is no PC register, only PC_F and PC_B. PC_F denotes the function,
    // PC_B the resume point inside of that function. The entry of the function has PC_B = 0.
    ldr.SetSymSect(s, sect)
    ldr.SetSymValue(s, int64(funcValueOffset+va/ld.MINFUNC)<<16) // va starts at zero
    va += uint64(ld.MINFUNC)
    return sect, n, va
}

Is there any special reason that the compiler must do so?

0 Answers
Related