I created an issue here on the repo as a potential fix. I had to use the help of LLMs for this as I am not an expert in this but I was able to grok through the changes.
The suggested change of using DI did not work as it is used elsewhere in the code.
Also created a PR here: fix: change r15 usage so its not clobbered with go plugin buildmode by rhnvrm · Pull Request #211 · parquet-go/parquet-go · GitHub
R15 Clobbering Issue in Go Plugins
A quick summary of what I learnt, was that in plugin build mode, the R15 register is used for internal runtime operations so there is a compiler check in Go that does not allow this. Changing R15 to something else, is a simple solution. In the klauspost/compress repo, they changed it to DI. But here, DI is used elsewhere so we have to use a different register.
Generated
The R15 clobbering issue arises from a conflict between Go’s dynamic linking model and the use of the R15 register in AMD64 assembly code. When building with
-buildmode=plugin, Go uses dynamic linking, which requires certain registers, like R15, to be preserved for internal runtime operations, such as managing global variables or stack offsets.Key Points:
- Error Context: The error occurs when assembly code uses R15 for computations, but dynamic linking expects it to remain unchanged, leading to clobbering.
- Dynamic Linking: In this mode, Go’s runtime needs R15 to be preserved across function calls and global variable accesses.
- Assembly Code: Using R15 directly in assembly for arithmetic or addressing can interfere with the Go runtime’s management, causing state corruption.
- Global Variable Access: The error often involves global variable access, where R15 might be temporarily used by the runtime, leading to conflicts.
Solutions:
- Avoid Using R15: Use other registers instead of R15 in assembly code for calculations.
- Save/Restore R15: If R15 must be used, save and restore its value around global variable accesses.
- Adhere to Go Assembly Conventions: Use Go’s assembler conventions to manage register preservation automatically.
- Conditional Compilation: Use build directives to apply safe code paths for plugin builds.
This issue is similar to problems in performance-optimized packages like
klauspost/compress, where hand-written assembly is common. The solution involves careful management of register usage to align with Go’s dynamic linking requirements.