1*5ac3bc71Schristos /* $NetBSD: dwarf_frame.c,v 1.5 2024/03/03 17:37:31 christos Exp $ */
2e81373b4Schristos
39dd9d0cfSchristos /*-
49dd9d0cfSchristos * Copyright (c) 2009,2011 Kai Wang
59dd9d0cfSchristos * All rights reserved.
69dd9d0cfSchristos *
79dd9d0cfSchristos * Redistribution and use in source and binary forms, with or without
89dd9d0cfSchristos * modification, are permitted provided that the following conditions
99dd9d0cfSchristos * are met:
109dd9d0cfSchristos * 1. Redistributions of source code must retain the above copyright
119dd9d0cfSchristos * notice, this list of conditions and the following disclaimer.
129dd9d0cfSchristos * 2. Redistributions in binary form must reproduce the above copyright
139dd9d0cfSchristos * notice, this list of conditions and the following disclaimer in the
149dd9d0cfSchristos * documentation and/or other materials provided with the distribution.
159dd9d0cfSchristos *
169dd9d0cfSchristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
179dd9d0cfSchristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
189dd9d0cfSchristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
199dd9d0cfSchristos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
209dd9d0cfSchristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
219dd9d0cfSchristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
229dd9d0cfSchristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
239dd9d0cfSchristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
249dd9d0cfSchristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
259dd9d0cfSchristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
269dd9d0cfSchristos * SUCH DAMAGE.
279dd9d0cfSchristos */
289dd9d0cfSchristos
299dd9d0cfSchristos #include "_libdwarf.h"
309dd9d0cfSchristos
31*5ac3bc71Schristos __RCSID("$NetBSD: dwarf_frame.c,v 1.5 2024/03/03 17:37:31 christos Exp $");
3242bd3019Schristos ELFTC_VCSID("Id: dwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27");
339dd9d0cfSchristos
349dd9d0cfSchristos int
dwarf_get_fde_list(Dwarf_Debug dbg,Dwarf_Cie ** cie_list,Dwarf_Signed * cie_count,Dwarf_Fde ** fde_list,Dwarf_Signed * fde_count,Dwarf_Error * error)359dd9d0cfSchristos dwarf_get_fde_list(Dwarf_Debug dbg, Dwarf_Cie **cie_list,
369dd9d0cfSchristos Dwarf_Signed *cie_count, Dwarf_Fde **fde_list, Dwarf_Signed *fde_count,
379dd9d0cfSchristos Dwarf_Error *error)
389dd9d0cfSchristos {
399dd9d0cfSchristos
409dd9d0cfSchristos if (dbg == NULL || cie_list == NULL || cie_count == NULL ||
419dd9d0cfSchristos fde_list == NULL || fde_count == NULL) {
429dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
439dd9d0cfSchristos return (DW_DLV_ERROR);
449dd9d0cfSchristos }
459dd9d0cfSchristos
469dd9d0cfSchristos if (dbg->dbg_internal_reg_table == NULL) {
479dd9d0cfSchristos if (_dwarf_frame_interal_table_init(dbg, error) != DW_DLE_NONE)
489dd9d0cfSchristos return (DW_DLV_ERROR);
499dd9d0cfSchristos }
509dd9d0cfSchristos
519dd9d0cfSchristos if (dbg->dbg_frame == NULL) {
529dd9d0cfSchristos if (_dwarf_frame_section_load(dbg, error) != DW_DLE_NONE)
539dd9d0cfSchristos return (DW_DLV_ERROR);
549dd9d0cfSchristos if (dbg->dbg_frame == NULL) {
559dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
569dd9d0cfSchristos return (DW_DLV_NO_ENTRY);
579dd9d0cfSchristos }
589dd9d0cfSchristos }
599dd9d0cfSchristos
609dd9d0cfSchristos if (dbg->dbg_frame->fs_ciearray == NULL ||
619dd9d0cfSchristos dbg->dbg_frame->fs_fdearray == NULL) {
629dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
639dd9d0cfSchristos return (DW_DLV_NO_ENTRY);
649dd9d0cfSchristos }
659dd9d0cfSchristos
669dd9d0cfSchristos *cie_list = dbg->dbg_frame->fs_ciearray;
679dd9d0cfSchristos *cie_count = dbg->dbg_frame->fs_cielen;
689dd9d0cfSchristos *fde_list = dbg->dbg_frame->fs_fdearray;
699dd9d0cfSchristos *fde_count = dbg->dbg_frame->fs_fdelen;
709dd9d0cfSchristos
719dd9d0cfSchristos return (DW_DLV_OK);
729dd9d0cfSchristos }
739dd9d0cfSchristos
749dd9d0cfSchristos int
dwarf_get_fde_list_eh(Dwarf_Debug dbg,Dwarf_Cie ** cie_list,Dwarf_Signed * cie_count,Dwarf_Fde ** fde_list,Dwarf_Signed * fde_count,Dwarf_Error * error)759dd9d0cfSchristos dwarf_get_fde_list_eh(Dwarf_Debug dbg, Dwarf_Cie **cie_list,
769dd9d0cfSchristos Dwarf_Signed *cie_count, Dwarf_Fde **fde_list, Dwarf_Signed *fde_count,
779dd9d0cfSchristos Dwarf_Error *error)
789dd9d0cfSchristos {
799dd9d0cfSchristos
809dd9d0cfSchristos if (dbg == NULL || cie_list == NULL || cie_count == NULL ||
819dd9d0cfSchristos fde_list == NULL || fde_count == NULL) {
829dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
839dd9d0cfSchristos return (DW_DLV_ERROR);
849dd9d0cfSchristos }
859dd9d0cfSchristos
869dd9d0cfSchristos if (dbg->dbg_internal_reg_table == NULL) {
879dd9d0cfSchristos if (_dwarf_frame_interal_table_init(dbg, error) != DW_DLE_NONE)
889dd9d0cfSchristos return (DW_DLV_ERROR);
899dd9d0cfSchristos }
909dd9d0cfSchristos
919dd9d0cfSchristos if (dbg->dbg_eh_frame == NULL) {
929dd9d0cfSchristos if (_dwarf_frame_section_load_eh(dbg, error) != DW_DLE_NONE)
939dd9d0cfSchristos return (DW_DLV_ERROR);
949dd9d0cfSchristos if (dbg->dbg_eh_frame == NULL) {
959dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
969dd9d0cfSchristos return (DW_DLV_NO_ENTRY);
979dd9d0cfSchristos }
989dd9d0cfSchristos }
999dd9d0cfSchristos
1009dd9d0cfSchristos if (dbg->dbg_eh_frame->fs_ciearray == NULL ||
1019dd9d0cfSchristos dbg->dbg_eh_frame->fs_fdearray == NULL) {
1029dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
1039dd9d0cfSchristos return (DW_DLV_NO_ENTRY);
1049dd9d0cfSchristos }
1059dd9d0cfSchristos
1069dd9d0cfSchristos *cie_list = dbg->dbg_eh_frame->fs_ciearray;
1079dd9d0cfSchristos *cie_count = dbg->dbg_eh_frame->fs_cielen;
1089dd9d0cfSchristos *fde_list = dbg->dbg_eh_frame->fs_fdearray;
1099dd9d0cfSchristos *fde_count = dbg->dbg_eh_frame->fs_fdelen;
1109dd9d0cfSchristos
1119dd9d0cfSchristos return (DW_DLV_OK);
1129dd9d0cfSchristos }
1139dd9d0cfSchristos
1149dd9d0cfSchristos int
dwarf_get_fde_n(Dwarf_Fde * fdelist,Dwarf_Unsigned fde_index,Dwarf_Fde * ret_fde,Dwarf_Error * error)1159dd9d0cfSchristos dwarf_get_fde_n(Dwarf_Fde *fdelist, Dwarf_Unsigned fde_index,
1169dd9d0cfSchristos Dwarf_Fde *ret_fde, Dwarf_Error *error)
1179dd9d0cfSchristos {
1189dd9d0cfSchristos Dwarf_FrameSec fs;
1199dd9d0cfSchristos Dwarf_Debug dbg;
1209dd9d0cfSchristos
1219dd9d0cfSchristos dbg = fdelist != NULL ? (*fdelist)->fde_dbg : NULL;
1229dd9d0cfSchristos
1239dd9d0cfSchristos if (fdelist == NULL || ret_fde == NULL) {
1249dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
1259dd9d0cfSchristos return (DW_DLV_ERROR);
1269dd9d0cfSchristos }
1279dd9d0cfSchristos
1289dd9d0cfSchristos fs = fdelist[0]->fde_fs;
1299dd9d0cfSchristos assert(fs != NULL);
1309dd9d0cfSchristos
1319dd9d0cfSchristos if (fde_index >= fs->fs_fdelen) {
1329dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
1339dd9d0cfSchristos return (DW_DLV_NO_ENTRY);
1349dd9d0cfSchristos }
1359dd9d0cfSchristos
1369dd9d0cfSchristos *ret_fde = fdelist[fde_index];
1379dd9d0cfSchristos
1389dd9d0cfSchristos return (DW_DLV_OK);
1399dd9d0cfSchristos }
1409dd9d0cfSchristos
1419dd9d0cfSchristos int
dwarf_get_fde_at_pc(Dwarf_Fde * fdelist,Dwarf_Addr pc,Dwarf_Fde * ret_fde,Dwarf_Addr * lopc,Dwarf_Addr * hipc,Dwarf_Error * error)1429dd9d0cfSchristos dwarf_get_fde_at_pc(Dwarf_Fde *fdelist, Dwarf_Addr pc, Dwarf_Fde *ret_fde,
1439dd9d0cfSchristos Dwarf_Addr *lopc, Dwarf_Addr *hipc, Dwarf_Error *error)
1449dd9d0cfSchristos {
1459dd9d0cfSchristos Dwarf_FrameSec fs;
1469dd9d0cfSchristos Dwarf_Debug dbg;
1479dd9d0cfSchristos Dwarf_Fde fde;
1489dd9d0cfSchristos int i;
1499dd9d0cfSchristos
1509dd9d0cfSchristos dbg = fdelist != NULL ? (*fdelist)->fde_dbg : NULL;
1519dd9d0cfSchristos
1529dd9d0cfSchristos if (fdelist == NULL || ret_fde == NULL || lopc == NULL ||
1539dd9d0cfSchristos hipc == NULL) {
1549dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
1559dd9d0cfSchristos return (DW_DLV_ERROR);
1569dd9d0cfSchristos }
1579dd9d0cfSchristos
1589dd9d0cfSchristos fs = fdelist[0]->fde_fs;
1599dd9d0cfSchristos assert(fs != NULL);
1609dd9d0cfSchristos
1619dd9d0cfSchristos for (i = 0; (Dwarf_Unsigned)i < fs->fs_fdelen; i++) {
1629dd9d0cfSchristos fde = fdelist[i];
1639dd9d0cfSchristos if (pc >= fde->fde_initloc && pc < fde->fde_initloc +
1649dd9d0cfSchristos fde->fde_adrange) {
1659dd9d0cfSchristos *ret_fde = fde;
1669dd9d0cfSchristos *lopc = fde->fde_initloc;
1679dd9d0cfSchristos *hipc = fde->fde_initloc + fde->fde_adrange - 1;
1689dd9d0cfSchristos return (DW_DLV_OK);
1699dd9d0cfSchristos }
1709dd9d0cfSchristos }
1719dd9d0cfSchristos
1729dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
1739dd9d0cfSchristos return (DW_DLV_NO_ENTRY);
1749dd9d0cfSchristos }
1759dd9d0cfSchristos
1769dd9d0cfSchristos int
dwarf_get_cie_of_fde(Dwarf_Fde fde,Dwarf_Cie * ret_cie,Dwarf_Error * error)1779dd9d0cfSchristos dwarf_get_cie_of_fde(Dwarf_Fde fde, Dwarf_Cie *ret_cie, Dwarf_Error *error)
1789dd9d0cfSchristos {
1799dd9d0cfSchristos Dwarf_Debug dbg;
1809dd9d0cfSchristos
1819dd9d0cfSchristos dbg = fde != NULL ? fde->fde_dbg : NULL;
1829dd9d0cfSchristos
1839dd9d0cfSchristos if (fde == NULL || ret_cie == NULL) {
1849dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
1859dd9d0cfSchristos return (DW_DLV_ERROR);
1869dd9d0cfSchristos }
1879dd9d0cfSchristos
1889dd9d0cfSchristos *ret_cie = fde->fde_cie;
1899dd9d0cfSchristos
1909dd9d0cfSchristos return (DW_DLV_OK);
1919dd9d0cfSchristos }
1929dd9d0cfSchristos
1939dd9d0cfSchristos int
dwarf_get_fde_range(Dwarf_Fde fde,Dwarf_Addr * low_pc,Dwarf_Unsigned * func_len,Dwarf_Ptr * fde_bytes,Dwarf_Unsigned * fde_byte_len,Dwarf_Off * cie_offset,Dwarf_Signed * cie_index,Dwarf_Off * fde_offset,Dwarf_Error * error)1949dd9d0cfSchristos dwarf_get_fde_range(Dwarf_Fde fde, Dwarf_Addr *low_pc, Dwarf_Unsigned *func_len,
1959dd9d0cfSchristos Dwarf_Ptr *fde_bytes, Dwarf_Unsigned *fde_byte_len, Dwarf_Off *cie_offset,
1969dd9d0cfSchristos Dwarf_Signed *cie_index, Dwarf_Off *fde_offset, Dwarf_Error *error)
1979dd9d0cfSchristos {
1989dd9d0cfSchristos Dwarf_Debug dbg;
1999dd9d0cfSchristos
2009dd9d0cfSchristos dbg = fde != NULL ? fde->fde_dbg : NULL;
2019dd9d0cfSchristos
2029dd9d0cfSchristos if (fde == NULL || low_pc == NULL || func_len == NULL ||
2039dd9d0cfSchristos fde_bytes == NULL || fde_byte_len == NULL || cie_offset == NULL ||
2049dd9d0cfSchristos cie_index == NULL || fde_offset == NULL) {
2059dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
2069dd9d0cfSchristos return (DW_DLV_ERROR);
2079dd9d0cfSchristos }
2089dd9d0cfSchristos
2099dd9d0cfSchristos *low_pc = fde->fde_initloc;
2109dd9d0cfSchristos *func_len = fde->fde_adrange;
2119dd9d0cfSchristos *fde_bytes = fde->fde_addr;
2129dd9d0cfSchristos *fde_byte_len = fde->fde_length;
2139dd9d0cfSchristos *cie_offset = fde->fde_cieoff;
2149dd9d0cfSchristos *cie_index = fde->fde_cie->cie_index;
2159dd9d0cfSchristos *fde_offset = fde->fde_offset;
2169dd9d0cfSchristos
2179dd9d0cfSchristos return (DW_DLV_OK);
2189dd9d0cfSchristos }
2199dd9d0cfSchristos
2209dd9d0cfSchristos int
dwarf_get_cie_info(Dwarf_Cie cie,Dwarf_Unsigned * bytes_in_cie,Dwarf_Small * version,char ** augmenter,Dwarf_Unsigned * caf,Dwarf_Unsigned * daf,Dwarf_Half * ra,Dwarf_Ptr * initinst,Dwarf_Unsigned * inst_len,Dwarf_Error * error)2219dd9d0cfSchristos dwarf_get_cie_info(Dwarf_Cie cie, Dwarf_Unsigned *bytes_in_cie,
2229dd9d0cfSchristos Dwarf_Small *version, char **augmenter, Dwarf_Unsigned *caf,
2239dd9d0cfSchristos Dwarf_Unsigned *daf, Dwarf_Half *ra, Dwarf_Ptr *initinst,
2249dd9d0cfSchristos Dwarf_Unsigned *inst_len, Dwarf_Error *error)
2259dd9d0cfSchristos {
2269dd9d0cfSchristos
2279dd9d0cfSchristos if (cie == NULL || bytes_in_cie == NULL || version == NULL ||
2289dd9d0cfSchristos augmenter == NULL || caf == NULL || daf == NULL || ra == NULL ||
2299dd9d0cfSchristos initinst == NULL || inst_len == NULL) {
2309dd9d0cfSchristos DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
2319dd9d0cfSchristos return (DW_DLV_ERROR);
2329dd9d0cfSchristos }
2339dd9d0cfSchristos
2349dd9d0cfSchristos *bytes_in_cie = cie->cie_length;
2359dd9d0cfSchristos *version = cie->cie_version;
2369dd9d0cfSchristos *augmenter = (char *) cie->cie_augment;
2379dd9d0cfSchristos *caf = cie->cie_caf;
2389dd9d0cfSchristos *daf = cie->cie_daf;
2399dd9d0cfSchristos *ra = cie->cie_ra;
2409dd9d0cfSchristos *initinst = cie->cie_initinst;
2419dd9d0cfSchristos *inst_len = cie->cie_instlen;
2429dd9d0cfSchristos
2439dd9d0cfSchristos return (DW_DLV_OK);
2449dd9d0cfSchristos }
2459dd9d0cfSchristos
2469dd9d0cfSchristos int
dwarf_get_cie_index(Dwarf_Cie cie,Dwarf_Signed * cie_index,Dwarf_Error * error)2479dd9d0cfSchristos dwarf_get_cie_index(Dwarf_Cie cie, Dwarf_Signed *cie_index, Dwarf_Error *error)
2489dd9d0cfSchristos {
2499dd9d0cfSchristos
2509dd9d0cfSchristos if (cie == NULL || cie_index == NULL) {
2519dd9d0cfSchristos DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
2529dd9d0cfSchristos return (DW_DLV_ERROR);
2539dd9d0cfSchristos }
2549dd9d0cfSchristos
2559dd9d0cfSchristos *cie_index = cie->cie_index;
2569dd9d0cfSchristos
2579dd9d0cfSchristos return (DW_DLV_OK);
2589dd9d0cfSchristos }
2599dd9d0cfSchristos
2609dd9d0cfSchristos int
dwarf_get_fde_instr_bytes(Dwarf_Fde fde,Dwarf_Ptr * ret_inst,Dwarf_Unsigned * ret_len,Dwarf_Error * error)2619dd9d0cfSchristos dwarf_get_fde_instr_bytes(Dwarf_Fde fde, Dwarf_Ptr *ret_inst,
2629dd9d0cfSchristos Dwarf_Unsigned *ret_len, Dwarf_Error *error)
2639dd9d0cfSchristos {
2649dd9d0cfSchristos Dwarf_Debug dbg;
2659dd9d0cfSchristos
2669dd9d0cfSchristos dbg = fde != NULL ? fde->fde_dbg : NULL;
2679dd9d0cfSchristos
2689dd9d0cfSchristos if (fde == NULL || ret_inst == NULL || ret_len == NULL) {
2699dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
2709dd9d0cfSchristos return (DW_DLV_ERROR);
2719dd9d0cfSchristos }
2729dd9d0cfSchristos
2739dd9d0cfSchristos *ret_inst = fde->fde_inst;
2749dd9d0cfSchristos *ret_len = fde->fde_instlen;
2759dd9d0cfSchristos
2769dd9d0cfSchristos return (DW_DLV_OK);
2779dd9d0cfSchristos }
2789dd9d0cfSchristos
2799dd9d0cfSchristos #define RL rt->rt3_rules[table_column]
2809dd9d0cfSchristos #define CFA rt->rt3_cfa_rule
2819dd9d0cfSchristos
2829dd9d0cfSchristos int
dwarf_get_fde_info_for_reg(Dwarf_Fde fde,Dwarf_Half table_column,Dwarf_Addr pc_requested,Dwarf_Signed * offset_relevant,Dwarf_Signed * register_num,Dwarf_Signed * offset,Dwarf_Addr * row_pc,Dwarf_Error * error)2839dd9d0cfSchristos dwarf_get_fde_info_for_reg(Dwarf_Fde fde, Dwarf_Half table_column,
2849dd9d0cfSchristos Dwarf_Addr pc_requested, Dwarf_Signed *offset_relevant,
2859dd9d0cfSchristos Dwarf_Signed *register_num, Dwarf_Signed *offset, Dwarf_Addr *row_pc,
2869dd9d0cfSchristos Dwarf_Error *error)
2879dd9d0cfSchristos {
2889dd9d0cfSchristos Dwarf_Regtable3 *rt;
2899dd9d0cfSchristos Dwarf_Debug dbg;
2909dd9d0cfSchristos Dwarf_Addr pc;
2919dd9d0cfSchristos int ret;
2929dd9d0cfSchristos
2939dd9d0cfSchristos dbg = fde != NULL ? fde->fde_dbg : NULL;
2949dd9d0cfSchristos
2959dd9d0cfSchristos if (fde == NULL || offset_relevant == NULL || register_num == NULL ||
2969dd9d0cfSchristos offset == NULL || row_pc == NULL) {
2979dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
2989dd9d0cfSchristos return (DW_DLV_ERROR);
2999dd9d0cfSchristos }
3009dd9d0cfSchristos
3019dd9d0cfSchristos if (pc_requested < fde->fde_initloc ||
3029dd9d0cfSchristos pc_requested >= fde->fde_initloc + fde->fde_adrange) {
3039dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
3049dd9d0cfSchristos return (DW_DLV_ERROR);
3059dd9d0cfSchristos }
3069dd9d0cfSchristos
3079dd9d0cfSchristos ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
3089dd9d0cfSchristos error);
3099dd9d0cfSchristos if (ret != DW_DLE_NONE)
3109dd9d0cfSchristos return (DW_DLV_ERROR);
3119dd9d0cfSchristos
3129dd9d0cfSchristos if (table_column == dbg->dbg_frame_cfa_value) {
3139dd9d0cfSchristos /* Application ask for CFA. */
3149dd9d0cfSchristos *offset_relevant = CFA.dw_offset_relevant;
3159dd9d0cfSchristos *register_num = CFA.dw_regnum;
3169dd9d0cfSchristos *offset = CFA.dw_offset_or_block_len;
3179dd9d0cfSchristos } else {
3189dd9d0cfSchristos /* Application ask for normal registers. */
3199dd9d0cfSchristos if (table_column >= dbg->dbg_frame_rule_table_size ||
3209dd9d0cfSchristos table_column >= DW_REG_TABLE_SIZE) {
3219dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
3229dd9d0cfSchristos return (DW_DLV_ERROR);
3239dd9d0cfSchristos }
3249dd9d0cfSchristos
3259dd9d0cfSchristos *offset_relevant = RL.dw_offset_relevant;
3269dd9d0cfSchristos *register_num = RL.dw_regnum;
3279dd9d0cfSchristos *offset = RL.dw_offset_or_block_len;
3289dd9d0cfSchristos }
3299dd9d0cfSchristos
3309dd9d0cfSchristos *row_pc = pc;
3319dd9d0cfSchristos
3329dd9d0cfSchristos return (DW_DLV_OK);
3339dd9d0cfSchristos }
3349dd9d0cfSchristos
3359dd9d0cfSchristos int
dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,Dwarf_Addr pc_requested,Dwarf_Regtable * reg_table,Dwarf_Addr * row_pc,Dwarf_Error * error)3369dd9d0cfSchristos dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde, Dwarf_Addr pc_requested,
3379dd9d0cfSchristos Dwarf_Regtable *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error)
3389dd9d0cfSchristos {
3399dd9d0cfSchristos Dwarf_Debug dbg;
3409dd9d0cfSchristos Dwarf_Regtable3 *rt;
3419dd9d0cfSchristos Dwarf_Addr pc;
3429dd9d0cfSchristos Dwarf_Half cfa;
3439dd9d0cfSchristos int i, ret;
3449dd9d0cfSchristos
3459dd9d0cfSchristos dbg = fde != NULL ? fde->fde_dbg : NULL;
3469dd9d0cfSchristos
3479dd9d0cfSchristos if (fde == NULL || reg_table == NULL || row_pc == NULL) {
3489dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
3499dd9d0cfSchristos return (DW_DLV_ERROR);
3509dd9d0cfSchristos }
3519dd9d0cfSchristos
3529dd9d0cfSchristos assert(dbg != NULL);
3539dd9d0cfSchristos
3549dd9d0cfSchristos if (pc_requested < fde->fde_initloc ||
3559dd9d0cfSchristos pc_requested >= fde->fde_initloc + fde->fde_adrange) {
3569dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
3579dd9d0cfSchristos return (DW_DLV_ERROR);
3589dd9d0cfSchristos }
3599dd9d0cfSchristos
3609dd9d0cfSchristos ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
3619dd9d0cfSchristos error);
3629dd9d0cfSchristos if (ret != DW_DLE_NONE)
3639dd9d0cfSchristos return (DW_DLV_ERROR);
3649dd9d0cfSchristos
3659dd9d0cfSchristos /*
3669dd9d0cfSchristos * Copy the CFA rule to the column intended for holding the CFA,
3679dd9d0cfSchristos * if it's within the range of regtable.
3689dd9d0cfSchristos */
3699dd9d0cfSchristos cfa = dbg->dbg_frame_cfa_value;
3709dd9d0cfSchristos if (cfa < DW_REG_TABLE_SIZE) {
3719dd9d0cfSchristos reg_table->rules[cfa].dw_offset_relevant =
3729dd9d0cfSchristos CFA.dw_offset_relevant;
3739dd9d0cfSchristos reg_table->rules[cfa].dw_regnum = CFA.dw_regnum;
3749dd9d0cfSchristos reg_table->rules[cfa].dw_offset = CFA.dw_offset_or_block_len;
3759dd9d0cfSchristos }
3769dd9d0cfSchristos
3779dd9d0cfSchristos /*
3789dd9d0cfSchristos * Copy other columns.
3799dd9d0cfSchristos */
3809dd9d0cfSchristos for (i = 0; i < DW_REG_TABLE_SIZE && i < dbg->dbg_frame_rule_table_size;
3819dd9d0cfSchristos i++) {
3829dd9d0cfSchristos
3839dd9d0cfSchristos /* Do not overwrite CFA column */
3849dd9d0cfSchristos if (i == cfa)
3859dd9d0cfSchristos continue;
3869dd9d0cfSchristos
3879dd9d0cfSchristos reg_table->rules[i].dw_offset_relevant =
3889dd9d0cfSchristos rt->rt3_rules[i].dw_offset_relevant;
3899dd9d0cfSchristos reg_table->rules[i].dw_regnum = rt->rt3_rules[i].dw_regnum;
3909dd9d0cfSchristos reg_table->rules[i].dw_offset =
3919dd9d0cfSchristos rt->rt3_rules[i].dw_offset_or_block_len;
3929dd9d0cfSchristos }
3939dd9d0cfSchristos
3949dd9d0cfSchristos *row_pc = pc;
3959dd9d0cfSchristos
3969dd9d0cfSchristos return (DW_DLV_OK);
3979dd9d0cfSchristos }
3989dd9d0cfSchristos
3999dd9d0cfSchristos int
dwarf_get_fde_info_for_reg3(Dwarf_Fde fde,Dwarf_Half table_column,Dwarf_Addr pc_requested,Dwarf_Small * value_type,Dwarf_Signed * offset_relevant,Dwarf_Signed * register_num,Dwarf_Signed * offset_or_block_len,Dwarf_Ptr * block_ptr,Dwarf_Addr * row_pc,Dwarf_Error * error)4009dd9d0cfSchristos dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, Dwarf_Half table_column,
4019dd9d0cfSchristos Dwarf_Addr pc_requested, Dwarf_Small *value_type,
4029dd9d0cfSchristos Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num,
4039dd9d0cfSchristos Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr,
4049dd9d0cfSchristos Dwarf_Addr *row_pc, Dwarf_Error *error)
4059dd9d0cfSchristos {
4069dd9d0cfSchristos Dwarf_Regtable3 *rt;
4079dd9d0cfSchristos Dwarf_Debug dbg;
4089dd9d0cfSchristos Dwarf_Addr pc;
4099dd9d0cfSchristos int ret;
4109dd9d0cfSchristos
4119dd9d0cfSchristos dbg = fde != NULL ? fde->fde_dbg : NULL;
4129dd9d0cfSchristos
4139dd9d0cfSchristos if (fde == NULL || value_type == NULL || offset_relevant == NULL ||
4149dd9d0cfSchristos register_num == NULL || offset_or_block_len == NULL ||
4159dd9d0cfSchristos block_ptr == NULL || row_pc == NULL) {
4169dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
4179dd9d0cfSchristos return (DW_DLV_ERROR);
4189dd9d0cfSchristos }
4199dd9d0cfSchristos
4209dd9d0cfSchristos if (pc_requested < fde->fde_initloc ||
4219dd9d0cfSchristos pc_requested >= fde->fde_initloc + fde->fde_adrange) {
4229dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
4239dd9d0cfSchristos return (DW_DLV_ERROR);
4249dd9d0cfSchristos }
4259dd9d0cfSchristos
4269dd9d0cfSchristos ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
4279dd9d0cfSchristos error);
4289dd9d0cfSchristos if (ret != DW_DLE_NONE)
4299dd9d0cfSchristos return (DW_DLV_ERROR);
4309dd9d0cfSchristos
4319dd9d0cfSchristos if (table_column >= dbg->dbg_frame_rule_table_size) {
4329dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
4339dd9d0cfSchristos return (DW_DLV_ERROR);
4349dd9d0cfSchristos }
4359dd9d0cfSchristos
4369dd9d0cfSchristos *value_type = RL.dw_value_type;
4379dd9d0cfSchristos *offset_relevant = RL.dw_offset_relevant;
4389dd9d0cfSchristos *register_num = RL.dw_regnum;
4399dd9d0cfSchristos *offset_or_block_len = RL.dw_offset_or_block_len;
4409dd9d0cfSchristos *block_ptr = RL.dw_block_ptr;
4419dd9d0cfSchristos *row_pc = pc;
4429dd9d0cfSchristos
4439dd9d0cfSchristos return (DW_DLV_OK);
4449dd9d0cfSchristos }
4459dd9d0cfSchristos
4469dd9d0cfSchristos int
dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,Dwarf_Addr pc_requested,Dwarf_Small * value_type,Dwarf_Signed * offset_relevant,Dwarf_Signed * register_num,Dwarf_Signed * offset_or_block_len,Dwarf_Ptr * block_ptr,Dwarf_Addr * row_pc,Dwarf_Error * error)4479dd9d0cfSchristos dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, Dwarf_Addr pc_requested,
4489dd9d0cfSchristos Dwarf_Small *value_type, Dwarf_Signed *offset_relevant,
4499dd9d0cfSchristos Dwarf_Signed *register_num, Dwarf_Signed *offset_or_block_len,
4509dd9d0cfSchristos Dwarf_Ptr *block_ptr, Dwarf_Addr *row_pc, Dwarf_Error *error)
4519dd9d0cfSchristos {
4529dd9d0cfSchristos Dwarf_Regtable3 *rt;
4539dd9d0cfSchristos Dwarf_Debug dbg;
4549dd9d0cfSchristos Dwarf_Addr pc;
4559dd9d0cfSchristos int ret;
4569dd9d0cfSchristos
4579dd9d0cfSchristos dbg = fde != NULL ? fde->fde_dbg : NULL;
4589dd9d0cfSchristos
4599dd9d0cfSchristos if (fde == NULL || value_type == NULL || offset_relevant == NULL ||
4609dd9d0cfSchristos register_num == NULL || offset_or_block_len == NULL ||
4619dd9d0cfSchristos block_ptr == NULL || row_pc == NULL) {
4629dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
4639dd9d0cfSchristos return (DW_DLV_ERROR);
4649dd9d0cfSchristos }
4659dd9d0cfSchristos
4669dd9d0cfSchristos if (pc_requested < fde->fde_initloc ||
4679dd9d0cfSchristos pc_requested >= fde->fde_initloc + fde->fde_adrange) {
4689dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
4699dd9d0cfSchristos return (DW_DLV_ERROR);
4709dd9d0cfSchristos }
4719dd9d0cfSchristos
4729dd9d0cfSchristos ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
4739dd9d0cfSchristos error);
4749dd9d0cfSchristos if (ret != DW_DLE_NONE)
4759dd9d0cfSchristos return (DW_DLV_ERROR);
4769dd9d0cfSchristos
4779dd9d0cfSchristos *value_type = CFA.dw_value_type;
4789dd9d0cfSchristos *offset_relevant = CFA.dw_offset_relevant;
4799dd9d0cfSchristos *register_num = CFA.dw_regnum;
4809dd9d0cfSchristos *offset_or_block_len = CFA.dw_offset_or_block_len;
4819dd9d0cfSchristos *block_ptr = CFA.dw_block_ptr;
4829dd9d0cfSchristos *row_pc = pc;
4839dd9d0cfSchristos
4849dd9d0cfSchristos return (DW_DLV_OK);
4859dd9d0cfSchristos }
4869dd9d0cfSchristos
4879dd9d0cfSchristos #undef RL
4889dd9d0cfSchristos #undef CFA
4899dd9d0cfSchristos
4909dd9d0cfSchristos int
dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,Dwarf_Addr pc_requested,Dwarf_Regtable3 * reg_table,Dwarf_Addr * row_pc,Dwarf_Error * error)4919dd9d0cfSchristos dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, Dwarf_Addr pc_requested,
4929dd9d0cfSchristos Dwarf_Regtable3 *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error)
4939dd9d0cfSchristos {
4949dd9d0cfSchristos Dwarf_Regtable3 *rt;
4959dd9d0cfSchristos Dwarf_Debug dbg;
4969dd9d0cfSchristos Dwarf_Addr pc;
4979dd9d0cfSchristos int ret;
4989dd9d0cfSchristos
4999dd9d0cfSchristos dbg = fde != NULL ? fde->fde_dbg : NULL;
5009dd9d0cfSchristos
5019dd9d0cfSchristos if (fde == NULL || reg_table == NULL || reg_table->rt3_rules == NULL ||
5029dd9d0cfSchristos row_pc == NULL) {
5039dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
5049dd9d0cfSchristos return (DW_DLV_ERROR);
5059dd9d0cfSchristos }
5069dd9d0cfSchristos
5079dd9d0cfSchristos assert(dbg != NULL);
5089dd9d0cfSchristos
5099dd9d0cfSchristos if (pc_requested < fde->fde_initloc ||
5109dd9d0cfSchristos pc_requested >= fde->fde_initloc + fde->fde_adrange) {
5119dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
5129dd9d0cfSchristos return (DW_DLV_ERROR);
5139dd9d0cfSchristos }
5149dd9d0cfSchristos
5159dd9d0cfSchristos ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
5169dd9d0cfSchristos error);
5179dd9d0cfSchristos if (ret != DW_DLE_NONE)
5189dd9d0cfSchristos return (DW_DLV_ERROR);
5199dd9d0cfSchristos
5209dd9d0cfSchristos ret = _dwarf_frame_regtable_copy(dbg, ®_table, rt, error);
5219dd9d0cfSchristos if (ret != DW_DLE_NONE)
5229dd9d0cfSchristos return (DW_DLV_ERROR);
5239dd9d0cfSchristos
5249dd9d0cfSchristos *row_pc = pc;
5259dd9d0cfSchristos
5269dd9d0cfSchristos return (DW_DLV_OK);
5279dd9d0cfSchristos }
5289dd9d0cfSchristos
5299dd9d0cfSchristos int
dwarf_expand_frame_instructions(Dwarf_Cie cie,Dwarf_Ptr instruction,Dwarf_Unsigned len,Dwarf_Frame_Op ** ret_oplist,Dwarf_Signed * ret_opcnt,Dwarf_Error * error)5309dd9d0cfSchristos dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Ptr instruction,
5319dd9d0cfSchristos Dwarf_Unsigned len, Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt,
5329dd9d0cfSchristos Dwarf_Error *error)
5339dd9d0cfSchristos {
5349dd9d0cfSchristos Dwarf_Debug dbg;
5359dd9d0cfSchristos int ret;
5369dd9d0cfSchristos
5379dd9d0cfSchristos dbg = cie != NULL ? cie->cie_dbg : NULL;
5389dd9d0cfSchristos
5399dd9d0cfSchristos if (cie == NULL || instruction == NULL || len == 0 ||
5409dd9d0cfSchristos ret_oplist == NULL || ret_opcnt == NULL) {
5419dd9d0cfSchristos DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
5429dd9d0cfSchristos return (DW_DLV_ERROR);
5439dd9d0cfSchristos }
5449dd9d0cfSchristos
54542bd3019Schristos ret = _dwarf_frame_get_fop(dbg, cie->cie_addrsize, instruction, len,
54642bd3019Schristos ret_oplist, ret_opcnt, error);
5479dd9d0cfSchristos if (ret != DW_DLE_NONE)
5489dd9d0cfSchristos return (DW_DLV_ERROR);
5499dd9d0cfSchristos
5509dd9d0cfSchristos return (DW_DLV_OK);
5519dd9d0cfSchristos }
5529dd9d0cfSchristos
5539dd9d0cfSchristos Dwarf_Half
dwarf_set_frame_rule_table_size(Dwarf_Debug dbg,Dwarf_Half value)5549dd9d0cfSchristos dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value)
5559dd9d0cfSchristos {
5569dd9d0cfSchristos Dwarf_Half old_value;
5579dd9d0cfSchristos
5589dd9d0cfSchristos old_value = dbg->dbg_frame_rule_table_size;
5599dd9d0cfSchristos dbg->dbg_frame_rule_table_size = value;
5609dd9d0cfSchristos
5619dd9d0cfSchristos return (old_value);
5629dd9d0cfSchristos }
5639dd9d0cfSchristos
5649dd9d0cfSchristos Dwarf_Half
dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg,Dwarf_Half value)5659dd9d0cfSchristos dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value)
5669dd9d0cfSchristos {
5679dd9d0cfSchristos Dwarf_Half old_value;
5689dd9d0cfSchristos
5699dd9d0cfSchristos old_value = dbg->dbg_frame_rule_initial_value;
5709dd9d0cfSchristos dbg->dbg_frame_rule_initial_value = value;
5719dd9d0cfSchristos
5729dd9d0cfSchristos return (old_value);
5739dd9d0cfSchristos }
5749dd9d0cfSchristos
5759dd9d0cfSchristos Dwarf_Half
dwarf_set_frame_cfa_value(Dwarf_Debug dbg,Dwarf_Half value)5769dd9d0cfSchristos dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value)
5779dd9d0cfSchristos {
5789dd9d0cfSchristos Dwarf_Half old_value;
5799dd9d0cfSchristos
5809dd9d0cfSchristos old_value = dbg->dbg_frame_cfa_value;
5819dd9d0cfSchristos dbg->dbg_frame_cfa_value = value;
5829dd9d0cfSchristos
5839dd9d0cfSchristos return (old_value);
5849dd9d0cfSchristos }
5859dd9d0cfSchristos
5869dd9d0cfSchristos Dwarf_Half
dwarf_set_frame_same_value(Dwarf_Debug dbg,Dwarf_Half value)5879dd9d0cfSchristos dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value)
5889dd9d0cfSchristos {
5899dd9d0cfSchristos Dwarf_Half old_value;
5909dd9d0cfSchristos
5919dd9d0cfSchristos old_value = dbg->dbg_frame_same_value;
5929dd9d0cfSchristos dbg->dbg_frame_same_value = value;
5939dd9d0cfSchristos
5949dd9d0cfSchristos return (old_value);
5959dd9d0cfSchristos }
5969dd9d0cfSchristos
5979dd9d0cfSchristos Dwarf_Half
dwarf_set_frame_undefined_value(Dwarf_Debug dbg,Dwarf_Half value)5989dd9d0cfSchristos dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value)
5999dd9d0cfSchristos {
6009dd9d0cfSchristos Dwarf_Half old_value;
6019dd9d0cfSchristos
6029dd9d0cfSchristos old_value = dbg->dbg_frame_undefined_value;
6039dd9d0cfSchristos dbg->dbg_frame_undefined_value = value;
6049dd9d0cfSchristos
6059dd9d0cfSchristos return (old_value);
6069dd9d0cfSchristos }
607