This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] [RFC] Building for SuperH fails with gcc5/6
- From: Alexey Neyman <stilor at att dot net>
- To: libc-alpha at sourceware dot org
- Date: Wed, 25 Jan 2017 23:03:36 -0800
- Subject: [PATCH] [RFC] Building for SuperH fails with gcc5/6
- Authentication-results: sourceware.org; auth=none
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