SOME BACKGROUND

I'm modifying an emulator that runs under Linux (kernel 2.6) and want to leave the emulator process's
address space from address zero free to map in (4 megabyte paged) shared memory at run time. This
shared memory then holds the emulated machine's memory, and having both the emulated machine and
emulator process see them mapped from address zero reduces the cost of mapping the emulated machine's
address accesses to resulting emulator's address accesses.

I reserved as empty the early address space of the emulator process by explicitly siting the bss,

data and text sections at high addresses: passing the params -Xlinker "-Tbss=0xB3000000" -Xlinker
"-Tdata=0xB5000000" -Xlinker "-Ttext=0xBA000000" to gcc. Gcc in turn forwards these link requests to
the linker/loader to perform. Using 0xB0000000 and higher addresses would enable me to map in to the emulator process up to 2Gbytes of shared memory in the range
0x00000000 to 0x7FFFFFFF.

THE ERROR

But when I ran my emulator it failed after printing the error message:

libgcc_s.so.1 must be installed for pthread_cancel to work

I've tracked the generation of the above error to the following glibc code:

void
pthread_cancel_init (void)
{
void *resume, *personality, *forcedunwind, *getcfa;
void *handle;

if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
return;

handle = __libc_dlopen ("libgcc_s.so.1"); // Bug or unexpected return: handle is set to zero

if (handle == NULL
|| (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
|| (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL
|| (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind"))
== NULL
|| (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
#ifdef ARCH_CANCEL_INIT
|| ARCH_CANCEL_INIT (handle)
#endif
)
__libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");

libgcc_s_resume = resume;
libgcc_s_personality = personality;
libgcc_s_forcedunwind = forcedunwind;
/* Make sure libgcc_s_getcfa is written last. Otherwise,
pthread_cancel_init might return early even when the pointer the
caller is interested in is not initialized yet. */
atomic_write_barrier ();
libgcc_s_getcfa = getcfa;
}

This code instance occurs in
nptl/sysdeps/pthread/unwind-resume.c.

I've found the libgcc_s.so.1 link library opening (i.e. handle = __libc_dlopen) failing by returning zero. However, when I lower the load address of the text section to below 0x40000000 then the above error doesn't
occur, and my emulator works fine. Note: loading the text section between 0x40000000 and 0x80000000 does not correct matters.

My two queries are:

1) Is there a bug in the dynamic link library loading of glibc (including version 2.3.4) which is

activated when the text section is located higher than a certain memory address?

or

2) is there something special about a piece of dynamic link library (dll) code where if the two

most signicant address bits of its code are non-zero (i.e. in the address range 0x40000000 to 0xFFFFFFFF) then the
dll is not loadable?