[uClibc] ARM shared libs segfault

David Poole daveml at mbuf.com
Thu May 20 17:49:41 UTC 2004


The linker isn't creating a correct executable. The output needs to 
have a TEXTREL section in the .dynamic section so the loader will know 
to mark the code segments read/write. The farthest I tracked it is the 
pc_count and count fields of the elf32-arm_relocs_copied structure then 
I ran out of time.

http://uclibc.org/lists/uclibc/2004-May/008943.html

A very quick and dirty hack is to change the uClibc loader to always 
mark the code sections read/write.

In toolchain/gcc-3.3.x/toolchain_build_arm_nofpu/uClibc/ldso/ldso

dl-startup.c

around line 413 (I'm using a snapshot) change:
         /* First cover the shared library/dynamic linker. */
         if (tpnt->dynamic_info[DT_TEXTREL]) {
             header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
             ppnt = (ElfW(Phdr) *) ((int)auxvt[AT_BASE].a_un.a_ptr +
                     header->e_phoff);

to:
         /* First cover the shared library/dynamic linker. */
         if ( 1 ) {
             header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
             ppnt = (ElfW(Phdr) *) ((int)auxvt[AT_BASE].a_un.a_ptr +
                     header->e_phoff);

around line 448 change:
        /* Now cover the application program. */
         if (app_tpnt->dynamic_info[DT_TEXTREL]) {
             ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;

to:
        /* Now cover the application program. */
         if ( 1 ) {
             ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;


dl-elf.c

around line 668 change:

     /* If the TEXTREL is set, this means that we need to make the pages
        writable before we perform relocations.  Do this now. They get 
set
        back again later. */

     if (dynamic_info[DT_TEXTREL]) {
#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
         ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];

to:

     /* If the TEXTREL is set, this means that we need to make the pages
        writable before we perform relocations.  Do this now. They get 
set
        back again later. */

     if ( 1 ) {
#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
         ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];


The text segments are set back to read-only in ldso.c around line 626:

        /* We had to set the protections of all pages to R/W for dynamic 
linking.
            Set text pages back to R/O */
         for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
             for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, 
myppnt++) {
                 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & 
PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
                     _dl_mprotect((void *) (tpnt->loadaddr + 
(myppnt->p_vaddr & PAGE_ALIGN)),
                             (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned 
long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
                 }
             }
         }

but I haven't gone through that inner if() to figure out how to if(1) 
it. There two different programs in play here: the loader and the 
program being loaded.

There's probably a simpler way to do this like hardwiring 
dynamic_info[DT_TEXTREL] to '1' somewhere.

(ps - I've learned a lot about linkers, loaders, and ELF these last two 
weeks. Very fun.)

On May 20, 2004, at 1:37 AM, roman wrote:

> Hello Erik,
>
> Thursday, May 20, 2004, 3:01:37 AM, you wrote:
>
> EA> When I build a uClibc root_fs for arm and attempt to chroot into
> EA> it on my netwinder, I immediately get a segfault.  Until that is
> EA> resolved there is little hope of getting i.e. /sbin/init to run,
> EA> or getting a system to boot.
>
> When I use static built busybox init there are no problem to boot and
> get a working system. With shared libraries there are two segfaults in
> ldso code. When I changed ldso sources as it was discussed at
> http://www.uclibc.org/lists/uclibc/2004-May/008870.html the system now
> works with shared libs as well. But I guess missing DT_TEXTREL is
> toolchain bug, as described at 
> http://www.uclibc.org/lists/uclibc/2004-May/008917.html

-- 
David Poole <dpoole at mobl.com>
Mobility Electronics, Idaho   http://www.mobl.com
960 Broadway Avenue, Suite 300
Boise, ID  83706




More information about the uClibc mailing list