golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
121.23k stars 17.37k forks source link

proposal: os: access to ELF auxiliary vector #67839

Open 0xF0CACC1A opened 1 month ago

0xF0CACC1A commented 1 month ago

Proposal Details

like os.Args and os.Environ, I was wondering why there is neither an API to get ELF auxiliary vector nor Aux type. C does provide them in Elf.h

ianlancetaylor commented 1 month ago

If we do this I think it should be in the golang.org/x/sys/unix package. The os package is mainly aimed at OS-independent functionality, but auxv is specific to ELF-based systems.

0xF0CACC1A commented 1 month ago

so, in the current state of art, is there no way to get the full aux vector?

ianlancetaylor commented 1 month ago

As far as I know there is not.

adonovan commented 1 month ago

so, in the current state of art, is there no way to get the full aux vector?

Not from Go. In C you can usually derive it from the address of the environ symbol, but it may be non-portable.

seankhliao commented 1 month ago

I see runtime has an internal sysauxv which x/sys/cpu hooks into, falling back to /proc/self/auxv. Is the proc file sufficient?

0xF0CACC1A commented 3 weeks ago

/proc/self/auxv

could you provide a minimal example on how to retrieve auxv values?

seankhliao commented 3 weeks ago

see https://go.googlesource.com/sys/+/9a28524796a519b225fedd6aaaf4b1bf6c06c002/cpu/hwcap_linux.go#26

florianl commented 2 weeks ago

https://github.com/golang/go/issues/68089 advocated to expose runtime.getAuxv() and make it a public API. Exposing the auxiliary vector via os was not considered as a viable option, as os should be more of a higher level layer with cross OS compatability. But adding a public API, like runtime.Getauxv(), would also introduce some kind of OS specifics into runtime.

An alternative, also mentioned in https://github.com/golang/go/issues/67839#issuecomment-2150542705 and go.dev/cl/458256, could be an exposure of the auxiliary vector via golang.org/x/sys. golang.org/x/sys is OS specific and therefore a perfect fit. The unknown for me in this approach is how golang.org/x/sys can get access to something, that only runtime knows about, without techniques like //go:linkname.

ianlancetaylor commented 2 weeks ago

golang.org/x/sys/cpu already reaches into the runtime to fetch the auxiliary vector, using go:linkname. Adding an exported function in golang.org/x/sys/unix isn't going to make matters better or worse.

Reaching in from packages in x/sys is better than reaching in from arbitrary external packages, because we can change the x/sys packages ourselves, and then drop the support in runtime when we no longer support older versions of the x/sys packages.

florianl commented 2 weeks ago

Thanks for the clarification. I really wasn't sure about x/sys, as I considered x/sys as an external package, "just" in a more controlled manner.

If it helps, I can open a CL against x/sys for GetAuxv() []uintptr using go:linkname.

ianlancetaylor commented 2 weeks ago

Thanks, may as well wait for the proposal process.

lmb commented 2 weeks ago

Is the proc file sufficient?

/proc is tricky because it has additional permission checks and interacts with capabilities. See https://dxuuu.xyz/filecaps.html. Using auxv from the runtime really is a lot less error prone.