RTLD_LAZY is a flag that you can pass to dlopen() when you load a shared object.
Even though the word "lazy" in the name suggests that it's about lazy binding as described above in " Lazy binding," it has different semantics. It makes (semantically) no difference whether a program is lazy- or now- bound, but for objects that you load with dlopen(), RTLD_LAZY means "there may be symbols that can't be resolved; don't try to resolve them until they're used." This flag currently applies only to function symbols, not data symbols.
What does it practically mean? To explain that, consider a system that comprises an executable X, and shared objects P (primary) and S (secondary). X uses dlopen() to load P, and P loads S. Let's assume that P has a reference to some_function(), and S has the definition of some_function().
If X opens P without RTLD_LAZY binding, the symbol some_function() doesn't get resolved — not at the load time, nor later by opening S. However, if P is loaded with RTLD_LAZY | RTLD_WORLD, the runtime linker doesn't try to resolve the symbol some_function(), and there's an opportunity for us to call dlopen("S", RTLD_GLOBAL) before calling some_function(). This way, the some_function() reference in P will be satisfied by the definition of some_function() in S.
There are several programming models made possible by RTLD_LAZY: