Import RHEL's test Sanity/dts-probe-binaries

Unchanged yet, failing on Fedora Rawhide. I'll fix it in the
upcoming commit.
This commit is contained in:
Václav Kadlčík 2021-05-12 05:39:34 +02:00
parent 8e50243c45
commit 22348da57d
8 changed files with 846 additions and 0 deletions

View File

@ -0,0 +1,63 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /tools/binutils/Sanity/dts-probe-binaries
# Description: Toolset binutils on system/toolset/built binaries.
# Author: Marek Polacek <polacek@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/tools/binutils/Sanity/dts-probe-binaries
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE check-localplt.c m.c popcnt.c virtual2.C
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Marek Polacek <mpolacek@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Toolset binutils on system/toolset/built binaries." >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 120m" >> $(METADATA)
@echo "RunFor: binutils" >> $(METADATA)
@echo "Requires: binutils ed gcc glibc glibc-headers grep gdb gcc-c++ gawk" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -0,0 +1,3 @@
PURPOSE of /tools/binutils/Sanity/dts-probe-binaries
Description: Toolset binutils on system/toolset/built binaries.
Author: Marek Polacek <polacek@redhat.com>

View File

@ -0,0 +1,298 @@
/* Show local PLT use in DSOs.
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contribute by Ulrich Drepper <drepper@redhat.com>. 2006.
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
<http://www.gnu.org/licenses/>. */
#include <byteswap.h>
#include <elf.h>
#include <endian.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef BITS
# define AB(name) _AB (name, BITS)
# define _AB(name, bits) __AB (name, bits)
# define __AB(name, bits) name##bits
# define E(name) _E (name, BITS)
# define _E(name, bits) __E (name, bits)
# define __E(name, bits) Elf##bits##_##name
# define EE(name) _EE (name, BITS)
# define _EE(name, bits) __EE (name, bits)
# define __EE(name, bits) ELF##bits##_##name
# define SWAP(val) \
({ __typeof (val) __res; \
if (((ehdr.e_ident[EI_DATA] == ELFDATA2MSB \
&& BYTE_ORDER == LITTLE_ENDIAN) \
|| (ehdr.e_ident[EI_DATA] == ELFDATA2LSB \
&& BYTE_ORDER == BIG_ENDIAN)) \
&& sizeof (val) != 1) \
{ \
if (sizeof (val) == 2) \
__res = bswap_16 (val); \
else if (sizeof (val) == 4) \
__res = bswap_32 (val); \
else \
__res = bswap_64 (val); \
} \
else \
__res = (val); \
__res; })
static int
AB(handle_file) (const char *fname, int fd)
{
E(Ehdr) ehdr;
if (pread (fd, &ehdr, sizeof (ehdr), 0) != sizeof (ehdr))
{
read_error:
printf ("%s: read error: %m\n", fname);
return 1;
}
const size_t phnum = SWAP (ehdr.e_phnum);
const size_t phentsize = SWAP (ehdr.e_phentsize);
/* Read the program header. */
E(Phdr) *phdr = alloca (phentsize * phnum);
if (pread (fd, phdr, phentsize * phnum, SWAP (ehdr.e_phoff))
!= phentsize * phnum)
goto read_error;
/* Search for the PT_DYNAMIC entry. */
size_t cnt;
E(Phdr) *dynphdr = NULL;
for (cnt = 0; cnt < phnum; ++cnt)
if (SWAP (phdr[cnt].p_type) == PT_DYNAMIC)
{
dynphdr = &phdr[cnt];
break;
}
if (dynphdr == NULL)
{
printf ("%s: no DYNAMIC segment found\n", fname);
return 1;
}
/* Read the dynamic segment. */
size_t pmemsz = SWAP(dynphdr->p_memsz);
E(Dyn) *dyn = alloca (pmemsz);
if (pread64 (fd, dyn, pmemsz, SWAP(dynphdr->p_offset)) != pmemsz)
goto read_error;
/* Search for an DT_PLTREL, DT_JMPREL, DT_PLTRELSZ, DT_STRTAB,
DT_STRSZ, and DT_SYMTAB entries. */
size_t pltrel_idx = SIZE_MAX;
size_t jmprel_idx = SIZE_MAX;
size_t pltrelsz_idx = SIZE_MAX;
size_t strtab_idx = SIZE_MAX;
size_t strsz_idx = SIZE_MAX;
size_t symtab_idx = SIZE_MAX;
for (cnt = 0; (cnt + 1) * sizeof (E(Dyn)) - 1 < pmemsz; ++cnt)
{
unsigned int tag = SWAP (dyn[cnt].d_tag);
if (tag == DT_NULL)
/* We reached the end. */
break;
if (tag == DT_PLTREL)
pltrel_idx = cnt;
else if (tag == DT_JMPREL)
jmprel_idx = cnt;
else if (tag == DT_PLTRELSZ)
pltrelsz_idx = cnt;
else if (tag == DT_STRTAB)
strtab_idx = cnt;
else if (tag == DT_STRSZ)
strsz_idx = cnt;
else if (tag == DT_SYMTAB)
symtab_idx = cnt;
}
if (pltrel_idx == SIZE_MAX || jmprel_idx == SIZE_MAX
|| pltrelsz_idx == SIZE_MAX || strtab_idx == SIZE_MAX
|| strsz_idx == SIZE_MAX || symtab_idx == SIZE_MAX)
{
puts ("not all PLT information found");
return 1;
}
E(Xword) relsz = SWAP (dyn[pltrelsz_idx].d_un.d_val);
void *relmem = NULL;
char *strtab = NULL;
E(Xword) symtab_offset = 0;
/* Find the offset of DT_JMPREL and load the data. */
for (cnt = 0; cnt < phnum; ++cnt)
if (SWAP (phdr[cnt].p_type) == PT_LOAD)
{
E(Addr) vaddr = SWAP (phdr[cnt].p_vaddr);
E(Xword) memsz = SWAP (phdr[cnt].p_memsz);
if (vaddr <= SWAP (dyn[jmprel_idx].d_un.d_val)
&& vaddr + memsz >= SWAP (dyn[jmprel_idx].d_un.d_val) + relsz)
{
relmem = alloca (SWAP (dyn[pltrelsz_idx].d_un.d_val));
if (pread64 (fd, relmem, relsz,
SWAP (phdr[cnt].p_offset)
+ SWAP (dyn[jmprel_idx].d_un.d_val) - vaddr)
!= relsz)
{
puts ("cannot read JMPREL");
return 1;
}
}
if (vaddr <= SWAP (dyn[symtab_idx].d_un.d_val)
&& vaddr + memsz > SWAP (dyn[symtab_idx].d_un.d_val))
symtab_offset = (SWAP (phdr[cnt].p_offset)
+ SWAP (dyn[symtab_idx].d_un.d_val) - vaddr);
if (vaddr <= SWAP (dyn[strtab_idx].d_un.d_val)
&& vaddr + memsz >= (SWAP (dyn[strtab_idx].d_un.d_val)
+ SWAP(dyn[strsz_idx].d_un.d_val)))
{
strtab = alloca (SWAP(dyn[strsz_idx].d_un.d_val));
if (pread64 (fd, strtab, SWAP(dyn[strsz_idx].d_un.d_val),
SWAP (phdr[cnt].p_offset)
+ SWAP (dyn[strtab_idx].d_un.d_val) - vaddr)
!= SWAP(dyn[strsz_idx].d_un.d_val))
{
puts ("cannot read STRTAB");
return 1;
}
}
}
if (relmem == NULL || strtab == NULL || symtab_offset == 0)
{
puts ("couldn't load PLT data");
return 1;
}
if (SWAP (dyn[pltrel_idx].d_un.d_val) == DT_RELA)
for (E(Rela) *rela = relmem; (char *) rela - (char *) relmem < relsz;
++rela)
{
E(Sym) sym;
if (pread64 (fd, &sym, sizeof (sym),
symtab_offset
+ EE(R_SYM) (SWAP (rela->r_info)) * sizeof (sym))
!= sizeof (sym))
{
puts ("cannot read symbol");
return 1;
}
if (sym.st_value != 0)
/* This symbol is locally defined. */
printf ("%s: %s\n", basename (fname), strtab + SWAP (sym.st_name));
}
else
for (E(Rel) *rel = relmem; (char *) rel - (char *) relmem < relsz; ++rel)
{
E(Sym) sym;
if (pread64 (fd, &sym, sizeof (sym),
symtab_offset
+ EE(R_SYM) (SWAP (rel->r_info)) * sizeof (sym))
!= sizeof (sym))
{
puts ("cannot read symbol");
return 1;
}
if (sym.st_value != 0)
/* This symbol is locally defined. */
printf ("%s: %s\n", basename (fname), strtab + SWAP (sym.st_name));
}
return 0;
}
# undef BITS
#else
# define BITS 32
# include "check-localplt.c"
# define BITS 64
# include "check-localplt.c"
static int
handle_file (const char *fname)
{
int fd = open (fname, O_RDONLY);
if (fd == -1)
{
printf ("cannot open %s: %m\n", fname);
return 1;
}
/* Read was is supposed to be the ELF header. Read the initial
bytes to determine whether this is a 32 or 64 bit file. */
char ident[EI_NIDENT];
if (read (fd, ident, EI_NIDENT) != EI_NIDENT)
{
printf ("%s: read error: %m\n", fname);
close (fd);
return 1;
}
if (memcmp (&ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
{
printf ("%s: not an ELF file\n", fname);
close (fd);
return 1;
}
int result;
if (ident[EI_CLASS] == ELFCLASS64)
result = handle_file64 (fname, fd);
else
result = handle_file32 (fname, fd);
close (fd);
return result;
}
int
main (int argc, char *argv[])
{
int cnt;
int result = 0;
for (cnt = 1; cnt < argc; ++cnt)
result |= handle_file (argv[cnt]);
return result;
}
#endif

View File

@ -0,0 +1,6 @@
int a (int), b (int), c (int);
int
main (void)
{
return a (6) + b (4) - c (2);
}

View File

@ -0,0 +1,20 @@
summary: Toolset binutils on system/toolset/built binaries.
description: ''
contact: Marek Polacek <mpolacek@redhat.com>
component:
- binutils
test: ./runtest.sh
framework: beakerlib
recommend:
- binutils
- ed
- gcc
- glibc
- glibc-headers
- grep
- gdb
- gcc-c++
- gawk
duration: 120m
extra-summary: /tools/binutils/Sanity/dts-probe-binaries
extra-task: /tools/binutils/Sanity/dts-probe-binaries

View File

@ -0,0 +1,7 @@
#include <stdio.h>
int
main (int argc, char *argv[] __attribute__((unused)))
{
printf ("%p\n", main);
return __builtin_popcount (argc);
}

View File

@ -0,0 +1,418 @@
#!/bin/bash
# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /tools/binutils/Sanity/dts-probe-binaries
# Description: Toolset binutils on system/toolset built binaries.
# Author: Marek Polacek <polacek@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# This is for DTS. But could be used even for RHEL versions.
# Include Beaker environment
. /usr/share/beakerlib/beakerlib.sh || exit 1
PACKAGES=(gdb gcc gcc-c++ binutils gawk grep)
# Choose the binaries.
GCC=${GCC:-gcc}
GXX=${GXX:-g++}
GDB=${GDB:-gdb}
AR=${AR:-ar}
ADDR2LINE=${ADDR2LINE:-addr2line}
CXXFILT=${CXXFILT:-c++filt}
ELFEDIT=${ELFEDIT:-elfedit}
NM=${NM:-nm}
OBJCOPY=${OBJCOPY:-objcopy}
OBJDUMP=${OBJDUMP:-objdump}
READELF=${READELF:-readelf}
SIZE=${SIZE:-size}
STRINGS=${STRINGS:-strings}
rlJournalStart
rlPhaseStartSetup
for p in "${PACKAGES[@]}"; do
rlAssertRpm "$p"
done; unset p
rpm -q devtoolset-1.0-binutils
rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
# Copy the GDB commands file and testcase.
rlRun "cp -v check-localplt.c m.c popcnt.c virtual2.C $TmpDir"
rlRun "pushd $TmpDir"
rlPhaseEnd
rlPhaseStartTest "Prepare a DTS binary."
# Compile a test case.
rlRun "$GCC -O2 -g -std=gnu99 check-localplt.c -o localplt"
rlAssertExists "localplt"
rlPhaseEnd
rlPhaseStartTest "Test ar."
# Test --help.
rlRun "$AR --help"
# We need a few ET_RELs.
rlRun "$GCC -O2 -g -std=gnu99 -c -o a.o -xc - <<< 'int a(int a){return a^2;}'"
rlAssertExists "a.o"
rlRun "$GCC -O2 -g -std=gnu99 -c -o b.o -xc - <<< 'int b(int a){return a&2;}'"
rlAssertExists "b.o"
rlRun "$GCC -O2 -g -std=gnu99 -c -o c.o -xc - <<< 'int c(int a){return a|2;}'"
rlAssertExists "c.o"
rlRun "$GCC -O2 -g -std=gnu99 -c -o d.o -xc - <<< 'int d(int a){return a%2;}'"
rlAssertExists "d.o"
# Test that we can create a static library.
rlRun "$AR crsv abc.a a.o b.o c.o"
rlAssertExists "abc.a"
# ...and use this library.
rlRun "$GCC -O2 -Wall -std=gnu99 m.c abc.a -o abc"
rlRun "./abc" 2
# Test -t option.
rlRun "$AR t abc.a > ar-t.out"
printf "a.o\nb.o\nc.o\n" > ar-t
rlAssertNotDiffer ar-t ar-t.out
# Test -d option.
rlRun "$AR d abc.a c.o"
rlRun "$AR t abc.a > ar-t.out"
printf "a.o\nb.o\n" > ar-t
rlAssertNotDiffer ar-t ar-t.out
# Test -r option.
rlRun "$AR r abc.a d.o"
rlRun "$AR t abc.a > ar-t.out"
printf "a.o\nb.o\nd.o\n" > ar-t
rlAssertNotDiffer ar-t ar-t.out
rlPhaseEnd
rlPhaseStartTest "Test addr2line."
rlRun "$ADDR2LINE --help"
# Compile a testcase.
rlRun "$GCC -g3 -Wall -O2 -o popcnt popcnt.c"
# Save the address where main resides.
./popcnt > a
rlRun "$ADDR2LINE -e popcnt $(cat a) > r"
# We know that main is at line 4. But on PPC we get ??:0...
if test ! $(uname -i) = "ppc64"; then
rlAssertGrep "popcnt.c:4" r
fi
rm -vf [ra]
rlPhaseEnd
rlPhaseStartTest "Test c++filt."
rlRun "$CXXFILT --help"
# Compile a testcase.
rlRun "$GXX -g -O0 virtual2.C -o virt"
rlRun "$NM virt | $CXXFILT &> f"
rlLogInfo "===== f"
rlLogInfo "$(cat f)"
rlLogInfo "====="
rlAssertGrep "A::~A()" f
rlAssertGrep "B::~B()" f
rlAssertGrep "typeinfo for A" f
rlAssertGrep "typeinfo for B" f
rlAssertGrep "typeinfo name for A" f
rlAssertGrep "typeinfo name for B" f
rlAssertGrep "vtable for A" f
rlAssertGrep "vtable for B" f
rlAssertGrep "operator delete(void\*)" f
rlRun "grep -E 'operator new\(unsigned (long|int)\)' f"
rlRun "$CXXFILT -n _Z1ft > f"
# Create test file.
echo "f(unsigned short)" > F
rlAssertNotDiffer F f
rm -vf [Ff]
rlPhaseEnd
# RHEL5/6 don't have elfedit.
elfedit --help
if test $? -eq 0; then
rlPhaseStartTest "Test elfedit."
rlRun "$ELFEDIT --help"
# Change the Ehdr somewhat.
rlRun "$ELFEDIT --output-osabi=TRU64 virt"
rlRun "$ELFEDIT --output-type=rel virt"
rlRun "$READELF -Wh virt > r"
rlAssertGrep "UNIX - TRU64" r
rlAssertGrep "REL (Relocatable file)" r
# Ok, back to normal.
rlRun "$ELFEDIT --output-osabi=none virt"
rlRun "$ELFEDIT --output-type=exec virt"
rlRun "$READELF -Wh virt > r"
rlAssertGrep "UNIX - System V" r
rlAssertGrep "EXEC (Executable file)" r
rm -vf r
rlPhaseEnd
fi
rlPhaseStartTest "Test nm."
rlRun "$NM --help"
# Try --debug-syms.
rlRun "$NM --debug-syms virt | gawk '{ print \$2 \" \" \$3 }' > o"
rlLogInfo "$(cat o)"
rlAssertGrep "completed" o
if [ "`rlGetPrimaryArch`" != "s390x" ] || [ ! rlIsRHEL 7 ]; then
rlAssertGrep "virtual2.C" o
fi
rlAssertGrep "_ZN1BD1Ev" o
rlAssertGrep ".dynstr" o
# On PPC, we have .toc instead.
if [ "$(rlGetPrimaryArch)" != "ppc64" ] && [ "$(rlGetPrimaryArch)" != "ppc64le" ]; then
rlAssertGrep "_GLOBAL_OFFSET_TABLE_" o
fi
# Try -u.
rlRun "$NM -u popcnt > u"
rlAssertGrep "printf@@GLIBC" u
if [ "`rlGetPrimaryArch`" != "ppc64" ] || [ ! rlIsRHEL 7 ]; then
rlAssertGrep "__gmon_start__" u
fi
rlAssertGrep "__libc_start_main@@GLIBC" u
# Try -P --size-sort.
rlRun "$NM -P --size-sort localplt > p"
if test $(uname -i) = "ppc64" -a $(rlGetDistroRelease) -gt 5; then
rlAssertGrep "__libc_csu_init D" p
rlAssertGrep "main D" p
else
rlAssertGrep "__libc_csu_init T" p
rlAssertGrep "main T" p
fi
rlAssertGrep "completed.* b" p
rlAssertGrep "_IO_stdin_used R" p
# Try --defined-only --print-size.
rlRun "$NM --defined-only --print-size localplt > d"
rm -vf [oupd]
rlPhaseEnd
rlPhaseStartTest "Test objcopy."
rlRun "$OBJCOPY --help"
# RHEL's dont know --compress-debug-sections. :-(
if ! :; then
# Try compressing.
cp -v virt zvirt
rlRun "$OBJCOPY --compress-debug-sections zvirt"
rlRun "$READELF -WS zvirt > c"
rlAssertGrep ".zdebug_*" c
rlRun "$OBJCOPY --decompress-debug-sections zvirt"
rlRun "$READELF -WS zvirt > v"
rlAssertNotGrep ".zdebug_*" v
fi
cp -v virt xvirt
if ! rlIsRHEL 5; then
rlRun "$OBJCOPY --only-section=.shstrtab xvirt"
rlRun "$READELF -WS xvirt > x"
rlAssertGrep ".shstrtab" x
fi
# Try to delete .interp section.
cp -v virt virt2
rlRun "$OBJCOPY -R .interp virt2"
rlRun "$READELF -WS virt2 > i"
rlAssertNotGrep ".interp" i
rm -vf [vcx] xvirt zvirt
rlPhaseEnd
rlPhaseStartTest "Test objdump."
rlRun "$OBJDUMP --help"
# Just try to run with -f.
rlRun "$OBJDUMP -f virt"
# Just try to run with -x.
rlRun "$OBJDUMP -wx virt"
# -dr. No good way how to compare this.
rlRun "$OBJDUMP -dr virt > d"
rlAssertGrep "Disassembly of section .text:" d
rlAssertGrep "_start" d
rlAssertGrep "main" d
# -T.
rlRun "$OBJDUMP -T virt > t"
rlAssertGrep "abort" t
# -R.
rlRun "$OBJDUMP -R virt > R"
rlAssertGrep "abort" R
# -Wl.
rlRun "$OBJDUMP -Wl virt > w"
rlAssertGrep "Extended opcode 2: set Address to" w
# -dr on system binary.
rlRun "$OBJDUMP -dr /bin/true > D"
rlAssertGrep "Disassembly of section .text:" d
rlAssertGrep "_start" d
rlAssertGrep "main" d
# -R on system binary.
rlRun "$OBJDUMP -R /bin/true > r"
rlAssertGrep "abort" r
# -T.
rlRun "$OBJDUMP -T /bin/true > T"
rlAssertGrep "abort" T
rm -vf [DdrtTwR]
rlPhaseEnd
rlPhaseStartTest "Test readelf."
# Readelf is probably most important, check more things.
rlRun "$READELF --help"
# Just run with -a.
rlRun "$READELF -Wa virt"
# Try -h.
rlRun "$READELF -Wh virt > h"
rlAssertGrep "ELF Header:" h
rlAssertGrep "7f 45 4c 46" h
rlAssertGrep "EXEC (Executable file)" h
rlAssertGrep "Section header string table index:" h
rlAssertGrep "ABI Version:" h
# Try -l.
rlRun "$READELF -Wl virt > l"
rlAssertGrep "There are .* program headers, starting at offset" l
rlAssertGrep "Section to Segment mapping:" l
rlAssertGrep "[Requesting program interpreter: /lib*]" l
# Try -S.
rlRun "$READELF -WS virt > S"
rlAssertGrep "There are .* section headers, starting at offset" S
# I don't like rlAssertGrep.
rlRun "grep -E '\[[0-9]*\] \.(got|ctors|text|plt|init|symtab|bss|strtab|eh_*)' S"
# Try -s.
rlRun "$READELF -Ws virt > s"
rlAssertGrep "Symbol table '.symtab' contains .* entries:" s
rlRun "grep -E '[0-9]*\: [0-9a-f]*[\ \t]*[0-9]* (FUNC|OBJECT|NOTYPE)[\ \t]*(WEAK|GLOBAL)[\ \t]*(DEFAULT|HIDDEN)[\ \t]*([0-9]*|UND|ABS).*' s"
# Try -n.
rlRun "$READELF -Wn virt > n"
rlRun "grep -qE '[Nn]otes.*at.*offset .* with length .*:|Displaying notes found in: .note.ABI-tag' n"
# Try -r.
rlRun "$READELF -Wr virt > r"
rlRun "grep -E 'Relocation section .\.rela?.(dyn|plt). at offset 0x[0-9a-f]+ contains [0-9]+ entries\:' r"
# Try -d.
rlRun "$READELF -Wd virt > d"
rlAssertGrep "Dynamic section at offset .* contains .* entries:" d
rlRun "grep -E '0x[0-9a-f]+ \((JMPREL|STRSZ|INIT|NEEDED|VERSYM|RELA|DEBUG|SYMENT|GNU_HASH|STRTAB)\)[\ \t]*(Shared|0x|[0-9]*)' d"
# Try -I.
rlRun "$READELF -I virt > I"
# PPC64 produces no output (?).
if [ "$(rlGetPrimaryArch)" != "ppc64" ] && [ "$(rlGetPrimaryArch)" != "ppc64le" ]; then
rlAssertGrep "Histogram for .* bucket list length (total of .* buckets):" I
fi
# Try hex dump.
rlRun "$READELF -x .strtab virt > x"
rlAssertGrep "Hex dump of section '.strtab':" x
# Dump .debug_info.
rlRun "$READELF -wi virt > w"
rlAssertGrep "Compilation Unit @ offset .*:" w
rlAssertGrep "DW_AT_producer" w
rlAssertGrep "DW_AT_comp_dir" w
rlAssertGrep "DW_TAG_structure_type" w
rlRun "grep -E '<[0-9]+><[0-9a-f]+>\: Abbrev Number\: [0-9]+ \(DW_TAG_.*\)' w"
if ! rlIsRHEL 5; then
rlRun "grep -E '<[0-9]+>[\ \t]+DW_AT_.*\:' w"
fi
# Version info.
rlRun "$READELF -V virt > V"
rlAssertGrep "Version symbols section '.gnu.version' contains .* entries:" V
rlRun "grep -E '(0x)?[0-9a-f]*\: Version\:.*File\:.*Cnt\: [0-9]+' V"
# Try -h on /bin/true.
rlRun "$READELF -Wh /bin/true > H"
rlAssertGrep "ELF Header:" H
rlAssertGrep "7f 45 4c 46" H
if rlIsRHEL 8; then
rlAssertGrep "DYN (Shared object file)" H
else
rlAssertGrep "EXEC (Executable file)" H
fi
rlAssertGrep "Section header string table index:" H
rlAssertGrep "ABI Version:" H
# Try -l on /bin/true.
rlRun "$READELF -Wl /bin/true > L"
rlAssertGrep "There are .* program headers, starting at offset" L
rlAssertGrep "Section to Segment mapping:" L
rlAssertGrep "[Requesting program interpreter: /lib*]" L
# Try -S on /bin/true.
rlRun "$READELF -WS /bin/true > F"
rlAssertGrep "There are .* section headers, starting at offset" F
rlRun "grep -E '\[[0-9]*\] \.(got|ctors|text|plt|init|symtab|bss|strtab|eh_*)' F"
# Try -r on /bin/true.
rlRun "$READELF -Wr /bin/true > c"
rlRun "grep -E 'Relocation section .\.rela?.(dyn|plt). at offset 0x[0-9a-f]+ contains [0-9]+ entries\:' c"
rm -vf [HIwhnSLslcrxVdF]
rlPhaseEnd
rlPhaseStartTest "Test size."
rlRun "$SIZE --help"
rlRun "$SIZE -dB virt > s"
rlAssertGrep "text.*data.*bss.*dec.*hex.*filename" s
rlRun "$SIZE -dB /bin/ed > S"
rlAssertGrep "text.*data.*bss.*dec.*hex.*filename" S
rm -vf [Ss]
rlPhaseEnd
rlPhaseStartTest "Test strings."
rlRun "$STRINGS --help"
# Try on our binary.
rlRun "$STRINGS virt > s"
rlAssertGrep "__gmon_start__" s
rlAssertGrep "libc.so.6" s
rlAssertGrep "abort" s
rlAssertGrep "libm.so.6" s
# Try on system binary.
rlRun "$STRINGS /bin/echo > S"
rlAssertGrep "abort" S
rlAssertGrep "echo" S
rlAssertGrep "POSIXLY_CORRECT" S
rlAssertGrep "libc.so.6" S
rm -vf [Ss]
rlPhaseEnd
rlPhaseStartCleanup
rlRun "popd"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View File

@ -0,0 +1,31 @@
// PR c++/52746
// { dg-do run }
extern "C" int printf(const char*,...);
extern "C" void abort();
bool db;
struct A
{
virtual ~A() {}
};
struct B : public A
{
virtual ~B() { db = true; }
};
template<int> void test()
{
B * b = new B;
A * a = b;
a->~A();
::operator delete(b);
}
int main()
{
test<0>();
if (!db)
abort();
}