mirror of
git://sourceware.org/git/glibc.git
synced 2026-10-28 14:16:45 +08:00
powerpc: Fix stack buffer overflow in _dl_reloc_overflow/_dl_error_localentry (bug 34541)
Consolidate the 32-bit and 64-bit implementation and use _dl_exception_create_format to create an exception message of the correct size. Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
committed by
Adhemerval Zanella
co-authored by
Adhemerval Zanella
parent
76c3d4472f
commit
a9d335d922
@@ -130,12 +130,14 @@ _dl_exception_create_format (struct dl_exception *exception, const char *objname
|
||||
case 'z':
|
||||
if (p[1] == 'x')
|
||||
{
|
||||
va_arg (ap, unsigned long int);
|
||||
length += LONG_WIDTH / 4;
|
||||
++p;
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case 'x':
|
||||
va_arg (ap, unsigned int);
|
||||
length += INT_WIDTH / 4;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -90,6 +90,11 @@ do_test (void)
|
||||
TEST_LONG ("fffffffe", "test", "%zx", (size_t)~1ul);
|
||||
TEST_LONG ("fffffffe-test", "test", "%zx-test", (size_t)~1ul);
|
||||
|
||||
TEST ("0000007b-test", NULL, "%x-%s", 123, "test");
|
||||
TEST ("0000007b-test-000001c8", NULL, "%x-%s-%x", 123, "test", 456);
|
||||
TEST_LONG ("fffffffd-test", NULL, "%lx-%s", (long int)~2ul, "test");
|
||||
TEST_LONG ("fffffffe-test", NULL, "%zx-%s", (size_t)~1ul, "test");
|
||||
|
||||
struct support_capture_subprocess result;
|
||||
result = support_capture_subprocess (do_test_invalid_conversion, NULL);
|
||||
support_capture_subprocess_check (&result, "dl-exception",
|
||||
|
||||
@@ -4,7 +4,7 @@ endif
|
||||
|
||||
ifeq ($(subdir),elf)
|
||||
# extra shared linker files to link into dl-allobjs.so and libc
|
||||
sysdep-dl-routines += dl-machine hwcapinfo
|
||||
sysdep-dl-routines += dl-machine dl-reloc_overflow hwcapinfo
|
||||
sysdep_routines += dl-machine hwcapinfo
|
||||
# extra shared linker files to link only into dl-allobjs.so
|
||||
sysdep-rtld-routines += dl-machine hwcapinfo
|
||||
@@ -14,6 +14,12 @@ mod-tlsopt-powerpc.so-no-z-defs = yes
|
||||
tests += tst-tlsopt-powerpc
|
||||
$(objpfx)tst-tlsopt-powerpc: $(objpfx)mod-tlsopt-powerpc.so
|
||||
|
||||
tests += tst-reloc-overflow
|
||||
modules-names += tst-reloc-overflow-mod tst-reloc-overflow-lib
|
||||
$(objpfx)tst-reloc-overflow: $(libdl)
|
||||
$(objpfx)tst-reloc-overflow.out: $(objpfx)tst-reloc-overflow-mod.so
|
||||
$(objpfx)tst-reloc-overflow-mod.so: $(objpfx)tst-reloc-overflow-lib.so
|
||||
|
||||
tests-static += tst-cache-ppc-static
|
||||
tests-internal += tst-cache-ppc-static
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* Relocation overflow reporting for POWER.
|
||||
Copyright (C) 1995-2026 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 Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <ldsodefs.h>
|
||||
#include <dl-machine.h>
|
||||
|
||||
void
|
||||
_dl_reloc_overflow (struct link_map *map, const char *name,
|
||||
ElfW(Addr) *const reloc_addr, const ElfW(Sym) *refsym)
|
||||
{
|
||||
struct dl_exception exc;
|
||||
|
||||
if (refsym != NULL)
|
||||
{
|
||||
const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
_dl_exception_create_format
|
||||
(&exc, map->l_name, "%s reloc at 0x%lx for symbol `%s' out of range",
|
||||
name, (unsigned long int) reloc_addr, strtab + refsym->st_name);
|
||||
}
|
||||
else
|
||||
_dl_exception_create_format
|
||||
(&exc, map->l_name, "%s reloc at 0x%lx out of range",
|
||||
name, (unsigned long int) reloc_addr);
|
||||
|
||||
_dl_signal_exception (0, &exc, NULL);
|
||||
}
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <ldsodefs.h>
|
||||
#include <elf/dynamic-link.h>
|
||||
#include <dl-machine.h>
|
||||
#include <_itoa.h>
|
||||
|
||||
/* Stuff for the PLT. */
|
||||
#define PLT_INITIAL_ENTRY_WORDS 18
|
||||
@@ -377,30 +376,6 @@ __elf_machine_fixup_plt (struct link_map *map,
|
||||
return finaladdr;
|
||||
}
|
||||
|
||||
void
|
||||
_dl_reloc_overflow (struct link_map *map,
|
||||
const char *name,
|
||||
Elf32_Addr *const reloc_addr,
|
||||
const Elf32_Sym *refsym)
|
||||
{
|
||||
char buffer[128];
|
||||
char *t;
|
||||
t = stpcpy (buffer, name);
|
||||
t = stpcpy (t, " relocation at 0x00000000");
|
||||
_itoa_word ((unsigned) reloc_addr, t, 16, 0);
|
||||
if (refsym)
|
||||
{
|
||||
const char *strtab;
|
||||
|
||||
strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
t = stpcpy (t, " for symbol `");
|
||||
t = stpcpy (t, strtab + refsym->st_name);
|
||||
t = stpcpy (t, "'");
|
||||
}
|
||||
t = stpcpy (t, " out of range");
|
||||
_dl_signal_error (0, map->l_name, NULL, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
__process_machine_rela (struct link_map *map,
|
||||
const Elf32_Rela *reloc,
|
||||
|
||||
@@ -261,6 +261,12 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
|
||||
#define ARCH_LA_PLTENTER ppc32_gnu_pltenter
|
||||
#define ARCH_LA_PLTEXIT ppc32_gnu_pltexit
|
||||
|
||||
/* Call _dl_signal_error when a resolved value overflows a relocated area. */
|
||||
extern void attribute_hidden _dl_reloc_overflow (struct link_map *map,
|
||||
const char *name,
|
||||
ElfW(Addr) *const reloc_addr,
|
||||
const ElfW(Sym) *refsym);
|
||||
|
||||
#endif /* dl_machine_h */
|
||||
|
||||
#ifdef RESOLVE_MAP
|
||||
@@ -277,12 +283,6 @@ extern void __process_machine_rela (struct link_map *map,
|
||||
int rinfo, bool skip_ifunc)
|
||||
attribute_hidden;
|
||||
|
||||
/* Call _dl_signal_error when a resolved value overflows a relocated area. */
|
||||
extern void _dl_reloc_overflow (struct link_map *map,
|
||||
const char *name,
|
||||
Elf32_Addr *const reloc_addr,
|
||||
const Elf32_Sym *refsym) attribute_hidden;
|
||||
|
||||
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
|
||||
LOADADDR is the load address of the object; INFO is an array indexed
|
||||
by DT_* of the .dynamic section info. */
|
||||
|
||||
@@ -16,51 +16,18 @@
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ldsodefs.h>
|
||||
#include <_itoa.h>
|
||||
#include <dl-machine.h>
|
||||
|
||||
void
|
||||
_dl_reloc_overflow (struct link_map *map,
|
||||
const char *name,
|
||||
Elf64_Addr *const reloc_addr,
|
||||
const Elf64_Sym *refsym)
|
||||
{
|
||||
char buffer[1024];
|
||||
char *t;
|
||||
t = stpcpy (buffer, name);
|
||||
/* Notice that _itoa_word() writes characters from the higher address to the
|
||||
lower address, requiring the destination string to reserve all the
|
||||
required size before the call. */
|
||||
t = stpcpy (t, " reloc at 0x0000000000000000");
|
||||
_itoa_word ((unsigned long) reloc_addr, t, 16, 0);
|
||||
if (refsym)
|
||||
{
|
||||
const char *strtab;
|
||||
|
||||
strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
t = stpcpy (t, " for symbol `");
|
||||
t = stpcpy (t, strtab + refsym->st_name);
|
||||
t = stpcpy (t, "'");
|
||||
}
|
||||
t = stpcpy (t, " out of range");
|
||||
_dl_signal_error (0, map->l_name, NULL, buffer);
|
||||
}
|
||||
|
||||
#if _CALL_ELF == 2
|
||||
void
|
||||
_dl_error_localentry (struct link_map *map, const Elf64_Sym *refsym)
|
||||
{
|
||||
char buffer[1024];
|
||||
char *t;
|
||||
const char *strtab;
|
||||
const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
|
||||
strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
t = stpcpy (buffer, "expected localentry:0 `");
|
||||
t = stpcpy (t, strtab + refsym->st_name);
|
||||
t = stpcpy (t, "'");
|
||||
_dl_signal_error (0, map->l_name, NULL, buffer);
|
||||
struct dl_exception exc;
|
||||
_dl_exception_create_format (&exc, map->l_name, "expected localentry:0 `%s'",
|
||||
strtab + refsym->st_name);
|
||||
_dl_signal_exception (0, &exc, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -590,6 +590,12 @@ ppc_init_fake_thread_pointer (void)
|
||||
ppc_init_fake_thread_pointer ();
|
||||
#endif /* ENABLE_STATIC_PIE && !defined SHARED && !IS_IN (rtld) */
|
||||
|
||||
/* Call _dl_signal_error when a resolved value overflows a relocated area. */
|
||||
extern void attribute_hidden _dl_reloc_overflow (struct link_map *map,
|
||||
const char *name,
|
||||
ElfW(Addr) *const reloc_addr,
|
||||
const ElfW(Sym) *refsym);
|
||||
|
||||
#endif /* dl_machine_h */
|
||||
|
||||
#ifdef RESOLVE_MAP
|
||||
@@ -606,11 +612,6 @@ ppc_init_fake_thread_pointer (void)
|
||||
|
||||
#define dont_expect(X) __builtin_expect ((X), 0)
|
||||
|
||||
extern void attribute_hidden _dl_reloc_overflow (struct link_map *map,
|
||||
const char *name,
|
||||
Elf64_Addr *const reloc_addr,
|
||||
const Elf64_Sym *refsym);
|
||||
|
||||
static inline void __attribute__ ((always_inline))
|
||||
elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
|
||||
void *const reloc_addr_arg)
|
||||
|
||||
@@ -237,4 +237,18 @@ ifeq (no,$(build-hardcoded-path-in-tests))
|
||||
tests-container += tst-glibc-hwcaps-cache
|
||||
endif
|
||||
|
||||
tests += tst-localentry
|
||||
modules-names += tst-localentry-mod tst-localentry-callee \
|
||||
tst-localentry-callee-v0
|
||||
|
||||
# Both callees share a soname, so the module records a DT_NEEDED on
|
||||
# tst-localentry-callee.so while being linked against the v0 definition.
|
||||
LDFLAGS-tst-localentry-callee-v0.so += -Wl,-soname,tst-localentry-callee.so
|
||||
LDFLAGS-tst-localentry-mod.so += -Wl,--plt-localentry
|
||||
|
||||
$(objpfx)tst-localentry: $(libdl)
|
||||
$(objpfx)tst-localentry.out: $(objpfx)tst-localentry-mod.so \
|
||||
$(objpfx)tst-localentry-callee.so
|
||||
$(objpfx)tst-localentry-mod.so: $(objpfx)tst-localentry-callee-v0.so
|
||||
|
||||
endif # $(subdir) == elf
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/* Callee with a local entry point of zero, used at link time.
|
||||
Copyright (C) 2026 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-localentry-name.h"
|
||||
|
||||
/* The modules required st_other to have localentry:0, because that is what
|
||||
makes ld optimize the module's call under --plt-localentry.
|
||||
|
||||
This is written in assembly to assure the code generation decision
|
||||
regardless of compiler flags (like stack protection) which change how
|
||||
the leaf function returns the value. */
|
||||
|
||||
.abiversion 2
|
||||
.section ".text"
|
||||
.globl LOCALENTRY_SYMBOL
|
||||
.type LOCALENTRY_SYMBOL, @function
|
||||
LOCALENTRY_SYMBOL:
|
||||
.localentry LOCALENTRY_SYMBOL, 0
|
||||
li 3, 42
|
||||
blr
|
||||
.size LOCALENTRY_SYMBOL, .-LOCALENTRY_SYMBOL
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Callee with a non-zero local entry point, substituted at run time.
|
||||
Copyright (C) 2026 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-localentry-name.h"
|
||||
|
||||
/* The same symbol with a global entry sequence that sets up r2, so st_other
|
||||
says localentry:8. Resolving the module's optimized call to this
|
||||
definition is the ABI violation ld.so has to reject. */
|
||||
|
||||
.abiversion 2
|
||||
.section ".text"
|
||||
.globl LOCALENTRY_SYMBOL
|
||||
.type LOCALENTRY_SYMBOL, @function
|
||||
LOCALENTRY_SYMBOL:
|
||||
0: addis 2, 12, .TOC.-0b@ha
|
||||
addi 2, 2, .TOC.-0b@l
|
||||
.localentry LOCALENTRY_SYMBOL, .-LOCALENTRY_SYMBOL
|
||||
li 3, 43
|
||||
blr
|
||||
.size LOCALENTRY_SYMBOL, .-LOCALENTRY_SYMBOL
|
||||
@@ -0,0 +1,27 @@
|
||||
/* Module whose PLT call was optimized for a localentry:0 callee.
|
||||
Copyright (C) 2026 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-localentry-name.h"
|
||||
|
||||
extern int LOCALENTRY_SYMBOL (void);
|
||||
|
||||
int
|
||||
call_it (void)
|
||||
{
|
||||
return LOCALENTRY_SYMBOL ();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/* Overly long symbol name shared by the local entry point test.
|
||||
Copyright (C) 2026 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/>. */
|
||||
|
||||
#ifndef _TST_LOCALENTRY_NAME_H
|
||||
#define _TST_LOCALENTRY_NAME_H 1
|
||||
|
||||
#define CAT_(a, b) a##b
|
||||
#define CAT(a, b) CAT_(a, b)
|
||||
|
||||
#define N16 xxxxxxxxxxxxxxxx
|
||||
#define N32 CAT (N16, N16)
|
||||
#define N64 CAT (N32, N32)
|
||||
#define N128 CAT (N64, N64)
|
||||
#define N256 CAT (N128, N128)
|
||||
#define N512 CAT (N256, N256)
|
||||
#define N1024 CAT (N512, N512)
|
||||
#define N2048 CAT (N1024, N1024)
|
||||
#define N4096 CAT (N2048, N2048)
|
||||
#define N8192 CAT (N4096, N4096)
|
||||
|
||||
#define LOCALENTRY_SYMBOL CAT (tst_localentry_symbol_, N8192)
|
||||
|
||||
#define STR_(x) #x
|
||||
#define STR(x) STR_(x)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/* Check the message for a local entry point mismatch (bug 34541).
|
||||
Copyright (C) 2026 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 <dlfcn.h>
|
||||
#include <string.h>
|
||||
#include <support/check.h>
|
||||
|
||||
#include "tst-localentry-name.h"
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
void *h = dlopen ("tst-localentry-mod.so", RTLD_NOW);
|
||||
TEST_VERIFY (h == NULL);
|
||||
|
||||
const char *msg = dlerror ();
|
||||
TEST_VERIFY_EXIT (msg != NULL);
|
||||
|
||||
TEST_VERIFY (strstr (msg, STR (LOCALENTRY_SYMBOL)) != NULL);
|
||||
TEST_VERIFY (strstr (msg, "expected localentry:0") != NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
||||
@@ -0,0 +1,21 @@
|
||||
/* Definition of the symbol the relocation overflow test refers to.
|
||||
Copyright (C) 2026 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-reloc-overflow-name.h"
|
||||
|
||||
int OVERFLOW_SYMBOL = 42;
|
||||
@@ -0,0 +1,29 @@
|
||||
/* Module with an out of range R_PPC*_ADDR16 relocation.
|
||||
Copyright (C) 2026 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-reloc-overflow-name.h"
|
||||
|
||||
/* _dl_reloc_overflow is only reached for relocation types that store an
|
||||
address into a field narrower than a pointer. */
|
||||
|
||||
.data
|
||||
.globl refword
|
||||
.type refword, @object
|
||||
refword:
|
||||
.short OVERFLOW_SYMBOL
|
||||
.size refword, 2
|
||||
@@ -0,0 +1,41 @@
|
||||
/* Overly long symbol name shared by the relocation overflow test.
|
||||
Copyright (C) 2026 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/>. */
|
||||
|
||||
#ifndef _TST_RELOC_OVERFLOW_NAME_H
|
||||
#define _TST_RELOC_OVERFLOW_NAME_H 1
|
||||
|
||||
#define CAT_(a, b) a##b
|
||||
#define CAT(a, b) CAT_(a, b)
|
||||
|
||||
#define N16 xxxxxxxxxxxxxxxx
|
||||
#define N32 CAT (N16, N16)
|
||||
#define N64 CAT (N32, N32)
|
||||
#define N128 CAT (N64, N64)
|
||||
#define N256 CAT (N128, N128)
|
||||
#define N512 CAT (N256, N256)
|
||||
#define N1024 CAT (N512, N512)
|
||||
#define N2048 CAT (N1024, N1024)
|
||||
#define N4096 CAT (N2048, N2048)
|
||||
#define N8192 CAT (N4096, N4096)
|
||||
|
||||
#define OVERFLOW_SYMBOL CAT (tst_reloc_overflow_symbol_, N8192)
|
||||
|
||||
#define STR_(x) #x
|
||||
#define STR(x) STR_(x)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/* Check the message for an out of range relocation (bug 34541).
|
||||
Copyright (C) 2026 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 <dlfcn.h>
|
||||
#include <string.h>
|
||||
#include <support/check.h>
|
||||
|
||||
#include "tst-reloc-overflow-name.h"
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
void *h = dlopen ("tst-reloc-overflow-mod.so", RTLD_NOW);
|
||||
TEST_VERIFY (h == NULL);
|
||||
|
||||
const char *msg = dlerror ();
|
||||
TEST_VERIFY_EXIT (msg != NULL);
|
||||
|
||||
TEST_VERIFY (strstr (msg, STR (OVERFLOW_SYMBOL)) != NULL);
|
||||
TEST_VERIFY (strstr (msg, "out of range") != NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
||||
Reference in New Issue
Block a user