This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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]

[PATCH] [RFC] Building for SuperH fails with gcc5/6


Hi,

Build glibc for sh4-unknown-linux-gnu currently fails if one's using GCC5/6: in dl-conflict.c, the elf_machine_rela() function is called with NULL as its 3rd argument, sym. The implementation of that function in sysdeps/sh/dl-machine.h dereferences that pointer:

const Elf32_Sym *const refsym = sym;
...
if (map == &GL(dl_rtld_map))
  value -= map->l_addr + refsym->st_value + reloc->r_addend;

GCC discovers a null pointer dereference, and in accordance with -fdelete-null-pointer-checks (which is enabled in -O2) replaces this code with a trap - which, as SH does not implement a trap pattern in GCC, evaluates to an abort() call. This abort() call pulls many more objects from libc_nonshared.a, eventually resulting in link failure due to multiple definitions for a number of symbols.

As far as I see, the conditional before this code is always false in rtld: _dl_resolve_conflicts() is called with main_map as the first argument, not GL(_dl_rtld_map), but since that call is in yet another compilation unit, GCC does not know about it. Patch that wraps this conditional into !defined RESOLVE_CONFLICT_FIND_MAP attached.

However, I thought the abort() call may be also inserted by GCC on other architectures that do not implement the trap pattern, so it may make sense to provide a dummy abort() in rtld that does not pull any other dependencies. An alternative patch for this approach also attached.

And, of course, it is also possible to just add -fno-delete-null-pointer-checks to the compiler flags for dl-conflict.c on SH, even though it would unnecessarily pessimize the code.

Comments?

Regards,
Alexey.

>From e8c40e96f9aa31addab370c8ed13a58efcf77abf Mon Sep 17 00:00:00 2001
From: Alexey Neyman <stilor@att.net>
Date: Wed, 25 Jan 2017 21:38:02 -0800
Subject: [PATCH] Provide a minimal abort() stub for rtld

... to avoid pulling in more dependencies from libc_nonshared.a.

Signed-off-by: Alexey Neyman <stilor@att.net>
---
 elf/dl-abort-stub.c | 27 +++++++++++++++++++++++++++
 sysdeps/sh/Makefile |  4 ++++
 2 files changed, 31 insertions(+)
 create mode 100644 elf/dl-abort-stub.c

diff --git a/elf/dl-abort-stub.c b/elf/dl-abort-stub.c
new file mode 100644
index 0000000..a4924e2
--- /dev/null
+++ b/elf/dl-abort-stub.c
@@ -0,0 +1,27 @@
+/* Stub for abort() to avoid pulling in extra objects on architectures
+   that do not implement __builtin_trap().
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Alexey Neyman <stilor@att.net>, 2017.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+void
+abort(void)
+{
+  // It's noreturn...
+  for (;;)
+    ;
+}
diff --git a/sysdeps/sh/Makefile b/sysdeps/sh/Makefile
index 0c6db9a..039217c 100644
--- a/sysdeps/sh/Makefile
+++ b/sysdeps/sh/Makefile
@@ -9,3 +9,7 @@ endif
 ifeq ($(subdir),debug)
 CFLAGS-backtrace.c += -funwind-tables
 endif
+
+ifeq ($(subdir),elf)
+sysdep-rtld-routines += dl-abort-stub
+endif
-- 
2.9.3

>From 279acf7a059f2d2296f690d7f2d886bd0e404f30 Mon Sep 17 00:00:00 2001
From: Alexey Neyman <stilor@att.net>
Date: Wed, 25 Jan 2017 21:46:53 -0800
Subject: [PATCH] sh: conditional is false in dl-conflict.c

... ifdef it out, so that it doesn't create a call to abort().

Signed-off-by: Alexey Neyman <stilor@att.net>
---
 sysdeps/sh/dl-machine.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
index 449deea..2b468af 100644
--- a/sysdeps/sh/dl-machine.h
+++ b/sysdeps/sh/dl-machine.h
@@ -389,7 +389,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	  break;
 	case R_SH_DIR32:
 	  {
-#ifndef RTLD_BOOTSTRAP
+#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
 	   /* This is defined in rtld.c, but nowhere in the static
 	      libc.a; make the reference weak so static programs can
 	      still link.  This declaration cannot be done when
-- 
2.9.3


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