diff mbox series

[v10,5/7] elf: Add more DT_RELR tests

Message ID 20220414232129.1886210-6-hjl.tools@gmail.com
State New
Headers show
Series Support DT_RELR relative relocation format | expand

Commit Message

H.J. Lu April 14, 2022, 11:21 p.m. UTC
Verify that:

1. A DT_RELR shared library without DT_NEEDED works.
2. A DT_RELR shared library without DT_VERNEED works.
3. A DT_RELR shared library without libc.so on DT_NEEDED works.
---
 elf/Makefile           | 71 ++++++++++++++++++++++++++++++++++++++++--
 elf/tst-relr-mod2.c    | 46 +++++++++++++++++++++++++++
 elf/tst-relr-mod3a.c   | 49 +++++++++++++++++++++++++++++
 elf/tst-relr-mod3b.c   | 22 +++++++++++++
 elf/tst-relr-mod4a.c   | 19 +++++++++++
 elf/tst-relr-mod4b.c   | 19 +++++++++++
 elf/tst-relr-mod4b.map |  3 ++
 elf/tst-relr2.c        | 27 ++++++++++++++++
 elf/tst-relr3.c        | 27 ++++++++++++++++
 elf/tst-relr4.c        |  1 +
 10 files changed, 281 insertions(+), 3 deletions(-)
 create mode 100644 elf/tst-relr-mod2.c
 create mode 100644 elf/tst-relr-mod3a.c
 create mode 100644 elf/tst-relr-mod3b.c
 create mode 100644 elf/tst-relr-mod4a.c
 create mode 100644 elf/tst-relr-mod4b.c
 create mode 100644 elf/tst-relr-mod4b.map
 create mode 100644 elf/tst-relr2.c
 create mode 100644 elf/tst-relr3.c
 create mode 100644 elf/tst-relr4.c

Comments

Adhemerval Zanella Netto April 20, 2022, 5:24 p.m. UTC | #1
On 14/04/2022 20:21, H.J. Lu wrote:
> Verify that:
> 
> 1. A DT_RELR shared library without DT_NEEDED works.
> 2. A DT_RELR shared library without DT_VERNEED works.
> 3. A DT_RELR shared library without libc.so on DT_NEEDED works.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  elf/Makefile           | 71 ++++++++++++++++++++++++++++++++++++++++--
>  elf/tst-relr-mod2.c    | 46 +++++++++++++++++++++++++++
>  elf/tst-relr-mod3a.c   | 49 +++++++++++++++++++++++++++++
>  elf/tst-relr-mod3b.c   | 22 +++++++++++++
>  elf/tst-relr-mod4a.c   | 19 +++++++++++
>  elf/tst-relr-mod4b.c   | 19 +++++++++++
>  elf/tst-relr-mod4b.map |  3 ++
>  elf/tst-relr2.c        | 27 ++++++++++++++++
>  elf/tst-relr3.c        | 27 ++++++++++++++++
>  elf/tst-relr4.c        |  1 +
>  10 files changed, 281 insertions(+), 3 deletions(-)
>  create mode 100644 elf/tst-relr-mod2.c
>  create mode 100644 elf/tst-relr-mod3a.c
>  create mode 100644 elf/tst-relr-mod3b.c
>  create mode 100644 elf/tst-relr-mod4a.c
>  create mode 100644 elf/tst-relr-mod4b.c
>  create mode 100644 elf/tst-relr-mod4b.map
>  create mode 100644 elf/tst-relr2.c
>  create mode 100644 elf/tst-relr3.c
>  create mode 100644 elf/tst-relr4.c
> 
> diff --git a/elf/Makefile b/elf/Makefile
> index 3f3e711dd2..07ac9ec3ef 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -544,7 +544,20 @@ endif
>  ifeq ($(have-dt-relr),yes)
>  tests += \
>    tst-relr \
> +  tst-relr2 \
> +  tst-relr3 \
> +  tst-relr4 \
>  # tests
> +modules-names-dt-relr = \
> +  tst-relr-mod2 \
> +  tst-relr-mod3a \
> +  tst-relr-mod3b \
> +  tst-relr-mod4a \
> +  tst-relr-mod4b \
> +# modules-names-dt-relr
> +modules-names += $(modules-names-dt-relr)
> +# These shared libraries have special build rules.
> +modules-names-nobuild += $(modules-names-dt-relr)
>  ifeq ($(have-fpie),yes)
>  tests += \
>    tst-relr-pie \
> @@ -603,7 +616,7 @@ test-extras += \
>    tst-tlsmod17a \
>    tst-tlsmod18a \
>    # test-extras
> -modules-names = \
> +modules-names += \
>    circlemod1 \
>    circlemod1a \
>    circlemod2 \
> @@ -973,8 +986,13 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
>  
>  # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
>  # rules.
> -modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \
> -			 tst-audit24bmod1 tst-audit24bmod2
> +modules-names-nobuild += \
> +  filtmod1 \
> +  tst-audit24bmod1 \
> +  tst-audit24bmod2 \
> +  tst-big-note-lib \
> +  tst-ro-dynamic-mod \
> +# modules-names-nobuild
>  
>  tests += $(tests-static)
>  

Ok.

