mirror of
https://github.com/openharmony/third_party_elfutils.git
synced 2026-07-01 06:41:51 -04:00
libdw: Allow .debug_frame only Dwarf.
.debug_frame is useful independent from the other .debug sections. Add a simplified variant of the addrcfi testcase dwarfcfi. dwarfcfi only uses dwarf_frame calls and no dwfl helpers. Signed-off-by: Mark Wielaard <mark@klomp.org>
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
2018-06-27 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
* dwarf_begin_elf.c (check_section): Allow a single .debug_frame
|
||||
section.
|
||||
|
||||
2018-06-26 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
* libdw.h (dwarf_getscn_info): Remove.
|
||||
|
||||
@@ -209,7 +209,8 @@ valid_p (Dwarf *result)
|
||||
Require at least one section that can be read "standalone". */
|
||||
if (likely (result != NULL)
|
||||
&& unlikely (result->sectiondata[IDX_debug_info] == NULL
|
||||
&& result->sectiondata[IDX_debug_line] == NULL))
|
||||
&& result->sectiondata[IDX_debug_line] == NULL
|
||||
&& result->sectiondata[IDX_debug_frame] == NULL))
|
||||
{
|
||||
Dwarf_Sig8_Hash_free (&result->sig8_hash);
|
||||
__libdw_seterrno (DWARF_E_NO_DWARF);
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
2018-06-27 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
* dwarf_cfi.c: New file.
|
||||
* run-dwarfcfi.sh: New test.
|
||||
* testfile11-debugframe.bz2: New testfile.
|
||||
* testfile12-debugframe.bz2: Likewise.
|
||||
* testfileaarch64-debugframe.bz2: Likewise.
|
||||
* testfilearm-debugframe.bz2: Likewise.
|
||||
* testfileppc32-debugframe.bz2: Likewise.
|
||||
* testfileppc64-debugframe.bz2: Likewise.
|
||||
* Makefile.am (check_PROGRAMS): Add dwarfcfi.
|
||||
(TESTS): Add run-dwarfcfi.sh.
|
||||
(EXTRA_DIST): Add run-dwarfcfi.sh, testfile11-debugframe.bz2,
|
||||
testfile12-debugframe.bz2, testfileaarch64-debugframe.bz2,
|
||||
testfilearm-debugframe.bz2, testfileppc32-debugframe.bz2 and
|
||||
testfileppc64-debugframe.bz2.
|
||||
|
||||
2018-06-23 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
* varlocs.c (print_expr): Take a new depth argument. Check it isn't
|
||||
|
||||
+7
-1
@@ -46,6 +46,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
|
||||
dwfl-bug-addr-overflow arls dwfl-bug-fd-leak \
|
||||
dwfl-addr-sect dwfl-bug-report early-offscn \
|
||||
dwfl-bug-getmodules dwarf-getmacros dwarf-ranges addrcfi \
|
||||
dwarfcfi \
|
||||
test-flag-nobits dwarf-getstring rerequest_tag \
|
||||
alldts typeiter typeiter2 low_high_pc \
|
||||
test-elf_cntl_gelf_getshdr dwflsyms dwfllines \
|
||||
@@ -95,6 +96,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \
|
||||
run-ranlib-test2.sh run-ranlib-test3.sh run-ranlib-test4.sh \
|
||||
run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \
|
||||
run-find-prologues.sh run-allregs.sh run-addrcfi.sh \
|
||||
run-dwarfcfi.sh \
|
||||
run-nm-self.sh run-readelf-self.sh run-readelf-info-plus.sh \
|
||||
run-readelf-const-values.sh \
|
||||
run-varlocs-self.sh run-exprlocs-self.sh \
|
||||
@@ -205,7 +207,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
|
||||
run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \
|
||||
run-nm-self.sh run-readelf-self.sh run-readelf-info-plus.sh \
|
||||
run-readelf-const-values.sh testfile-const-values.debug.bz2 \
|
||||
run-addrcfi.sh \
|
||||
run-addrcfi.sh run-dwarfcfi.sh \
|
||||
testfile11-debugframe.bz2 testfile12-debugframe.bz2 \
|
||||
testfileaarch64-debugframe.bz2 testfilearm-debugframe.bz2 \
|
||||
testfileppc32-debugframe.bz2 testfileppc64-debugframe.bz2 \
|
||||
run-varlocs-self.sh run-exprlocs-self.sh \
|
||||
run-find-prologues.sh run-allregs.sh run-native-test.sh \
|
||||
run-addrname-test.sh run-dwfl-bug-offline-rel.sh \
|
||||
@@ -506,6 +511,7 @@ dwarf_getmacros_LDADD = $(libdw)
|
||||
dwarf_ranges_LDADD = $(libdw)
|
||||
dwarf_getstring_LDADD = $(libdw)
|
||||
addrcfi_LDADD = $(libdw) $(libebl) $(libelf) $(argp_LDADD) -ldl
|
||||
dwarfcfi_LDADD = $(libdw) $(libelf)
|
||||
test_flag_nobits_LDADD = $(libelf)
|
||||
rerequest_tag_LDADD = $(libdw)
|
||||
alldts_LDADD = $(libdw) $(libelf)
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/* Test program for DWARF (.debug_frame) CFI handling.
|
||||
Copyright (C) 2009-2010, 2013, 2015, 2018 Red Hat, Inc.
|
||||
This file is part of elfutils.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
elfutils 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, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <error.h>
|
||||
#include ELFUTILS_HEADER(dw)
|
||||
#include <dwarf.h>
|
||||
#include <argp.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../libdw/known-dwarf.h"
|
||||
|
||||
static const char *
|
||||
op_name (unsigned int code)
|
||||
{
|
||||
static const char *const known[] =
|
||||
{
|
||||
#define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
|
||||
DWARF_ALL_KNOWN_DW_OP
|
||||
#undef DWARF_ONE_KNOWN_DW_OP
|
||||
};
|
||||
|
||||
if (likely (code < sizeof (known) / sizeof (known[0])))
|
||||
return known[code];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
print_detail (int result, const Dwarf_Op *ops, size_t nops)
|
||||
{
|
||||
if (result < 0)
|
||||
printf ("indeterminate (%s)\n", dwarf_errmsg (-1));
|
||||
else if (nops == 0)
|
||||
printf ("%s\n", ops == NULL ? "same_value" : "undefined");
|
||||
else
|
||||
{
|
||||
printf ("%s expression:", result == 0 ? "location" : "value");
|
||||
for (size_t i = 0; i < nops; ++i)
|
||||
{
|
||||
printf (" %s", op_name(ops[i].atom));
|
||||
if (ops[i].number2 == 0)
|
||||
{
|
||||
if (ops[i].atom == DW_OP_addr)
|
||||
printf ("(%#" PRIx64 ")", ops[i].number);
|
||||
else if (ops[i].number != 0)
|
||||
printf ("(%" PRId64 ")", ops[i].number);
|
||||
}
|
||||
else
|
||||
printf ("(%" PRId64 ",%" PRId64 ")",
|
||||
ops[i].number, ops[i].number2);
|
||||
}
|
||||
puts ("");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
handle_address (Dwarf_CFI *cfi, GElf_Addr pc)
|
||||
{
|
||||
Dwarf_Frame *frame;
|
||||
int result = dwarf_cfi_addrframe (cfi, pc, &frame);
|
||||
if (result != 0)
|
||||
{
|
||||
printf ("dwarf_cfi_addrframe: %s\n", dwarf_errmsg (-1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
Dwarf_Addr start = pc;
|
||||
Dwarf_Addr end = pc;
|
||||
bool signalp;
|
||||
int ra_regno = dwarf_frame_info (frame, &start, &end, &signalp);
|
||||
|
||||
printf ("%#" PRIx64 " => [%#" PRIx64 ", %#" PRIx64 "):\n",
|
||||
pc, start, end);
|
||||
|
||||
if (ra_regno < 0)
|
||||
printf ("\treturn address register unavailable (%s)\n",
|
||||
dwarf_errmsg (-1));
|
||||
else
|
||||
printf ("\treturn address in reg%u%s\n",
|
||||
ra_regno, signalp ? " (signal frame)" : "");
|
||||
|
||||
// Point cfa_ops to dummy to match print_detail expectations.
|
||||
// (nops == 0 && cfa_ops != NULL => "undefined")
|
||||
Dwarf_Op dummy;
|
||||
Dwarf_Op *cfa_ops = &dummy;
|
||||
size_t cfa_nops;
|
||||
result = dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops);
|
||||
|
||||
printf ("\tCFA ");
|
||||
print_detail (result, cfa_ops, cfa_nops);
|
||||
|
||||
// Print the location of the first 10 (DWARF nr) registers
|
||||
for (int r = 0; r < 10; r++)
|
||||
{
|
||||
Dwarf_Op ops_mem[3];
|
||||
Dwarf_Op *ops;
|
||||
size_t nops;
|
||||
printf ("\treg%d: ", r);
|
||||
int reg_result = dwarf_frame_register (frame, r, ops_mem, &ops, &nops);
|
||||
print_detail (reg_result, ops, nops);
|
||||
result |= reg_result;
|
||||
}
|
||||
|
||||
free (frame);
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
if (argc <= 2)
|
||||
error (EXIT_FAILURE, 0, "need file name argument and addresses");
|
||||
|
||||
int fd = open (argv[1], O_RDONLY);
|
||||
if (fd == -1)
|
||||
error (EXIT_FAILURE, errno, "cannot open input file `%s'", argv[1]);
|
||||
|
||||
elf_version (EV_CURRENT);
|
||||
|
||||
Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
|
||||
if (elf == NULL)
|
||||
error (EXIT_FAILURE, 0, "cannot create ELF descriptor: %s",
|
||||
elf_errmsg (-1));
|
||||
|
||||
Dwarf *dwarf = dwarf_begin_elf (elf, DWARF_C_READ, NULL);
|
||||
if (dwarf == NULL)
|
||||
error (EXIT_FAILURE, 0, "cannot create DWARF descriptor: %s",
|
||||
dwarf_errmsg (-1));
|
||||
|
||||
Dwarf_CFI *cfi = dwarf_getcfi (dwarf);
|
||||
if (cfi == NULL)
|
||||
error (EXIT_FAILURE, 0, "cannot get DWARF CFI from .dwarf_frame: %s",
|
||||
dwarf_errmsg (-1));
|
||||
|
||||
int result = 0;
|
||||
int args = 2;
|
||||
do
|
||||
{
|
||||
char *endp;
|
||||
uintmax_t addr = strtoumax (argv[args], &endp, 0);
|
||||
if (endp != argv[args])
|
||||
result |= handle_address (cfi, addr);
|
||||
else
|
||||
result = 1;
|
||||
}
|
||||
while (args++ < argc - 1);
|
||||
|
||||
dwarf_end (dwarf);
|
||||
elf_end (elf);
|
||||
|
||||
return result;
|
||||
}
|
||||
Executable
+133
@@ -0,0 +1,133 @@
|
||||
#! /bin/sh
|
||||
# Test for dwarf_getcfi.
|
||||
# Copyright (C) 2018 Red Hat, Inc.
|
||||
# This file is part of elfutils.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# elfutils 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. $srcdir/test-subr.sh
|
||||
|
||||
# Test files come from run-addrcfi with all sections stripped except
|
||||
# the .debug_frame.
|
||||
# for i in <testfiles>
|
||||
# eu-strip -f $i-debugframe $i
|
||||
# eu-strip -g --remove-comment --keep-section=.debug_frame $i-debugframe
|
||||
# done
|
||||
testfiles testfile11-debugframe testfile12-debugframe
|
||||
testfiles testfileaarch64-debugframe
|
||||
testfiles testfilearm-debugframe
|
||||
testfiles testfileppc32-debugframe
|
||||
testfiles testfileppc64-debugframe
|
||||
|
||||
testfiles testfile11-debugframe
|
||||
testrun_compare ${abs_builddir}/dwarfcfi testfile11-debugframe 0x080489b8 <<\EOF
|
||||
0x80489b8 => [0x80489b8, 0x80489b9):
|
||||
return address in reg8
|
||||
CFA location expression: bregx(4,4)
|
||||
reg0: undefined
|
||||
reg1: undefined
|
||||
reg2: undefined
|
||||
reg3: same_value
|
||||
reg4: location expression: call_frame_cfa stack_value
|
||||
reg5: same_value
|
||||
reg6: same_value
|
||||
reg7: same_value
|
||||
reg8: location expression: call_frame_cfa plus_uconst(-4)
|
||||
reg9: undefined
|
||||
EOF
|
||||
|
||||
testfiles testfile12-debugframe
|
||||
testrun_compare ${abs_builddir}/dwarfcfi testfile12-debugframe 0x00000000000009d0 <<\EOF
|
||||
0x9d0 => [0x9d0, 0x9d1):
|
||||
return address in reg16
|
||||
CFA location expression: bregx(7,8)
|
||||
reg0: same_value
|
||||
reg1: undefined
|
||||
reg2: undefined
|
||||
reg3: undefined
|
||||
reg4: undefined
|
||||
reg5: undefined
|
||||
reg6: same_value
|
||||
reg7: location expression: call_frame_cfa stack_value
|
||||
reg8: undefined
|
||||
reg9: undefined
|
||||
EOF
|
||||
|
||||
testfiles testfileppc32-debugframe
|
||||
testrun_compare ${abs_builddir}/dwarfcfi testfileppc32-debugframe 0x100004c0 <<\EOF
|
||||
0x100004c0 => [0x100004c0, 0x100004d0):
|
||||
return address in reg65
|
||||
CFA location expression: bregx(1)
|
||||
reg0: undefined
|
||||
reg1: location expression: call_frame_cfa stack_value
|
||||
reg2: same_value
|
||||
reg3: undefined
|
||||
reg4: undefined
|
||||
reg5: undefined
|
||||
reg6: undefined
|
||||
reg7: undefined
|
||||
reg8: undefined
|
||||
reg9: undefined
|
||||
EOF
|
||||
|
||||
testfiles testfileppc64-debugframe
|
||||
testrun_compare ${abs_builddir}/dwarfcfi testfileppc64-debugframe 0x00000000100005b0 <<\EOF
|
||||
0x100005b0 => [0x100005b0, 0x100005d0):
|
||||
return address in reg65
|
||||
CFA location expression: bregx(1)
|
||||
reg0: undefined
|
||||
reg1: location expression: call_frame_cfa stack_value
|
||||
reg2: same_value
|
||||
reg3: undefined
|
||||
reg4: undefined
|
||||
reg5: undefined
|
||||
reg6: undefined
|
||||
reg7: undefined
|
||||
reg8: undefined
|
||||
reg9: undefined
|
||||
EOF
|
||||
|
||||
testfiles testfilearm-debugframe
|
||||
testrun_compare ${abs_builddir}/dwarfcfi testfilearm-debugframe 0x00008510 <<\EOF
|
||||
0x8510 => [0x8510, 0x8524):
|
||||
return address in reg14
|
||||
CFA location expression: bregx(13)
|
||||
reg0: undefined
|
||||
reg1: undefined
|
||||
reg2: undefined
|
||||
reg3: undefined
|
||||
reg4: same_value
|
||||
reg5: same_value
|
||||
reg6: same_value
|
||||
reg7: same_value
|
||||
reg8: same_value
|
||||
reg9: undefined
|
||||
EOF
|
||||
|
||||
testfiles testfileaarch64-debugframe
|
||||
testrun_compare ${abs_builddir}/dwarfcfi testfileaarch64-debugframe 0x400550 <<\EOF
|
||||
0x400550 => [0x400550, 0x400568):
|
||||
return address in reg30
|
||||
CFA location expression: bregx(31)
|
||||
reg0: undefined
|
||||
reg1: undefined
|
||||
reg2: undefined
|
||||
reg3: undefined
|
||||
reg4: undefined
|
||||
reg5: undefined
|
||||
reg6: undefined
|
||||
reg7: undefined
|
||||
reg8: undefined
|
||||
reg9: undefined
|
||||
EOF
|
||||
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Reference in New Issue
Block a user