[UR] Make the device sanitizer layer a shared library (#22950)
The loader can be statically linked into more than one library of a
process. Its state is hidden, so the linker cannot merge those copies,
and the sanitizers ended up with two independent states over one device.
Both reserved device shadow memory, and the second reservation failed
with UR_RESULT_ERROR_OUT_OF_DEVICE_MEMORY.
Move the sanitizer layer into libur_sanitizer_layer.so, loaded on demand
from the same locations an adapter is loaded from, so all loader
instances of a process share one instance of it. Every loader still
initializes the layer with its own ddi table; the layer reference counts
those and hooks up the extra tables via context_t::interceptDdiTable
instead of setting up a second state.
Assisted-by: Claude