> @@ -2768,3 +2786,50 @@ $(objpfx)check-tst-relr-pie.out: $(objpfx)tst-relr-pie
>  		| sed -ne '/required from libc.so/,$$ p' \
>  		| grep GLIBC_ABI_DT_RELR > $@; \
>  	$(evaluate-test)
> +
> +# The test checks if a DT_RELR shared library without DT_NEEDED works as
> +# intended, so it uses an explicit link rule.
> +$(objpfx)tst-relr2: $(objpfx)tst-relr-mod2.so
> +$(objpfx)tst-relr-mod2.so: $(objpfx)tst-relr-mod2.os
> +	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
> +	$(LDFLAGS-soname-fname) \
> +	-shared -o $@.new $(filter-out $(map-file),$^)
> +	$(call after-link,$@.new)
> +	mv -f $@.new $@
> +
> +# The test checks if a DT_RELR shared library without DT_VERNEED works as
> +# intended, so it uses an explicit link rule.
> +$(objpfx)tst-relr3: $(objpfx)tst-relr-mod3a.so
> +$(objpfx)tst-relr-mod3b.so: $(objpfx)tst-relr-mod3b.os
> +	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
> +	$(LDFLAGS-soname-fname) \
> +	-shared -o $@.new $(filter-out $(map-file),$^)
> +	$(call after-link,$@.new)
> +	mv -f $@.new $@
> +
> +$(objpfx)tst-relr-mod3a.so: $(objpfx)tst-relr-mod3a.os \
> +  $(objpfx)tst-relr-mod3b.so
> +	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
> +	$(LDFLAGS-soname-fname) \
> +	-shared -o $@.new $(filter-out $(map-file),$^)
> +	$(call after-link,$@.new)
> +	mv -f $@.new $@
> +
> +# The test checks if a DT_RELR shared library without libc.so on DT_NEEDED
> +# works as intended, so it uses an explicit link rule.
> +$(objpfx)tst-relr4: $(objpfx)tst-relr-mod4a.so
> +$(objpfx)tst-relr-mod4b.so: $(objpfx)tst-relr-mod4b.os
> +	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
> +	$(LDFLAGS-soname-fname) \
> +	-Wl,--version-script=tst-relr-mod4b.map \
> +	-shared -o $@.new $(filter-out $(map-file),$^)
> +	$(call after-link,$@.new)
> +	mv -f $@.new $@
> +
> +$(objpfx)tst-relr-mod4a.so: $(objpfx)tst-relr-mod4a.os \
> +  $(objpfx)tst-relr-mod4b.so
> +	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
> +	$(LDFLAGS-soname-fname) \
> +	-shared -o $@.new $(filter-out $(map-file),$^)
> +	$(call after-link,$@.new)
> +	mv -f $@.new $@

Ok.

