This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Problem with early startup in dynamic linker.


On Wed, Nov 11, 2009 at 11:41 AM, John David Anglin
<dave@hiauly1.hia.nrc.ca> wrote:
>> Can I use this sequence to find the address of a static local variable?
>
> This will work if the local variable is in the same segment as
> the code. ?It may work generally because I believe there is a fixed
> relationship between the code and data segments on linux (this isn't
> true on hpux). ?The issue is whether the data is readonly or needs
> to be writeable.

CC'ing libc-ports in case anyone knows what might be wrong.

CC'ing Lu, who might have a suggestion (and is familiar with the code). Hi Lu!

There is code in dl-fptr.c which is called during relocation
processing and before rtld is fully relocated.

The code in dl-fptr.c looks like this:
~~~
static struct local
  {
    struct fdesc_table *root;
    struct fdesc *free_list;
    unsigned int npages;                /* # of pages to allocate */
    /* the next to members MUST be consecutive! */
    struct fdesc_table boot_table;
    struct fdesc boot_fdescs[1024];
  }
local =
  {
    .root = &local.boot_table,
    .npages = 2,
    .boot_table =
      {
        .len = sizeof (local.boot_fdescs) / sizeof (local.boot_fdescs[0]),
        .first_unused = 0
      }
  };
~~~

The ".root = &local.boot_table," assignment causes this relocation to
be emitted:
~~~
000219d8  00000101 R_PARISC_DIR32    000024b0   .text + 1f534
~~~

This is because the address of local + 12 is not known until .text has
been relocated.

However, this appears to mean that ALL DIR32 relocs have to be
processed before the above code can be called "safely relocated" and
before any PLABEL32 (official procedure descriptor relocations) relocs
can be processed since they use this code.

A trunk build shows a crash in the dynamic loader trying to access
l->root. The value of local.root is the unrelocated address (as
computed by the linker and placed at link time into .data).

Is the solution to sort the dynamic relocations and process all DIR32
relocs first?

The alternative is this:
~~~
 local =
   {
-    .root = &local.boot_table,
+    /* Address of .boot_table is not known until runtime.  */
+    .root = 0,
     .npages = 2,
     .boot_table =
       {
@@ -103,6 +105,10 @@ make_fdesc (ElfW(Addr) ip, ElfW(Addr) gp)
   struct local *l;

   ELF_MACHINE_LOAD_ADDRESS (l, local);
+  /* Initialize root once.  */
+  if (l->root == 0)
+    l->root = &l->boot_table;
~~~
This removes the relocation against local.

This fixes the dynamic linker segmentation fault in early startup
while trying to relocate a PLABEL32 reloc before all of the DIR32
relocs.

Are the changes to dl-fptr.c the right solution?

Cheers,
Carlos.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]