libdl: add AbstractLibrary with a stable-identity contract
Introduce `Libdl.AbstractLibrary`, an abstract supertype for library handles
that carry an identity the compiler can rely on. Subtypes implement `dlid` and
`dlname`, and promise that both are invariant for the life of the handle;
`LazyLibrary` becomes the first subtype.
When the library argument of a `ccall`/`cglobal` resolves to an
`AbstractLibrary`, method.c now expands the target to a 4-tuple
`(fname, lib_ref, lib_id, lib_name)`, freezing the identity where the call is
written. Codegen carries those two values through to the lookup, and the
runtime re-checks them via `jl_egal` when the symbol is first resolved, so a
subtype that violates the contract raises an error instead of silently binding
to a different library.
A `LazyLibrary` built from a plain string has no stable name to offer, so
`dlname` returns `nothing` for it and the target is left unexpanded.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01668muj5tpR4QXNXu8NVE9f