+2020-09-03 Mark Wielaard <mark@klomp.org>
+
+ * dwarf.h: Add DW_CFA_AARCH64_negate_ra_state.
+ * cfi.h (struct Dwarf_CFI_s): Add e_machine field.
+ * cfi.c (execute_cfi): Recognize, but ignore
+ DW_CFA_AARCH64_negate_ra_state on aarch64.
+ * dwarf_getcfi.c (dwarf_getcfi): Set cfi e_machine.
+ * dwarf_getcfi_elf.c (allocate_cfi): Take ehdr as argument and set
+ cfi e_machine.
+ (getcfi_gnu_eh_frame): Pass ehdr to allocate_cfi.
+ (getcfi_scn_eh_frame): Likewise.
+
2020-09-03 Mark Wielaard <mark@klomp.org>
* libdw.map (ELFUTILS_0.126): Remove local wildcard.
case DW_CFA_nop:
continue;
- case DW_CFA_GNU_window_save:
- /* This is magic shorthand used only by SPARC. It's equivalent
- to a bunch of DW_CFA_register and DW_CFA_offset operations. */
- if (unlikely (! enough_registers (31, &fs, &result)))
- goto out;
- for (regno = 8; regno < 16; ++regno)
+ case DW_CFA_GNU_window_save: /* DW_CFA_AARCH64_negate_ra_state */
+ if (cache->e_machine == EM_AARCH64)
{
- /* Find each %oN in %iN. */
- fs->regs[regno].rule = reg_register;
- fs->regs[regno].value = regno + 16;
+ /* Toggles the return address state, indicating whether
+ the return address is encrypted or not on
+ aarch64. XXX not handled yet. */
}
- unsigned int address_size = (cache->e_ident[EI_CLASS] == ELFCLASS32
- ? 4 : 8);
- for (; regno < 32; ++regno)
+ else
{
- /* Find %l0..%l7 and %i0..%i7 in a block at the CFA. */
- fs->regs[regno].rule = reg_offset;
- fs->regs[regno].value = (regno - 16) * address_size;
+ /* This is magic shorthand used only by SPARC. It's
+ equivalent to a bunch of DW_CFA_register and
+ DW_CFA_offset operations. */
+ if (unlikely (! enough_registers (31, &fs, &result)))
+ goto out;
+ for (regno = 8; regno < 16; ++regno)
+ {
+ /* Find each %oN in %iN. */
+ fs->regs[regno].rule = reg_register;
+ fs->regs[regno].value = regno + 16;
+ }
+ unsigned int address_size;
+ address_size = (cache->e_ident[EI_CLASS] == ELFCLASS32
+ ? 4 : 8);
+ for (; regno < 32; ++regno)
+ {
+ /* Find %l0..%l7 and %i0..%i7 in a block at the CFA. */
+ fs->regs[regno].rule = reg_offset;
+ fs->regs[regno].value = (regno - 16) * address_size;
+ }
}
continue;
size_t search_table_entries;
uint8_t search_table_encoding;
+ uint16_t e_machine;
+
/* True if the file has a byte order different from the host. */
bool other_byte_order;
DW_CFA_low_user = 0x1c,
DW_CFA_MIPS_advance_loc8 = 0x1d,
DW_CFA_GNU_window_save = 0x2d,
+ DW_CFA_AARCH64_negate_ra_state = 0x2d,
DW_CFA_GNU_args_size = 0x2e,
DW_CFA_GNU_negative_offset_extended = 0x2f,
DW_CFA_high_user = 0x3f
cfi->datarel = 0;
cfi->e_ident = (unsigned char *) elf_getident (dbg->elf, NULL);
+
+ GElf_Ehdr ehdr;
+ gelf_getehdr (dbg->elf, &ehdr);
+ cfi->e_machine = ehdr.e_machine;
+
cfi->other_byte_order = dbg->other_byte_order;
cfi->default_same_value = false;
static Dwarf_CFI *
-allocate_cfi (Elf *elf, GElf_Addr vaddr)
+allocate_cfi (Elf *elf, const GElf_Ehdr *ehdr, GElf_Addr vaddr)
{
Dwarf_CFI *cfi = calloc (1, sizeof *cfi);
if (cfi == NULL)
return NULL;
}
+ cfi->e_machine = ehdr->e_machine;
+
if ((BYTE_ORDER == LITTLE_ENDIAN && cfi->e_ident[EI_DATA] == ELFDATA2MSB)
|| (BYTE_ORDER == BIG_ENDIAN && cfi->e_ident[EI_DATA] == ELFDATA2LSB))
cfi->other_byte_order = true;
__libdw_seterrno (DWARF_E_INVALID_ELF); /* XXX might be read error */
return NULL;
}
- Dwarf_CFI *cfi = allocate_cfi (elf, eh_frame_ptr);
+ Dwarf_CFI *cfi = allocate_cfi (elf, ehdr, eh_frame_ptr);
if (cfi != NULL)
{
cfi->data = (Elf_Data_Scn *) data;
__libdw_seterrno (DWARF_E_INVALID_ELF);
return NULL;
}
- Dwarf_CFI *cfi = allocate_cfi (elf, shdr->sh_addr);
+ Dwarf_CFI *cfi = allocate_cfi (elf, ehdr, shdr->sh_addr);
if (cfi != NULL)
{
cfi->data = (Elf_Data_Scn *) data;
+2020-09-03 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (print_cfa_program): Take ehdr as argument. Use it to
+ recognize DW_CFA_AARCH64_negate_ra_state.
+ (print_debug_frame_section): Pass ehdr to print_cfa_program.
+ (print_debug): Don't warn if we dump frames, but cannot get dbg.
+
2020-09-01 Mark Wielaard <mark@klomp.org>
* readelf.c (print_debug_ranges_section): Base address entry can
int data_align,
unsigned int version, unsigned int ptr_size,
unsigned int encoding,
- Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
+ Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, Dwarf *dbg)
{
char regnamebuf[REGNAMESZ];
const char *regname (unsigned int regno)
printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
op1, pc += op1 * code_align);
break;
- case DW_CFA_GNU_window_save:
- puts (" GNU_window_save");
+ case DW_CFA_GNU_window_save: /* DW_CFA_AARCH64_negate_ra_state */
+ if (ehdr->e_machine == EM_AARCH64)
+ puts (" AARCH64_negate_ra_state");
+ else
+ puts (" GNU_window_save");
break;
case DW_CFA_GNU_args_size:
if ((uint64_t) (endp - readp) < 1)
else
print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
data_alignment_factor, version, ptr_size,
- fde_encoding, dwflmod, ebl, dbg);
+ fde_encoding, dwflmod, ebl, ehdr, dbg);
readp = cieend;
}
}
};
if (dbg == NULL)
{
- if ((print_debug_sections & ~section_exception) != 0)
+ if ((print_debug_sections & ~(section_exception|section_frame)) != 0)
error (0, 0, gettext ("cannot get debug context descriptor: %s"),
dwfl_errmsg (-1));
dbg = &dummy_dbg;
+2020-09-03 Mark Wielaard <mark@klomp.org>
+
+ * run-readelf-frames.sh: New test.
+ * Makefile.am (TESTS): Add run-readelf-frames.sh.
+ (EXTRA_DIST): Likewise.
+
2020-09-03 Mark Wielaard <mark@klomp.org>
* testfile-gnu-property-note-aarch64.bz2: New file.
run-readelf-test4.sh run-readelf-twofiles.sh \
run-readelf-macro.sh run-readelf-loc.sh run-readelf-ranges.sh \
run-readelf-aranges.sh run-readelf-line.sh run-readelf-z.sh \
+ run-readelf-frames.sh \
run-readelf-n.sh \
run-native-test.sh run-bug1-test.sh \
run-debuglink.sh run-debugaltlink.sh run-buildid.sh \
testfile-dwzstr.bz2 testfile-dwzstr.multi.bz2 \
run-readelf-addr.sh run-readelf-str.sh \
run-readelf-types.sh \
+ run-readelf-frames.sh \
run-readelf-n.sh \
testfile-gnu-property-note.bz2 testfile-gnu-property-note.o.bz2 \
testfile_gnu_props.32le.o.bz2 \
--- /dev/null
+#! /bin/sh
+# Copyright (C) 2020 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
+
+# See run-readelf-n.sh
+testfiles testfile-gnu-property-note-aarch64
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=frames testfile-gnu-property-note-aarch64 <<\EOF
+
+Call frame search table section [17] '.eh_frame_hdr':
+ version: 1
+ eh_frame_ptr_enc: 0x1b (sdata4 pcrel)
+ fde_count_enc: 0x3 (udata4)
+ table_enc: 0x3b (sdata4 datarel)
+ eh_frame_ptr: 0x44 (offset: 0x758)
+ fde_count: 7
+ Table:
+ 0xfffffe70 (offset: 0x580) -> 0x5c fde=[ 14]
+ 0xfffffea0 (offset: 0x5b0) -> 0x70 fde=[ 28]
+ 0xfffffee0 (offset: 0x5f0) -> 0x84 fde=[ 3c]
+ 0xffffff20 (offset: 0x630) -> 0xac fde=[ 64]
+ 0xffffff28 (offset: 0x638) -> 0xc0 fde=[ 78]
+ 0xffffff40 (offset: 0x650) -> 0xd8 fde=[ 90]
+ 0xffffffc0 (offset: 0x6d0) -> 0x110 fde=[ c8]
+
+Call frame information section [18] '.eh_frame' at offset 0x758:
+
+ [ 0] CIE length=16
+ CIE_id: 0
+ version: 1
+ augmentation: "zR"
+ code_alignment_factor: 4
+ data_alignment_factor: -8
+ return_address_register: 30
+ Augmentation data: 0x1b (FDE address encoding: sdata4 pcrel)
+
+ Program:
+ def_cfa r31 (sp) at offset 0
+
+ [ 14] FDE length=16 cie=[ 0]
+ CIE_pointer: 24
+ initial_location: 0x0000000000400580 (offset: 0x580)
+ address_range: 0x30 (end offset: 0x5b0)
+
+ Program:
+ nop
+ nop
+ nop
+
+ [ 28] FDE length=16 cie=[ 0]
+ CIE_pointer: 44
+ initial_location: 0x00000000004005b0 (offset: 0x5b0)
+ address_range: 0x3c (end offset: 0x5ec)
+
+ Program:
+ nop
+ nop
+ nop
+
+ [ 3c] FDE length=36 cie=[ 0]
+ CIE_pointer: 64
+ initial_location: 0x00000000004005f0 (offset: 0x5f0)
+ address_range: 0x38 (end offset: 0x628)
+
+ Program:
+ advance_loc 1 to 0x5f4
+ AARCH64_negate_ra_state
+ advance_loc 1 to 0x5f8
+ def_cfa_offset 32
+ offset r29 (x29) at cfa-32
+ offset r30 (x30) at cfa-24
+ advance_loc 2 to 0x600
+ offset r19 (x19) at cfa-16
+ advance_loc 8 to 0x620
+ restore r30 (x30)
+ restore r29 (x29)
+ restore r19 (x19)
+ def_cfa_offset 0
+ advance_loc 1 to 0x624
+ AARCH64_negate_ra_state
+ nop
+ nop
+ nop
+
+ [ 64] FDE length=16 cie=[ 0]
+ CIE_pointer: 104
+ initial_location: 0x0000000000400630 (offset: 0x630)
+ address_range: 0x8 (end offset: 0x638)
+
+ Program:
+ nop
+ nop
+ nop
+
+ [ 78] FDE length=20 cie=[ 0]
+ CIE_pointer: 124
+ initial_location: 0x0000000000400638 (offset: 0x638)
+ address_range: 0xc (end offset: 0x644)
+
+ Program:
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ [ 90] FDE length=52 cie=[ 0]
+ CIE_pointer: 148
+ initial_location: 0x0000000000400650 (offset: 0x650)
+ address_range: 0x80 (end offset: 0x6d0)
+
+ Program:
+ advance_loc 1 to 0x654
+ AARCH64_negate_ra_state
+ advance_loc 1 to 0x658
+ def_cfa_offset 64
+ offset r29 (x29) at cfa-64
+ offset r30 (x30) at cfa-56
+ advance_loc 2 to 0x660
+ offset r19 (x19) at cfa-48
+ offset r20 (x20) at cfa-40
+ advance_loc 3 to 0x66c
+ offset r21 (x21) at cfa-32
+ offset r22 (x22) at cfa-24
+ advance_loc 5 to 0x680
+ offset r23 (x23) at cfa-16
+ offset r24 (x24) at cfa-8
+ advance_loc 18 to 0x6c8
+ restore r30 (x30)
+ restore r29 (x29)
+ restore r23 (x23)
+ restore r24 (x24)
+ restore r21 (x21)
+ restore r22 (x22)
+ restore r19 (x19)
+ restore r20 (x20)
+ def_cfa_offset 0
+ advance_loc 1 to 0x6cc
+ AARCH64_negate_ra_state
+ nop
+ nop
+
+ [ c8] FDE length=16 cie=[ 0]
+ CIE_pointer: 204
+ initial_location: 0x00000000004006d0 (offset: 0x6d0)
+ address_range: 0x8 (end offset: 0x6d8)
+
+ Program:
+ nop
+ nop
+ nop
+
+ [ dc] Zero terminator
+EOF
+
+exit 0