Eu responderei a minha própria pergunta depois de algumas investigações. Em suma, isso é uma coisa dependente do arco. O PowerPC32 define uma função de endereço de carga preferida, enquanto a maioria dos outros arcos, incluindo o x86, não define isso.
/* The idea here is that to conform to the ABI, we are supposed to try
to load dynamic objects between 0x10000 (we actually use 0x40000 as
the lower bound, to increase the chance of a memory reference from
a null pointer giving a segfault) and the program's load address;
this may allow us to use a branch instruction in the PLT rather
than a computed jump. The address is only used as a preference for
mmap, so if we get it wrong the worst that happens is that it gets
mapped somewhere else. */
ElfW(Addr)
__elf_preferred_address (struct link_map *loader, size_t maplength,
ElfW(Addr) mapstartpref)
{
ElfW(Addr) low, high;
struct link_map *l;
Lmid_t nsid;
/* If the object has a preference, load it there! */
if (mapstartpref != 0)
return mapstartpref;
/* Otherwise, quickly look for a suitable gap between 0x3FFFF and
0x70000000. 0x3FFFF is so that references off NULL pointers will
cause a segfault, 0x70000000 is just paranoia (it should always
be superseded by the program's load address). */
low = 0x0003FFFF;
high = 0x70000000;
for (nsid = 0; nsid < DL_NNS; ++nsid)
for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
{
ElfW(Addr) mapstart, mapend;
mapstart = l->l_map_start & ~(GLRO(dl_pagesize) - 1);
mapend = l->l_map_end | (GLRO(dl_pagesize) - 1);
assert (mapend > mapstart);
/* Prefer gaps below the main executable, note that l ==
_dl_loaded does not work for static binaries loading
e.g. libnss_*.so. */
if ((mapend >= high || l->l_type == lt_executable)
&& high >= mapstart)
high = mapstart;
else if (mapend >= low && low >= mapstart)
low = mapend;
else if (high >= mapend && mapstart >= low)
{
if (high - mapend >= mapstart - low)
low = mapend;
else
high = mapstart;
}
}
high -= 0x10000; /* Allow some room between objects. */
maplength = (maplength | (GLRO(dl_pagesize) - 1)) + 1;
if (high <= low || high - low < maplength )
return 0;
return high - maplength; /* Both high and maplength are page-aligned. */
}