They're
(a) in no way connected to the .so files,
(b) not necessarily available,
(c) incomplete information since build information (e.g. compiler, command line options) is missing, and
(d) much harder to parse than necessary.
You don't need special compiler options to use a shared object. If you got it as a binary, there is nothing to compile.
The incomplete information in header files isn't the compiler command line options, but the nuances of the API semantics. Like if a structure is passed and the structure contains pointers. Who owns the structure and must free it? Who owns the pointers inside it? Oooh, here is a functional argument: what parts of the API can be safely invoked from that callback? That size argument, is that bytes or array elements? And so on.
Thanks. Yes, I was after an experience along the lines of python's inspect module, or Java reflection, but against native code shard objects. And feeling incredulous that it had not been standardised decades ago in major tool chains.
Another poster highlighted Stephen Kell's work, and this is exactly what I had in mind. He highlights obstacles with mmap in one video. I did not recognise these issues until I had watched his presentation, but now see that they are difficult hurdles that are inherent to the problem.