blob: 07f998cd4f4327a80f1e3afc6a944473f795ca56 [file] [log] [blame]
Roland McGrath3c84db32009-06-24 17:41:40 -07001/* Get CFA expression for frame.
Roland McGrath688f7fc2010-05-08 03:22:59 -07002 Copyright (C) 2009-2010 Red Hat, Inc.
Mark Wielaardde2ed972012-06-05 17:15:16 +02003 This file is part of elfutils.
Roland McGrath3c84db32009-06-24 17:41:40 -07004
Mark Wielaardde2ed972012-06-05 17:15:16 +02005 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
Roland McGrath3c84db32009-06-24 17:41:40 -07007
Mark Wielaardde2ed972012-06-05 17:15:16 +02008 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
11
12 or
13
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
17
18 or both in parallel, as here.
19
20 elfutils is distributed in the hope that it will be useful, but
Roland McGrath3c84db32009-06-24 17:41:40 -070021 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
Mark Wielaardde2ed972012-06-05 17:15:16 +020025 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
Roland McGrath3c84db32009-06-24 17:41:40 -070028
29#ifdef HAVE_CONFIG_H
30# include <config.h>
31#endif
32
33#include "cfi.h"
34#include <dwarf.h>
35#include <stdlib.h>
36
37int
Mark Wielaard1ccdfb62015-09-22 22:27:01 +020038dwarf_frame_cfa (Dwarf_Frame *fs, Dwarf_Op **ops, size_t *nops)
Roland McGrath3c84db32009-06-24 17:41:40 -070039{
40 /* Maybe there was a previous error. */
41 if (fs == NULL)
42 return -1;
43
Roland McGrathaf800142009-07-22 13:55:50 -070044 int result = 0;
Roland McGrath3c84db32009-06-24 17:41:40 -070045 switch (fs->cfa_rule)
46 {
47 case cfa_undefined:
48 *ops = NULL;
Roland McGrathaf800142009-07-22 13:55:50 -070049 *nops = 0;
50 break;
Roland McGrath3c84db32009-06-24 17:41:40 -070051
52 case cfa_offset:
53 /* The Dwarf_Op was already fully initialized by execute_cfi. */
54 *ops = &fs->cfa_data.offset;
Roland McGrathaf800142009-07-22 13:55:50 -070055 *nops = 1;
56 break;
Roland McGrath3c84db32009-06-24 17:41:40 -070057
58 case cfa_expr:
Roland McGrathaf800142009-07-22 13:55:50 -070059 /* Parse the expression into internal form. */
60 result = __libdw_intern_expression
61 (NULL, fs->cache->other_byte_order,
Roland McGrath688f7fc2010-05-08 03:22:59 -070062 fs->cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8, 4,
Roland McGrath0ab97832010-04-26 11:50:27 -070063 &fs->cache->expr_tree, &fs->cfa_data.expr, false, false,
Roland McGrathaf800142009-07-22 13:55:50 -070064 ops, nops, IDX_debug_frame);
65 break;
Roland McGrath3c84db32009-06-24 17:41:40 -070066
Roland McGrath3b10ac02010-04-26 18:45:36 -070067 case cfa_invalid:
68 __libdw_seterrno (DWARF_E_INVALID_CFI);
69 result = -1;
70 break;
71
Roland McGrath3c84db32009-06-24 17:41:40 -070072 default:
73 abort ();
74 }
75
Roland McGrathaf800142009-07-22 13:55:50 -070076 return result;
Roland McGrath3c84db32009-06-24 17:41:40 -070077}