> diff --git a/elf/tst-relr-mod2.c b/elf/tst-relr-mod2.c
> new file mode 100644
> index 0000000000..dc0a63365c
> --- /dev/null
> +++ b/elf/tst-relr-mod2.c
> @@ -0,0 +1,46 @@
> +/* Test for DT_RELR in a shared library without DT_NEEDED.
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <array_length.h>
> +
> +static int o, x;
> +
> +#define ELEMS O O O O O O O O X X X X X X X O O X O O X X X E X E E O X O E
> +#define E 0,
> +
> +#define O &o,
> +#define X &x,
> +void *arr[] = { ELEMS };
> +#undef O
> +#undef X
> +
> +#define O 1,
> +#define X 2,
> +static char val[] = { ELEMS };
> +
> +int
> +foo (void)
> +{
> +  int err = 0;
> +  for (int i = 0; i < array_length (arr); i++)
> +    if (!((arr[i] == 0 && val[i] == 0)
> +	  || (arr[i] == &o && val[i] == 1)
> +	  || (arr[i] == &x && val[i] == 2)))
> +      err++;
> +  return err;
> +}
> diff --git a/elf/tst-relr-mod3a.c b/elf/tst-relr-mod3a.c
> new file mode 100644
> index 0000000000..d1621c91b1
> --- /dev/null
> +++ b/elf/tst-relr-mod3a.c
> @@ -0,0 +1,49 @@
> +/* Test for DT_RELR in a shared library without DT_VERNEED.
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <array_length.h>
> +
> +static int o, x;
> +
> +#define ELEMS O O O O O O O O X X X X X X X O O X O O X X X E X E E O X O E
> +#define E 0,
> +
> +#define O &o,
> +#define X &x,
> +void *arr[] = { ELEMS };
> +#undef O
> +#undef X
> +
> +#define O 1,
> +#define X 2,
> +static char val[] = { ELEMS };
> +
> +extern void bar (void);
> +
> +int
> +foo (void)
> +{
> +  int err = 0;
> +  for (int i = 0; i < array_length (arr); i++)
> +    if (!((arr[i] == 0 && val[i] == 0)
> +	  || (arr[i] == &o && val[i] == 1)
> +	  || (arr[i] == &x && val[i] == 2)))
> +      err++;
> +  bar ();
> +  return err;
> +}
> diff --git a/elf/tst-relr-mod3b.c b/elf/tst-relr-mod3b.c
> new file mode 100644
> index 0000000000..544cb4bc05
> --- /dev/null
> +++ b/elf/tst-relr-mod3b.c
> @@ -0,0 +1,22 @@
> +/* Test for DT_RELR in a shared library without DT_VERNEED.
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +void
> +bar (void)
> +{
> +}
> diff --git a/elf/tst-relr-mod4a.c b/elf/tst-relr-mod4a.c
> new file mode 100644
> index 0000000000..e1bfebd4ac
> --- /dev/null
> +++ b/elf/tst-relr-mod4a.c
> @@ -0,0 +1,19 @@
> +/* Test for DT_RELR in a shared library without libc.so on DT_NEEDED.
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include "tst-relr-mod3a.c"
> diff --git a/elf/tst-relr-mod4b.c b/elf/tst-relr-mod4b.c
> new file mode 100644
> index 0000000000..617dff79c3
> --- /dev/null
> +++ b/elf/tst-relr-mod4b.c
> @@ -0,0 +1,19 @@
> +/* Test for DT_RELR in a shared library without libc.so on DT_NEEDED.
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include "tst-relr-mod3b.c"
> diff --git a/elf/tst-relr-mod4b.map b/elf/tst-relr-mod4b.map
> new file mode 100644
> index 0000000000..7f02247262
> --- /dev/null
> +++ b/elf/tst-relr-mod4b.map
> @@ -0,0 +1,3 @@
> +DT_RELR {
> +  global: bar;
> +};
> diff --git a/elf/tst-relr2.c b/elf/tst-relr2.c
> new file mode 100644
> index 0000000000..10d77f1791
> --- /dev/null
> +++ b/elf/tst-relr2.c
> @@ -0,0 +1,27 @@
> +/* Test for DT_RELR in a shared library without DT_NEEDED.
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +extern int foo (void);
> +
> +static int
> +do_test (void)
> +{
> +  return foo ();
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/elf/tst-relr3.c b/elf/tst-relr3.c
> new file mode 100644
> index 0000000000..69106cf7b7
> --- /dev/null
> +++ b/elf/tst-relr3.c
> @@ -0,0 +1,27 @@
> +/* Test for DT_RELR in a shared library without libc.so on DT_NEEDED.
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   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; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +extern int foo (void);
> +
> +static int
> +do_test (void)
> +{
> +  return foo ();
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/elf/tst-relr4.c b/elf/tst-relr4.c
> new file mode 100644
> index 0000000000..19a75013f8
> --- /dev/null
> +++ b/elf/tst-relr4.c
> @@ -0,0 +1 @@
> +#include "tst-relr3.c"

Ok.
Adhemerval Zanella Netto April 20, 2022, 5:41 p.m. UTC | #2
On 20/04/2022 14:24, Adhemerval Zanella wrote:
> 
> 
> On 14/04/2022 20:21, H.J. Lu wrote:
>> Verify that:
>>
>> 1. A DT_RELR shared library without DT_NEEDED works.
>> 2. A DT_RELR shared library without DT_VERNEED works.
>> 3. A DT_RELR shared library without libc.so on DT_NEEDED works.
> 
> LGTM, thanks.
> 
> Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
> 
>> ---
>>  elf/Makefile           | 71 ++++++++++++++++++++++++++++++++++++++++--
>>  elf/tst-relr-mod2.c    | 46 +++++++++++++++++++++++++++
>>  elf/tst-relr-mod3a.c   | 49 +++++++++++++++++++++++++++++
>>  elf/tst-relr-mod3b.c   | 22 +++++++++++++
>>  elf/tst-relr-mod4a.c   | 19 +++++++++++
>>  elf/tst-relr-mod4b.c   | 19 +++++++++++
>>  elf/tst-relr-mod4b.map |  3 ++
>>  elf/tst-relr2.c        | 27 ++++++++++++++++
>>  elf/tst-relr3.c        | 27 ++++++++++++++++
>>  elf/tst-relr4.c        |  1 +
>>  10 files changed, 281 insertions(+), 3 deletions(-)
>>  create mode 100644 elf/tst-relr-mod2.c
>>  create mode 100644 elf/tst-relr-mod3a.c
>>  create mode 100644 elf/tst-relr-mod3b.c
>>  create mode 100644 elf/tst-relr-mod4a.c
>>  create mode 100644 elf/tst-relr-mod4b.c
>>  create mode 100644 elf/tst-relr-mod4b.map
>>  create mode 100644 elf/tst-relr2.c
>>  create mode 100644 elf/tst-relr3.c
>>  create mode 100644 elf/tst-relr4.c
>>
>> diff --git a/elf/Makefile b/elf/Makefile
>> index 3f3e711dd2..07ac9ec3ef 100644
>> --- a/elf/Makefile
>> +++ b/elf/Makefile
>> @@ -544,7 +544,20 @@ endif
>>  ifeq ($(have-dt-relr),yes)
>>  tests += \
>>    tst-relr \
>> +  tst-relr2 \
>> +  tst-relr3 \
>> +  tst-relr4 \
>>  # tests
>> +modules-names-dt-relr = \
>> +  tst-relr-mod2 \
>> +  tst-relr-mod3a \
>> +  tst-relr-mod3b \
>> +  tst-relr-mod4a \
>> +  tst-relr-mod4b \
>> +# modules-names-dt-relr
>> +modules-names += $(modules-names-dt-relr)
>> +# These shared libraries have special build rules.
>> +modules-names-nobuild += $(modules-names-dt-relr)
>>  ifeq ($(have-fpie),yes)
>>  tests += \
>>    tst-relr-pie \
>> @@ -603,7 +616,7 @@ test-extras += \
>>    tst-tlsmod17a \
>>    tst-tlsmod18a \
>>    # test-extras
>> -modules-names = \
>> +modules-names += \
>>    circlemod1 \
>>    circlemod1a \
>>    circlemod2 \
>> @@ -973,8 +986,13 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
>>  
>>  # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
>>  # rules.
>> -modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \
>> -			 tst-audit24bmod1 tst-audit24bmod2
>> +modules-names-nobuild += \
>> +  filtmod1 \
>> +  tst-audit24bmod1 \
>> +  tst-audit24bmod2 \
>> +  tst-big-note-lib \
>> +  tst-ro-dynamic-mod \
>> +# modules-names-nobuild
>>  
>>  tests += $(tests-static)
>>  
> 
> Ok.
> 
>> @@ -2768,3 +2786,50 @@ $(objpfx)check-tst-relr-pie.out: $(objpfx)tst-relr-pie
>>  		| sed -ne '/required from libc.so/,$$ p' \
>>  		| grep GLIBC_ABI_DT_RELR > $@; \
>>  	$(evaluate-test)
>> +
>> +# The test checks if a DT_RELR shared library without DT_NEEDED works as
>> +# intended, so it uses an explicit link rule.
>> +$(objpfx)tst-relr2: $(objpfx)tst-relr-mod2.so
>> +$(objpfx)tst-relr-mod2.so: $(objpfx)tst-relr-mod2.os
>> +	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
>> +	$(LDFLAGS-soname-fname) \
>> +	-shared -o $@.new $(filter-out $(map-file),$^)
>> +	$(call after-link,$@.new)
>> +	mv -f $@.new $@
>> +
>> +# The test checks if a DT_RELR shared library without DT_VERNEED works as
>> +# intended, so it uses an explicit link rule.
>> +$(objpfx)tst-relr3: $(objpfx)tst-relr-mod3a.so
>> +$(objpfx)tst-relr-mod3b.so: $(objpfx)tst-relr-mod3b.os
>> +	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
>> +	$(LDFLAGS-soname-fname) \
>> +	-shared -o $@.new $(filter-out $(map-file),$^)
>> +	$(call after-link,$@.new)
>> +	mv -f $@.new $@
>> +
>> +$(objpfx)tst-relr-mod3a.so: $(objpfx)tst-relr-mod3a.os \
>> +  $(objpfx)tst-relr-mod3b.so
>> +	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
>> +	$(LDFLAGS-soname-fname) \
>> +	-shared -o $@.new $(filter-out $(map-file),$^)
>> +	$(call after-link,$@.new)
>> +	mv -f $@.new $@
>> +
>> +# The test checks if a DT_RELR shared library without libc.so on DT_NEEDED
>> +# works as intended, so it uses an explicit link rule.
>> +$(objpfx)tst-relr4: $(objpfx)tst-relr-mod4a.so
>> +$(objpfx)tst-relr-mod4b.so: $(objpfx)tst-relr-mod4b.os
>> +	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
>> +	$(LDFLAGS-soname-fname) \
>> +	-Wl,--version-script=tst-relr-mod4b.map \
>> +	-shared -o $@.new $(filter-out $(map-file),$^)
>> +	$(call after-link,$@.new)
>> +	mv -f $@.new $@
>> +
>> +$(objpfx)tst-relr-mod4a.so: $(objpfx)tst-relr-mod4a.os \
>> +  $(objpfx)tst-relr-mod4b.so
>> +	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
>> +	$(LDFLAGS-soname-fname) \
>> +	-shared -o $@.new $(filter-out $(map-file),$^)
>> +	$(call after-link,$@.new)
>> +	mv -f $@.new $@
> 
> Ok.

In fact I am seeing issues on i686-linux-gnu where linking is failing with
a missing __stack_chk_fail_local if --enable-stack-protector is used. I
think you will need to explicit add libc_nonshared for this specific
shared objects:

diff --git a/elf/Makefile b/elf/Makefile
index bf8a61dc30..152e495b8d 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -2795,7 +2795,8 @@ $(objpfx)tst-relr2: $(objpfx)tst-relr-mod2.so
 $(objpfx)tst-relr-mod2.so: $(objpfx)tst-relr-mod2.os
        $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
        $(LDFLAGS-soname-fname) \
-       -shared -o $@.new $(filter-out $(map-file),$^)
+       -shared -o $@.new $(filter-out $(map-file),$^) \
+       $(common-objpfx)libc_nonshared.a
        $(call after-link,$@.new)
        mv -f $@.new $@
 
@@ -2805,7 +2806,8 @@ $(objpfx)tst-relr3: $(objpfx)tst-relr-mod3a.so
 $(objpfx)tst-relr-mod3b.so: $(objpfx)tst-relr-mod3b.os
        $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
        $(LDFLAGS-soname-fname) \
-       -shared -o $@.new $(filter-out $(map-file),$^)
+       -shared -o $@.new $(filter-out $(map-file),$^) \
+       $(common-objpfx)libc_nonshared.a
        $(call after-link,$@.new)
        mv -f $@.new $@
 
@@ -2813,7 +2815,8 @@ $(objpfx)tst-relr-mod3a.so: $(objpfx)tst-relr-mod3a.os \
   $(objpfx)tst-relr-mod3b.so
        $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
        $(LDFLAGS-soname-fname) \
-       -shared -o $@.new $(filter-out $(map-file),$^)
+       -shared -o $@.new $(filter-out $(map-file),$^) \
+       $(common-objpfx)libc_nonshared.a
        $(call after-link,$@.new)
        mv -f $@.new $@
 
@@ -2824,7 +2827,8 @@ $(objpfx)tst-relr-mod4b.so: $(objpfx)tst-relr-mod4b.os
        $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
        $(LDFLAGS-soname-fname) \
        -Wl,--version-script=tst-relr-mod4b.map \
-       -shared -o $@.new $(filter-out $(map-file),$^)
+       -shared -o $@.new $(filter-out $(map-file),$^) \
+       $(common-objpfx)libc_nonshared.a
        $(call after-link,$@.new)
        mv -f $@.new $@
 
@@ -2832,6 +2836,7 @@ $(objpfx)tst-relr-mod4a.so: $(objpfx)tst-relr-mod4a.os \
   $(objpfx)tst-relr-mod4b.so
        $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
        $(LDFLAGS-soname-fname) \
-       -shared -o $@.new $(filter-out $(map-file),$^)
+       -shared -o $@.new $(filter-out $(map-file),$^) \
+       $(common-objpfx)libc_nonshared.a
        $(call after-link,$@.new)
        mv -f $@.new $@
H.J. Lu April 22, 2022, 6:44 p.m. UTC | #3
On Wed, Apr 20, 2022 at 10:41 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 20/04/2022 14:24, Adhemerval Zanella wrote:
> >
> >
> > On 14/04/2022 20:21, H.J. Lu wrote:
> >> Verify that:
> >>
> >> 1. A DT_RELR shared library without DT_NEEDED works.
> >> 2. A DT_RELR shared library without DT_VERNEED works.
> >> 3. A DT_RELR shared library without libc.so on DT_NEEDED works.
> >
> > LGTM, thanks.
> >
> > Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
> >
> >> ---
> >>  elf/Makefile           | 71 ++++++++++++++++++++++++++++++++++++++++--
> >>  elf/tst-relr-mod2.c    | 46 +++++++++++++++++++++++++++
> >>  elf/tst-relr-mod3a.c   | 49 +++++++++++++++++++++++++++++
> >>  elf/tst-relr-mod3b.c   | 22 +++++++++++++
> >>  elf/tst-relr-mod4a.c   | 19 +++++++++++
> >>  elf/tst-relr-mod4b.c   | 19 +++++++++++
> >>  elf/tst-relr-mod4b.map |  3 ++
> >>  elf/tst-relr2.c        | 27 ++++++++++++++++
> >>  elf/tst-relr3.c        | 27 ++++++++++++++++
> >>  elf/tst-relr4.c        |  1 +
> >>  10 files changed, 281 insertions(+), 3 deletions(-)
> >>  create mode 100644 elf/tst-relr-mod2.c
> >>  create mode 100644 elf/tst-relr-mod3a.c
> >>  create mode 100644 elf/tst-relr-mod3b.c
> >>  create mode 100644 elf/tst-relr-mod4a.c
> >>  create mode 100644 elf/tst-relr-mod4b.c
> >>  create mode 100644 elf/tst-relr-mod4b.map
> >>  create mode 100644 elf/tst-relr2.c
> >>  create mode 100644 elf/tst-relr3.c
> >>  create mode 100644 elf/tst-relr4.c
> >>
> >> diff --git a/elf/Makefile b/elf/Makefile
> >> index 3f3e711dd2..07ac9ec3ef 100644
> >> --- a/elf/Makefile
> >> +++ b/elf/Makefile
> >> @@ -544,7 +544,20 @@ endif
> >>  ifeq ($(have-dt-relr),yes)
> >>  tests += \
> >>    tst-relr \
> >> +  tst-relr2 \
> >> +  tst-relr3 \
> >> +  tst-relr4 \
> >>  # tests
> >> +modules-names-dt-relr = \
> >> +  tst-relr-mod2 \
> >> +  tst-relr-mod3a \
> >> +  tst-relr-mod3b \
> >> +  tst-relr-mod4a \
> >> +  tst-relr-mod4b \
> >> +# modules-names-dt-relr
> >> +modules-names += $(modules-names-dt-relr)
> >> +# These shared libraries have special build rules.
> >> +modules-names-nobuild += $(modules-names-dt-relr)
> >>  ifeq ($(have-fpie),yes)
> >>  tests += \
> >>    tst-relr-pie \
> >> @@ -603,7 +616,7 @@ test-extras += \
> >>    tst-tlsmod17a \
> >>    tst-tlsmod18a \
> >>    # test-extras
> >> -modules-names = \
> >> +modules-names += \
> >>    circlemod1 \
> >>    circlemod1a \
> >>    circlemod2 \
> >> @@ -973,8 +986,13 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
> >>
> >>  # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
> >>  # rules.
> >> -modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \
> >> -                     tst-audit24bmod1 tst-audit24bmod2
> >> +modules-names-nobuild += \
> >> +  filtmod1 \
> >> +  tst-audit24bmod1 \
> >> +  tst-audit24bmod2 \
> >> +  tst-big-note-lib \
> >> +  tst-ro-dynamic-mod \
> >> +# modules-names-nobuild
> >>
> >>  tests += $(tests-static)
> >>
> >
> > Ok.
> >
> >> @@ -2768,3 +2786,50 @@ $(objpfx)check-tst-relr-pie.out: $(objpfx)tst-relr-pie
> >>              | sed -ne '/required from libc.so/,$$ p' \
> >>              | grep GLIBC_ABI_DT_RELR > $@; \
> >>      $(evaluate-test)
> >> +
> >> +# The test checks if a DT_RELR shared library without DT_NEEDED works as
> >> +# intended, so it uses an explicit link rule.
> >> +$(objpfx)tst-relr2: $(objpfx)tst-relr-mod2.so
> >> +$(objpfx)tst-relr-mod2.so: $(objpfx)tst-relr-mod2.os
> >> +    $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
> >> +    $(LDFLAGS-soname-fname) \
> >> +    -shared -o $@.new $(filter-out $(map-file),$^)
> >> +    $(call after-link,$@.new)
> >> +    mv -f $@.new $@
> >> +
> >> +# The test checks if a DT_RELR shared library without DT_VERNEED works as
> >> +# intended, so it uses an explicit link rule.
> >> +$(objpfx)tst-relr3: $(objpfx)tst-relr-mod3a.so
> >> +$(objpfx)tst-relr-mod3b.so: $(objpfx)tst-relr-mod3b.os
> >> +    $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
> >> +    $(LDFLAGS-soname-fname) \
> >> +    -shared -o $@.new $(filter-out $(map-file),$^)
> >> +    $(call after-link,$@.new)
> >> +    mv -f $@.new $@
> >> +
> >> +$(objpfx)tst-relr-mod3a.so: $(objpfx)tst-relr-mod3a.os \
> >> +  $(objpfx)tst-relr-mod3b.so
> >> +    $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
> >> +    $(LDFLAGS-soname-fname) \
> >> +    -shared -o $@.new $(filter-out $(map-file),$^)
> >> +    $(call after-link,$@.new)
> >> +    mv -f $@.new $@
> >> +
> >> +# The test checks if a DT_RELR shared library without libc.so on DT_NEEDED
> >> +# works as intended, so it uses an explicit link rule.
> >> +$(objpfx)tst-relr4: $(objpfx)tst-relr-mod4a.so
> >> +$(objpfx)tst-relr-mod4b.so: $(objpfx)tst-relr-mod4b.os
> >> +    $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
> >> +    $(LDFLAGS-soname-fname) \
> >> +    -Wl,--version-script=tst-relr-mod4b.map \
> >> +    -shared -o $@.new $(filter-out $(map-file),$^)
> >> +    $(call after-link,$@.new)
> >> +    mv -f $@.new $@
> >> +
> >> +$(objpfx)tst-relr-mod4a.so: $(objpfx)tst-relr-mod4a.os \
> >> +  $(objpfx)tst-relr-mod4b.so
> >> +    $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
> >> +    $(LDFLAGS-soname-fname) \
> >> +    -shared -o $@.new $(filter-out $(map-file),$^)
> >> +    $(call after-link,$@.new)
> >> +    mv -f $@.new $@
> >
> > Ok.
>
> In fact I am seeing issues on i686-linux-gnu where linking is failing with
> a missing __stack_chk_fail_local if --enable-stack-protector is used. I
> think you will need to explicit add libc_nonshared for this specific
> shared objects:
>
> diff --git a/elf/Makefile b/elf/Makefile
> index bf8a61dc30..152e495b8d 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -2795,7 +2795,8 @@ $(objpfx)tst-relr2: $(objpfx)tst-relr-mod2.so
>  $(objpfx)tst-relr-mod2.so: $(objpfx)tst-relr-mod2.os
>         $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
>         $(LDFLAGS-soname-fname) \
> -       -shared -o $@.new $(filter-out $(map-file),$^)
> +       -shared -o $@.new $(filter-out $(map-file),$^) \
> +       $(common-objpfx)libc_nonshared.a

These shared libraries shouldn't have any undefined symbols.
I am adding these in v11:

+CFLAGS-tst-relr-mod2.c += $(no-stack-protector)
+CFLAGS-tst-relr-mod3a.c += $(no-stack-protector)
+CFLAGS-tst-relr-mod3b.c += $(no-stack-protector)
+CFLAGS-tst-relr-mod4a.c += $(no-stack-protector)
+CFLAGS-tst-relr-mod4b.c += $(no-stack-protector)

>         $(call after-link,$@.new)
>         mv -f $@.new $@
>
> @@ -2805,7 +2806,8 @@ $(objpfx)tst-relr3: $(objpfx)tst-relr-mod3a.so
>  $(objpfx)tst-relr-mod3b.so: $(objpfx)tst-relr-mod3b.os
>         $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
>         $(LDFLAGS-soname-fname) \
> -       -shared -o $@.new $(filter-out $(map-file),$^)
> +       -shared -o $@.new $(filter-out $(map-file),$^) \
> +       $(common-objpfx)libc_nonshared.a
>         $(call after-link,$@.new)
>         mv -f $@.new $@
>
> @@ -2813,7 +2815,8 @@ $(objpfx)tst-relr-mod3a.so: $(objpfx)tst-relr-mod3a.os \
>    $(objpfx)tst-relr-mod3b.so
>         $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
>         $(LDFLAGS-soname-fname) \
> -       -shared -o $@.new $(filter-out $(map-file),$^)
> +       -shared -o $@.new $(filter-out $(map-file),$^) \
> +       $(common-objpfx)libc_nonshared.a
>         $(call after-link,$@.new)
>         mv -f $@.new $@
>
> @@ -2824,7 +2827,8 @@ $(objpfx)tst-relr-mod4b.so: $(objpfx)tst-relr-mod4b.os
>         $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
>         $(LDFLAGS-soname-fname) \
>         -Wl,--version-script=tst-relr-mod4b.map \
> -       -shared -o $@.new $(filter-out $(map-file),$^)
> +       -shared -o $@.new $(filter-out $(map-file),$^) \
> +       $(common-objpfx)libc_nonshared.a
>         $(call after-link,$@.new)
>         mv -f $@.new $@
>
> @@ -2832,6 +2836,7 @@ $(objpfx)tst-relr-mod4a.so: $(objpfx)tst-relr-mod4a.os \
>    $(objpfx)tst-relr-mod4b.so
>         $(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
>         $(LDFLAGS-soname-fname) \
> -       -shared -o $@.new $(filter-out $(map-file),$^)
> +       -shared -o $@.new $(filter-out $(map-file),$^) \
> +       $(common-objpfx)libc_nonshared.a
>         $(call after-link,$@.new)
>         mv -f $@.new $@
>

Thanks.
diff mbox series

Patch

diff --git a/elf/Makefile b/elf/Makefile
index 3f3e711dd2..07ac9ec3ef 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -544,7 +544,20 @@  endif
 ifeq ($(have-dt-relr),yes)
 tests += \
   tst-relr \
+  tst-relr2 \
+  tst-relr3 \
+  tst-relr4 \
 # tests
+modules-names-dt-relr = \
+  tst-relr-mod2 \
+  tst-relr-mod3a \
+  tst-relr-mod3b \
+  tst-relr-mod4a \
+  tst-relr-mod4b \
+# modules-names-dt-relr
+modules-names += $(modules-names-dt-relr)
+# These shared libraries have special build rules.
+modules-names-nobuild += $(modules-names-dt-relr)
 ifeq ($(have-fpie),yes)
 tests += \
   tst-relr-pie \
@@ -603,7 +616,7 @@  test-extras += \
   tst-tlsmod17a \
   tst-tlsmod18a \
   # test-extras
-modules-names = \
+modules-names += \
   circlemod1 \
   circlemod1a \
   circlemod2 \
@@ -973,8 +986,13 @@  extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
 
 # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
 # rules.
-modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod \
-			 tst-audit24bmod1 tst-audit24bmod2
+modules-names-nobuild += \
+  filtmod1 \
+  tst-audit24bmod1 \
+  tst-audit24bmod2 \
+  tst-big-note-lib \
+  tst-ro-dynamic-mod \
+# modules-names-nobuild
 
 tests += $(tests-static)
 
@@ -2768,3 +2786,50 @@  $(objpfx)check-tst-relr-pie.out: $(objpfx)tst-relr-pie
 		| sed -ne '/required from libc.so/,$$ p' \
 		| grep GLIBC_ABI_DT_RELR > $@; \
 	$(evaluate-test)
+
+# The test checks if a DT_RELR shared library without DT_NEEDED works as
+# intended, so it uses an explicit link rule.
+$(objpfx)tst-relr2: $(objpfx)tst-relr-mod2.so
+$(objpfx)tst-relr-mod2.so: $(objpfx)tst-relr-mod2.os
+	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
+	$(LDFLAGS-soname-fname) \
+	-shared -o $@.new $(filter-out $(map-file),$^)
+	$(call after-link,$@.new)
+	mv -f $@.new $@
+
+# The test checks if a DT_RELR shared library without DT_VERNEED works as
+# intended, so it uses an explicit link rule.
+$(objpfx)tst-relr3: $(objpfx)tst-relr-mod3a.so
+$(objpfx)tst-relr-mod3b.so: $(objpfx)tst-relr-mod3b.os
+	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
+	$(LDFLAGS-soname-fname) \
+	-shared -o $@.new $(filter-out $(map-file),$^)
+	$(call after-link,$@.new)
+	mv -f $@.new $@
+
+$(objpfx)tst-relr-mod3a.so: $(objpfx)tst-relr-mod3a.os \
+  $(objpfx)tst-relr-mod3b.so
+	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
+	$(LDFLAGS-soname-fname) \
+	-shared -o $@.new $(filter-out $(map-file),$^)
+	$(call after-link,$@.new)
+	mv -f $@.new $@
+
+# The test checks if a DT_RELR shared library without libc.so on DT_NEEDED
+# works as intended, so it uses an explicit link rule.
+$(objpfx)tst-relr4: $(objpfx)tst-relr-mod4a.so
+$(objpfx)tst-relr-mod4b.so: $(objpfx)tst-relr-mod4b.os
+	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
+	$(LDFLAGS-soname-fname) \
+	-Wl,--version-script=tst-relr-mod4b.map \
+	-shared -o $@.new $(filter-out $(map-file),$^)
+	$(call after-link,$@.new)
+	mv -f $@.new $@
+
+$(objpfx)tst-relr-mod4a.so: $(objpfx)tst-relr-mod4a.os \
+  $(objpfx)tst-relr-mod4b.so
+	$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
+	$(LDFLAGS-soname-fname) \
+	-shared -o $@.new $(filter-out $(map-file),$^)
+	$(call after-link,$@.new)
+	mv -f $@.new $@
diff --git a/elf/tst-relr-mod2.c b/elf/tst-relr-mod2.c
new file mode 100644
index 0000000000..dc0a63365c
--- /dev/null
+++ b/elf/tst-relr-mod2.c
@@ -0,0 +1,46 @@ 
+/* Test for DT_RELR in a shared library without DT_NEEDED.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <array_length.h>
+
+static int o, x;
+
+#define ELEMS O O O O O O O O X X X X X X X O O X O O X X X E X E E O X O E
+#define E 0,
+
+#define O &o,
+#define X &x,
+void *arr[] = { ELEMS };
+#undef O
+#undef X
+
+#define O 1,
+#define X 2,
+static char val[] = { ELEMS };
+
+int
+foo (void)
+{
+  int err = 0;
+  for (int i = 0; i < array_length (arr); i++)
+    if (!((arr[i] == 0 && val[i] == 0)
+	  || (arr[i] == &o && val[i] == 1)
+	  || (arr[i] == &x && val[i] == 2)))
+      err++;
+  return err;
+}
diff --git a/elf/tst-relr-mod3a.c b/elf/tst-relr-mod3a.c
new file mode 100644
index 0000000000..d1621c91b1
--- /dev/null
+++ b/elf/tst-relr-mod3a.c
@@ -0,0 +1,49 @@ 
+/* Test for DT_RELR in a shared library without DT_VERNEED.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <array_length.h>
+
+static int o, x;
+
+#define ELEMS O O O O O O O O X X X X X X X O O X O O X X X E X E E O X O E
+#define E 0,
+
+#define O &o,
+#define X &x,
+void *arr[] = { ELEMS };
+#undef O
+#undef X
+
+#define O 1,
+#define X 2,
+static char val[] = { ELEMS };
+
+extern void bar (void);
+
+int
+foo (void)
+{
+  int err = 0;
+  for (int i = 0; i < array_length (arr); i++)
+    if (!((arr[i] == 0 && val[i] == 0)
+	  || (arr[i] == &o && val[i] == 1)
+	  || (arr[i] == &x && val[i] == 2)))
+      err++;
+  bar ();
+  return err;
+}
diff --git a/elf/tst-relr-mod3b.c b/elf/tst-relr-mod3b.c
new file mode 100644
index 0000000000..544cb4bc05
--- /dev/null
+++ b/elf/tst-relr-mod3b.c
@@ -0,0 +1,22 @@ 
+/* Test for DT_RELR in a shared library without DT_VERNEED.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+void
+bar (void)
+{
+}
diff --git a/elf/tst-relr-mod4a.c b/elf/tst-relr-mod4a.c
new file mode 100644
index 0000000000..e1bfebd4ac
--- /dev/null
+++ b/elf/tst-relr-mod4a.c
@@ -0,0 +1,19 @@ 
+/* Test for DT_RELR in a shared library without libc.so on DT_NEEDED.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include "tst-relr-mod3a.c"
diff --git a/elf/tst-relr-mod4b.c b/elf/tst-relr-mod4b.c
new file mode 100644
index 0000000000..617dff79c3
--- /dev/null
+++ b/elf/tst-relr-mod4b.c
@@ -0,0 +1,19 @@ 
+/* Test for DT_RELR in a shared library without libc.so on DT_NEEDED.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include "tst-relr-mod3b.c"
diff --git a/elf/tst-relr-mod4b.map b/elf/tst-relr-mod4b.map
new file mode 100644
index 0000000000..7f02247262
--- /dev/null
+++ b/elf/tst-relr-mod4b.map
@@ -0,0 +1,3 @@ 
+DT_RELR {
+  global: bar;
+};
diff --git a/elf/tst-relr2.c b/elf/tst-relr2.c
new file mode 100644
index 0000000000..10d77f1791
--- /dev/null
+++ b/elf/tst-relr2.c
@@ -0,0 +1,27 @@ 
+/* Test for DT_RELR in a shared library without DT_NEEDED.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+extern int foo (void);
+
+static int
+do_test (void)
+{
+  return foo ();
+}
+
+#include <support/test-driver.c>
diff --git a/elf/tst-relr3.c b/elf/tst-relr3.c
new file mode 100644
index 0000000000..69106cf7b7
--- /dev/null
+++ b/elf/tst-relr3.c
@@ -0,0 +1,27 @@ 
+/* Test for DT_RELR in a shared library without libc.so on DT_NEEDED.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+extern int foo (void);
+
+static int
+do_test (void)
+{
+  return foo ();
+}
+
+#include <support/test-driver.c>
diff --git a/elf/tst-relr4.c b/elf/tst-relr4.c
new file mode 100644
index 0000000000..19a75013f8
--- /dev/null
+++ b/elf/tst-relr4.c
@@ -0,0 +1 @@ 
+#include "tst-relr3.c"