summaryrefslogtreecommitdiffstats
path: root/libdw/cfi.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2013-10-06 17:04:07 +0200
committerMark Wielaard <[email protected]>2013-10-07 11:16:27 +0200
commit3dec3e110bb2a2453156868e1221dc8192399e3e (patch)
tree65eb424f42bfd80f2bcc2b6a8d1a6d96df5e475a /libdw/cfi.c
parent5dbbc5e32cc1fb3a7cf33e52e0bfc6f47097f3fe (diff)
backends: ppc_abi_cfi reg1 use DW_CFA_val_offset not DW_CFA_val_expression.
Register rules using expressions are stored using an offset from the start of the .eh_frame or .debug_frame ELF section data. Since abi_cfi rules aren't stored in those ELF sections they should use neither DW_CFA_expression nor DW_CFA_val_expression. The only backend that used DW_CFA_val_expression was ppc_cfi.c. It was easier to express the same rule using DW_CFA_val_offset than to change the code to handle register rules using expressions. On most architectures this did work by accident. See the definition of struct dwarf_frame_register value in libdw/cfi.h to see why. But on ia64 the abi_cfi data and actual frame data were placed too far apart and caused a crash in tests/run-addrcfi.sh for ppc32. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libdw/cfi.c')
-rw-r--r--libdw/cfi.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/libdw/cfi.c b/libdw/cfi.c
index b1e8d485..a146f129 100644
--- a/libdw/cfi.c
+++ b/libdw/cfi.c
@@ -252,6 +252,8 @@ execute_cfi (Dwarf_CFI *cache,
continue;
case DW_CFA_expression:
+ /* Expression rule relies on section data, abi_cfi cannot use it. */
+ assert (! abi_cfi);
get_uleb128 (regno, program);
offset = program - (const uint8_t *) cache->data->d.d_buf;
/* DW_FORM_block is a ULEB128 length followed by that many bytes. */
@@ -262,6 +264,8 @@ execute_cfi (Dwarf_CFI *cache,
continue;
case DW_CFA_val_expression:
+ /* Expression rule relies on section data, abi_cfi cannot use it. */
+ assert (! abi_cfi);
get_uleb128 (regno, program);
/* DW_FORM_block is a ULEB128 length followed by that many bytes. */
offset = program - (const uint8_t *) cache->data->d.d_buf;