Segmentation Fault while computing TLS address of weak undef symbol

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Segmentation Fault while computing TLS address of weak undef symbol

Glauber Costa-2
Hi,

I just went trough a SIGSEGV in the dynamic loader for ARM, while
trying to compute the address of an external weak undef symbol marked
with the __thread identifier. The code excerpt inlined in this message
reproduces the problem, and a fix follows attached.

#pragma weak foo

extern __thread int foo;

int main () {

        return &foo;
}

--
"Free as in Freedom"
Glauber de Oliveira Costa.

arm-weakundef-segv (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Segmentation Fault while computing TLS address of weak undef symbol

Daniel Jacobowitz-2
On Thu, Aug 10, 2006 at 08:55:43PM -0300, Glauber de Oliveira Costa wrote:
> Hi,
>
> I just went trough a SIGSEGV in the dynamic loader for ARM, while
> trying to compute the address of an external weak undef symbol marked
> with the __thread identifier. The code excerpt inlined in this message
> reproduces the problem, and a fix follows attached.

Hi Glauber, and sorry for not getting back to you sooner about this.
I've checked in this similar patch instead, which is more parallel
to how i686 handles the same issue.

--
Daniel Jacobowitz
CodeSourcery

2006-09-21  Daniel Jacobowitz  <[hidden email]>

        * sysdeps/arm/dl-machine.h (elf_machine_rel): Handle undefined
        symbols.
        (elf_machine_rela): Likewise.

Index: sysdeps/arm/dl-machine.h
===================================================================
RCS file: /cvs/glibc/ports/sysdeps/arm/dl-machine.h,v
retrieving revision 1.59
diff -u -p -r1.59 dl-machine.h
--- sysdeps/arm/dl-machine.h 5 Jul 2006 16:46:20 -0000 1.59
+++ sysdeps/arm/dl-machine.h 21 Sep 2006 18:19:58 -0000
@@ -447,12 +447,16 @@ elf_machine_rel (struct link_map *map, c
   break;
 
  case R_ARM_TLS_DTPOFF32:
-  *reloc_addr += sym->st_value;
+  if (sym != NULL)
+    *reloc_addr += sym->st_value;
   break;
 
  case R_ARM_TLS_TPOFF32:
-  CHECK_STATIC_TLS (map, sym_map);
-  *reloc_addr += sym->st_value + sym_map->l_tls_offset;
+  if (sym != NULL)
+    {
+      CHECK_STATIC_TLS (map, sym_map);
+      *reloc_addr += sym->st_value + sym_map->l_tls_offset;
+    }
   break;
 #endif
  default:
@@ -544,13 +548,16 @@ elf_machine_rela (struct link_map *map,
   break;
 
  case R_ARM_TLS_DTPOFF32:
-  *reloc_addr = sym->st_value + reloc->r_addend;
+  *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
   break;
 
  case R_ARM_TLS_TPOFF32:
-  CHECK_STATIC_TLS (map, sym_map);
-  *reloc_addr = (sym->st_value + sym_map->l_tls_offset
- + reloc->r_addend);
+  if (sym != NULL)
+    {
+      CHECK_STATIC_TLS (map, sym_map);
+      *reloc_addr = (sym->st_value + sym_map->l_tls_offset
+     + reloc->r_addend);
+    }
   break;
 #endif
  default: