1*2de3b87aSKai Wang /*-
2*2de3b87aSKai Wang * Copyright (c) 2010 Kai Wang
3*2de3b87aSKai Wang * All rights reserved.
4*2de3b87aSKai Wang *
5*2de3b87aSKai Wang * Redistribution and use in source and binary forms, with or without
6*2de3b87aSKai Wang * modification, are permitted provided that the following conditions
7*2de3b87aSKai Wang * are met:
8*2de3b87aSKai Wang * 1. Redistributions of source code must retain the above copyright
9*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer.
10*2de3b87aSKai Wang * 2. Redistributions in binary form must reproduce the above copyright
11*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer in the
12*2de3b87aSKai Wang * documentation and/or other materials provided with the distribution.
13*2de3b87aSKai Wang *
14*2de3b87aSKai Wang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*2de3b87aSKai Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*2de3b87aSKai Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*2de3b87aSKai Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*2de3b87aSKai Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*2de3b87aSKai Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*2de3b87aSKai Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*2de3b87aSKai Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*2de3b87aSKai Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*2de3b87aSKai Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*2de3b87aSKai Wang * SUCH DAMAGE.
25*2de3b87aSKai Wang */
26*2de3b87aSKai Wang
27*2de3b87aSKai Wang #include "_libdwarf.h"
28*2de3b87aSKai Wang
29*2de3b87aSKai Wang ELFTC_VCSID("$Id: dwarf_pro_frame.c 2074 2011-10-27 03:34:33Z jkoshy $");
30*2de3b87aSKai Wang
31*2de3b87aSKai Wang Dwarf_P_Fde
dwarf_new_fde(Dwarf_P_Debug dbg,Dwarf_Error * error)32*2de3b87aSKai Wang dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error *error)
33*2de3b87aSKai Wang {
34*2de3b87aSKai Wang Dwarf_P_Fde fde;
35*2de3b87aSKai Wang
36*2de3b87aSKai Wang if (dbg == NULL) {
37*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
38*2de3b87aSKai Wang return (DW_DLV_BADADDR);
39*2de3b87aSKai Wang }
40*2de3b87aSKai Wang
41*2de3b87aSKai Wang if ((fde = calloc(1, sizeof(struct _Dwarf_Fde))) == NULL) {
42*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
43*2de3b87aSKai Wang return (DW_DLV_BADADDR);
44*2de3b87aSKai Wang }
45*2de3b87aSKai Wang
46*2de3b87aSKai Wang fde->fde_dbg = dbg;
47*2de3b87aSKai Wang
48*2de3b87aSKai Wang return (fde);
49*2de3b87aSKai Wang }
50*2de3b87aSKai Wang
51*2de3b87aSKai Wang Dwarf_Unsigned
dwarf_add_frame_cie(Dwarf_P_Debug dbg,char * augmenter,Dwarf_Small caf,Dwarf_Small daf,Dwarf_Small ra,Dwarf_Ptr initinst,Dwarf_Unsigned inst_len,Dwarf_Error * error)52*2de3b87aSKai Wang dwarf_add_frame_cie(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small caf,
53*2de3b87aSKai Wang Dwarf_Small daf, Dwarf_Small ra, Dwarf_Ptr initinst,
54*2de3b87aSKai Wang Dwarf_Unsigned inst_len, Dwarf_Error *error)
55*2de3b87aSKai Wang {
56*2de3b87aSKai Wang Dwarf_P_Cie cie;
57*2de3b87aSKai Wang
58*2de3b87aSKai Wang if (dbg == NULL) {
59*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
60*2de3b87aSKai Wang return (DW_DLV_NOCOUNT);
61*2de3b87aSKai Wang }
62*2de3b87aSKai Wang
63*2de3b87aSKai Wang if ((cie = calloc(1, sizeof(struct _Dwarf_Cie))) == NULL) {
64*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error,DW_DLE_MEMORY);
65*2de3b87aSKai Wang return (DW_DLV_NOCOUNT);
66*2de3b87aSKai Wang }
67*2de3b87aSKai Wang STAILQ_INSERT_TAIL(&dbg->dbgp_cielist, cie, cie_next);
68*2de3b87aSKai Wang
69*2de3b87aSKai Wang cie->cie_index = dbg->dbgp_cielen++;
70*2de3b87aSKai Wang
71*2de3b87aSKai Wang if (augmenter != NULL) {
72*2de3b87aSKai Wang cie->cie_augment = (uint8_t *) strdup(augmenter);
73*2de3b87aSKai Wang if (cie->cie_augment == NULL) {
74*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
75*2de3b87aSKai Wang return (DW_DLV_NOCOUNT);
76*2de3b87aSKai Wang }
77*2de3b87aSKai Wang }
78*2de3b87aSKai Wang
79*2de3b87aSKai Wang cie->cie_caf = caf;
80*2de3b87aSKai Wang cie->cie_daf = (int8_t) daf; /* daf is signed. */
81*2de3b87aSKai Wang cie->cie_ra = ra;
82*2de3b87aSKai Wang if (initinst != NULL && inst_len > 0) {
83*2de3b87aSKai Wang cie->cie_initinst = malloc((size_t) inst_len);
84*2de3b87aSKai Wang if (cie->cie_initinst == NULL) {
85*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
86*2de3b87aSKai Wang return (DW_DLV_NOCOUNT);
87*2de3b87aSKai Wang }
88*2de3b87aSKai Wang memcpy(cie->cie_initinst, initinst, inst_len);
89*2de3b87aSKai Wang cie->cie_instlen = inst_len;
90*2de3b87aSKai Wang }
91*2de3b87aSKai Wang
92*2de3b87aSKai Wang return (cie->cie_index);
93*2de3b87aSKai Wang }
94*2de3b87aSKai Wang
95*2de3b87aSKai Wang Dwarf_Unsigned
dwarf_add_frame_fde(Dwarf_P_Debug dbg,Dwarf_P_Fde fde,Dwarf_P_Die die,Dwarf_Unsigned cie,Dwarf_Addr virt_addr,Dwarf_Unsigned code_len,Dwarf_Unsigned symbol_index,Dwarf_Error * error)96*2de3b87aSKai Wang dwarf_add_frame_fde(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die,
97*2de3b87aSKai Wang Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len,
98*2de3b87aSKai Wang Dwarf_Unsigned symbol_index, Dwarf_Error *error)
99*2de3b87aSKai Wang {
100*2de3b87aSKai Wang
101*2de3b87aSKai Wang return (dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr, code_len,
102*2de3b87aSKai Wang symbol_index, 0, 0, error));
103*2de3b87aSKai Wang }
104*2de3b87aSKai Wang
105*2de3b87aSKai Wang Dwarf_Unsigned
dwarf_add_frame_fde_b(Dwarf_P_Debug dbg,Dwarf_P_Fde fde,Dwarf_P_Die die,Dwarf_Unsigned cie,Dwarf_Addr virt_addr,Dwarf_Unsigned code_len,Dwarf_Unsigned symbol_index,Dwarf_Unsigned end_symbol_index,Dwarf_Addr offset_from_end_sym,Dwarf_Error * error)106*2de3b87aSKai Wang dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die,
107*2de3b87aSKai Wang Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len,
108*2de3b87aSKai Wang Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index,
109*2de3b87aSKai Wang Dwarf_Addr offset_from_end_sym, Dwarf_Error *error)
110*2de3b87aSKai Wang {
111*2de3b87aSKai Wang Dwarf_P_Cie ciep;
112*2de3b87aSKai Wang int i;
113*2de3b87aSKai Wang
114*2de3b87aSKai Wang /*
115*2de3b87aSKai Wang * XXX SGI libdwarf need the DIE arg because later it will insert a
116*2de3b87aSKai Wang * DW_AT_MIPS_fde attribute, which points to the offset the
117*2de3b87aSKai Wang * correspoding FDE, into this DIE. Do we need this?
118*2de3b87aSKai Wang */
119*2de3b87aSKai Wang (void) die;
120*2de3b87aSKai Wang
121*2de3b87aSKai Wang if (dbg == NULL || fde == NULL || fde->fde_dbg != dbg) {
122*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
123*2de3b87aSKai Wang return (DW_DLV_NOCOUNT);
124*2de3b87aSKai Wang }
125*2de3b87aSKai Wang
126*2de3b87aSKai Wang ciep = STAILQ_FIRST(&dbg->dbgp_cielist);
127*2de3b87aSKai Wang for (i = 0; (Dwarf_Unsigned) i < cie; i++) {
128*2de3b87aSKai Wang ciep = STAILQ_NEXT(ciep, cie_next);
129*2de3b87aSKai Wang if (ciep == NULL)
130*2de3b87aSKai Wang break;
131*2de3b87aSKai Wang }
132*2de3b87aSKai Wang if (ciep == NULL) {
133*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
134*2de3b87aSKai Wang return (DW_DLV_NOCOUNT);
135*2de3b87aSKai Wang }
136*2de3b87aSKai Wang
137*2de3b87aSKai Wang if (end_symbol_index > 0 &&
138*2de3b87aSKai Wang (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) {
139*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
140*2de3b87aSKai Wang return (DW_DLV_NOCOUNT);
141*2de3b87aSKai Wang }
142*2de3b87aSKai Wang
143*2de3b87aSKai Wang fde->fde_cie = ciep;
144*2de3b87aSKai Wang fde->fde_initloc = virt_addr;
145*2de3b87aSKai Wang fde->fde_adrange = code_len;
146*2de3b87aSKai Wang fde->fde_symndx = symbol_index;
147*2de3b87aSKai Wang fde->fde_esymndx = end_symbol_index;
148*2de3b87aSKai Wang fde->fde_eoff = offset_from_end_sym;
149*2de3b87aSKai Wang
150*2de3b87aSKai Wang STAILQ_INSERT_TAIL(&dbg->dbgp_fdelist, fde, fde_next);
151*2de3b87aSKai Wang
152*2de3b87aSKai Wang return (dbg->dbgp_fdelen++);
153*2de3b87aSKai Wang }
154*2de3b87aSKai Wang
155*2de3b87aSKai Wang Dwarf_P_Fde
dwarf_fde_cfa_offset(Dwarf_P_Fde fde,Dwarf_Unsigned reg,Dwarf_Signed offset,Dwarf_Error * error)156*2de3b87aSKai Wang dwarf_fde_cfa_offset(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset,
157*2de3b87aSKai Wang Dwarf_Error *error)
158*2de3b87aSKai Wang {
159*2de3b87aSKai Wang int ret;
160*2de3b87aSKai Wang Dwarf_Debug dbg;
161*2de3b87aSKai Wang
162*2de3b87aSKai Wang dbg = fde != NULL ? fde->fde_dbg : NULL;
163*2de3b87aSKai Wang
164*2de3b87aSKai Wang if (fde == NULL || reg > 0x3f) {
165*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
166*2de3b87aSKai Wang return (DW_DLV_BADADDR);
167*2de3b87aSKai Wang }
168*2de3b87aSKai Wang
169*2de3b87aSKai Wang ret = _dwarf_frame_fde_add_inst(fde, DW_CFA_offset | (reg & 0x3f),
170*2de3b87aSKai Wang offset, 0, error);
171*2de3b87aSKai Wang
172*2de3b87aSKai Wang if (ret != DW_DLE_NONE)
173*2de3b87aSKai Wang return (DW_DLV_BADADDR);
174*2de3b87aSKai Wang
175*2de3b87aSKai Wang return (fde);
176*2de3b87aSKai Wang }
177*2de3b87aSKai Wang
178*2de3b87aSKai Wang Dwarf_P_Fde
dwarf_add_fde_inst(Dwarf_P_Fde fde,Dwarf_Small op,Dwarf_Unsigned val1,Dwarf_Unsigned val2,Dwarf_Error * error)179*2de3b87aSKai Wang dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1,
180*2de3b87aSKai Wang Dwarf_Unsigned val2, Dwarf_Error *error)
181*2de3b87aSKai Wang {
182*2de3b87aSKai Wang int ret;
183*2de3b87aSKai Wang
184*2de3b87aSKai Wang if (fde == NULL) {
185*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
186*2de3b87aSKai Wang return (DW_DLV_BADADDR);
187*2de3b87aSKai Wang }
188*2de3b87aSKai Wang
189*2de3b87aSKai Wang ret = _dwarf_frame_fde_add_inst(fde, op, val1, val2, error);
190*2de3b87aSKai Wang
191*2de3b87aSKai Wang if (ret != DW_DLE_NONE)
192*2de3b87aSKai Wang return (DW_DLV_BADADDR);
193*2de3b87aSKai Wang
194*2de3b87aSKai Wang return (fde);
195*2de3b87aSKai Wang }
196