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:
parent
8e50243c45
commit
22348da57d
63
tests/Sanity/dts-probe-binaries/Makefile
Normal file
63
tests/Sanity/dts-probe-binaries/Makefile
Normal 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)
|
3
tests/Sanity/dts-probe-binaries/PURPOSE
Normal file
3
tests/Sanity/dts-probe-binaries/PURPOSE
Normal 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>
|
298
tests/Sanity/dts-probe-binaries/check-localplt.c
Normal file
298
tests/Sanity/dts-probe-binaries/check-localplt.c
Normal 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
|
6
tests/Sanity/dts-probe-binaries/m.c
Normal file
6
tests/Sanity/dts-probe-binaries/m.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
int a (int), b (int), c (int);
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
return a (6) + b (4) - c (2);
|
||||||
|
}
|
20
tests/Sanity/dts-probe-binaries/main.fmf
Normal file
20
tests/Sanity/dts-probe-binaries/main.fmf
Normal 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
|
7
tests/Sanity/dts-probe-binaries/popcnt.c
Normal file
7
tests/Sanity/dts-probe-binaries/popcnt.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[] __attribute__((unused)))
|
||||||
|
{
|
||||||
|
printf ("%p\n", main);
|
||||||
|
return __builtin_popcount (argc);
|
||||||
|
}
|
418
tests/Sanity/dts-probe-binaries/runtest.sh
Executable file
418
tests/Sanity/dts-probe-binaries/runtest.sh
Executable 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
|
31
tests/Sanity/dts-probe-binaries/virtual2.C
Normal file
31
tests/Sanity/dts-probe-binaries/virtual2.C
Normal 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();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user