1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi
3*7fd79137SRobert Mustacchi Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
4*7fd79137SRobert Mustacchi
5*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it
6*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License
7*7fd79137SRobert Mustacchi as published by the Free Software Foundation.
8*7fd79137SRobert Mustacchi
9*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but
10*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of
11*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*7fd79137SRobert Mustacchi
13*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is
14*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement
15*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or
16*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if
17*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with
18*7fd79137SRobert Mustacchi other software, or any other product whatsoever.
19*7fd79137SRobert Mustacchi
20*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public
21*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software
22*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23*7fd79137SRobert Mustacchi USA.
24*7fd79137SRobert Mustacchi
25*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
26*7fd79137SRobert Mustacchi Mountain View, CA 94043, or:
27*7fd79137SRobert Mustacchi
28*7fd79137SRobert Mustacchi http://www.sgi.com
29*7fd79137SRobert Mustacchi
30*7fd79137SRobert Mustacchi For further information regarding this notice, see:
31*7fd79137SRobert Mustacchi
32*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan
33*7fd79137SRobert Mustacchi
34*7fd79137SRobert Mustacchi */
35*7fd79137SRobert Mustacchi
36*7fd79137SRobert Mustacchi
37*7fd79137SRobert Mustacchi
38*7fd79137SRobert Mustacchi #include "config.h"
39*7fd79137SRobert Mustacchi #include "libdwarfdefs.h"
40*7fd79137SRobert Mustacchi #include <stdio.h>
41*7fd79137SRobert Mustacchi #include <string.h>
42*7fd79137SRobert Mustacchi #include <limits.h>
43*7fd79137SRobert Mustacchi #include "pro_incl.h"
44*7fd79137SRobert Mustacchi #include "pro_frame.h"
45*7fd79137SRobert Mustacchi
46*7fd79137SRobert Mustacchi static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde,
47*7fd79137SRobert Mustacchi Dwarf_P_Frame_Pgm inst);
48*7fd79137SRobert Mustacchi
49*7fd79137SRobert Mustacchi /*-------------------------------------------------------------------------
50*7fd79137SRobert Mustacchi This function adds a cie struct to the debug pointer. Its in the
51*7fd79137SRobert Mustacchi form of a linked list.
52*7fd79137SRobert Mustacchi augmenter: string reps augmentation (implementation defined)
53*7fd79137SRobert Mustacchi code_align: alignment of code
54*7fd79137SRobert Mustacchi data_align: alignment of data
55*7fd79137SRobert Mustacchi init_bytes: byts having initial instructions
56*7fd79137SRobert Mustacchi init_n_bytes: number of bytes of initial instructions
57*7fd79137SRobert Mustacchi --------------------------------------------------------------------------*/
58*7fd79137SRobert Mustacchi Dwarf_Unsigned
dwarf_add_frame_cie(Dwarf_P_Debug dbg,char * augmenter,Dwarf_Small code_align,Dwarf_Small data_align,Dwarf_Small return_reg,Dwarf_Ptr init_bytes,Dwarf_Unsigned init_n_bytes,Dwarf_Error * error)59*7fd79137SRobert Mustacchi dwarf_add_frame_cie(Dwarf_P_Debug dbg,
60*7fd79137SRobert Mustacchi char *augmenter,
61*7fd79137SRobert Mustacchi Dwarf_Small code_align,
62*7fd79137SRobert Mustacchi Dwarf_Small data_align,
63*7fd79137SRobert Mustacchi Dwarf_Small return_reg,
64*7fd79137SRobert Mustacchi Dwarf_Ptr init_bytes,
65*7fd79137SRobert Mustacchi Dwarf_Unsigned init_n_bytes, Dwarf_Error * error)
66*7fd79137SRobert Mustacchi {
67*7fd79137SRobert Mustacchi Dwarf_P_Cie curcie;
68*7fd79137SRobert Mustacchi
69*7fd79137SRobert Mustacchi if (dbg->de_frame_cies == NULL) {
70*7fd79137SRobert Mustacchi dbg->de_frame_cies = (Dwarf_P_Cie)
71*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
72*7fd79137SRobert Mustacchi if (dbg->de_frame_cies == NULL) {
73*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT);
74*7fd79137SRobert Mustacchi }
75*7fd79137SRobert Mustacchi curcie = dbg->de_frame_cies;
76*7fd79137SRobert Mustacchi dbg->de_n_cie = 1;
77*7fd79137SRobert Mustacchi dbg->de_last_cie = curcie;
78*7fd79137SRobert Mustacchi } else {
79*7fd79137SRobert Mustacchi curcie = dbg->de_last_cie;
80*7fd79137SRobert Mustacchi curcie->cie_next = (Dwarf_P_Cie)
81*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
82*7fd79137SRobert Mustacchi if (curcie->cie_next == NULL) {
83*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT);
84*7fd79137SRobert Mustacchi }
85*7fd79137SRobert Mustacchi curcie = curcie->cie_next;
86*7fd79137SRobert Mustacchi dbg->de_n_cie++;
87*7fd79137SRobert Mustacchi dbg->de_last_cie = curcie;
88*7fd79137SRobert Mustacchi }
89*7fd79137SRobert Mustacchi curcie->cie_version = DW_CIE_VERSION;
90*7fd79137SRobert Mustacchi curcie->cie_aug = augmenter;
91*7fd79137SRobert Mustacchi curcie->cie_code_align = code_align;
92*7fd79137SRobert Mustacchi curcie->cie_data_align = data_align;
93*7fd79137SRobert Mustacchi curcie->cie_ret_reg = return_reg;
94*7fd79137SRobert Mustacchi curcie->cie_inst = (char *) init_bytes;
95*7fd79137SRobert Mustacchi curcie->cie_inst_bytes = (long) init_n_bytes;
96*7fd79137SRobert Mustacchi curcie->cie_next = NULL;
97*7fd79137SRobert Mustacchi return dbg->de_n_cie;
98*7fd79137SRobert Mustacchi }
99*7fd79137SRobert Mustacchi
100*7fd79137SRobert Mustacchi
101*7fd79137SRobert Mustacchi /*-------------------------------------------------------------------------
102*7fd79137SRobert Mustacchi This functions adds a fde struct to the debug pointer. Its in the
103*7fd79137SRobert Mustacchi form of a linked list.
104*7fd79137SRobert Mustacchi die: subprogram/function die corresponding to this fde
105*7fd79137SRobert Mustacchi cie: cie referred to by this fde, obtained from call to
106*7fd79137SRobert Mustacchi add_frame_cie() routine.
107*7fd79137SRobert Mustacchi virt_addr: beginning address
108*7fd79137SRobert Mustacchi code_len: length of code reps by the fde
109*7fd79137SRobert Mustacchi --------------------------------------------------------------------------*/
110*7fd79137SRobert Mustacchi /*ARGSUSED*/ /* pretend all args used */
111*7fd79137SRobert Mustacchi Dwarf_Unsigned
dwarf_add_frame_fde(Dwarf_P_Debug dbg,Dwarf_P_Fde fde,Dwarf_P_Die die,Dwarf_Unsigned cie,Dwarf_Unsigned virt_addr,Dwarf_Unsigned code_len,Dwarf_Unsigned symidx,Dwarf_Error * error)112*7fd79137SRobert Mustacchi dwarf_add_frame_fde(Dwarf_P_Debug dbg,
113*7fd79137SRobert Mustacchi Dwarf_P_Fde fde,
114*7fd79137SRobert Mustacchi Dwarf_P_Die die,
115*7fd79137SRobert Mustacchi Dwarf_Unsigned cie,
116*7fd79137SRobert Mustacchi Dwarf_Unsigned virt_addr,
117*7fd79137SRobert Mustacchi Dwarf_Unsigned code_len,
118*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx, Dwarf_Error * error)
119*7fd79137SRobert Mustacchi {
120*7fd79137SRobert Mustacchi return dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr,
121*7fd79137SRobert Mustacchi code_len, symidx, 0, 0, error);
122*7fd79137SRobert Mustacchi }
123*7fd79137SRobert Mustacchi
124*7fd79137SRobert Mustacchi /*ARGSUSED10*/
125*7fd79137SRobert Mustacchi Dwarf_Unsigned
dwarf_add_frame_fde_b(Dwarf_P_Debug dbg,Dwarf_P_Fde fde,Dwarf_P_Die die,Dwarf_Unsigned cie,Dwarf_Unsigned virt_addr,Dwarf_Unsigned code_len,Dwarf_Unsigned symidx,Dwarf_Unsigned symidx_of_end,Dwarf_Addr offset_from_end_sym,Dwarf_Error * error)126*7fd79137SRobert Mustacchi dwarf_add_frame_fde_b(Dwarf_P_Debug dbg,
127*7fd79137SRobert Mustacchi Dwarf_P_Fde fde,
128*7fd79137SRobert Mustacchi Dwarf_P_Die die,
129*7fd79137SRobert Mustacchi Dwarf_Unsigned cie,
130*7fd79137SRobert Mustacchi Dwarf_Unsigned virt_addr,
131*7fd79137SRobert Mustacchi Dwarf_Unsigned code_len,
132*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx,
133*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx_of_end,
134*7fd79137SRobert Mustacchi Dwarf_Addr offset_from_end_sym,
135*7fd79137SRobert Mustacchi Dwarf_Error * error)
136*7fd79137SRobert Mustacchi {
137*7fd79137SRobert Mustacchi Dwarf_P_Fde curfde;
138*7fd79137SRobert Mustacchi
139*7fd79137SRobert Mustacchi fde->fde_die = die;
140*7fd79137SRobert Mustacchi fde->fde_cie = (long) cie;
141*7fd79137SRobert Mustacchi fde->fde_initloc = virt_addr;
142*7fd79137SRobert Mustacchi fde->fde_r_symidx = symidx;
143*7fd79137SRobert Mustacchi fde->fde_addr_range = code_len;
144*7fd79137SRobert Mustacchi fde->fde_offset_into_exception_tables = DW_DLX_NO_EH_OFFSET;
145*7fd79137SRobert Mustacchi fde->fde_exception_table_symbol = 0;
146*7fd79137SRobert Mustacchi fde->fde_end_symbol_offset = offset_from_end_sym;
147*7fd79137SRobert Mustacchi fde->fde_end_symbol = symidx_of_end;
148*7fd79137SRobert Mustacchi fde->fde_dbg = dbg;
149*7fd79137SRobert Mustacchi
150*7fd79137SRobert Mustacchi curfde = dbg->de_last_fde;
151*7fd79137SRobert Mustacchi if (curfde == NULL) {
152*7fd79137SRobert Mustacchi dbg->de_frame_fdes = fde;
153*7fd79137SRobert Mustacchi dbg->de_last_fde = fde;
154*7fd79137SRobert Mustacchi dbg->de_n_fde = 1;
155*7fd79137SRobert Mustacchi } else {
156*7fd79137SRobert Mustacchi curfde->fde_next = fde;
157*7fd79137SRobert Mustacchi dbg->de_last_fde = fde;
158*7fd79137SRobert Mustacchi dbg->de_n_fde++;
159*7fd79137SRobert Mustacchi }
160*7fd79137SRobert Mustacchi return dbg->de_n_fde;
161*7fd79137SRobert Mustacchi }
162*7fd79137SRobert Mustacchi
163*7fd79137SRobert Mustacchi /*-------------------------------------------------------------------------
164*7fd79137SRobert Mustacchi This functions adds information to an fde. The fde is
165*7fd79137SRobert Mustacchi linked into the linked list of fde's maintained in the Dwarf_P_Debug
166*7fd79137SRobert Mustacchi structure.
167*7fd79137SRobert Mustacchi dbg: The debug descriptor.
168*7fd79137SRobert Mustacchi fde: The fde to be added.
169*7fd79137SRobert Mustacchi die: subprogram/function die corresponding to this fde
170*7fd79137SRobert Mustacchi cie: cie referred to by this fde, obtained from call to
171*7fd79137SRobert Mustacchi add_frame_cie() routine.
172*7fd79137SRobert Mustacchi virt_addr: beginning address
173*7fd79137SRobert Mustacchi code_len: length of code reps by the fde
174*7fd79137SRobert Mustacchi symidx: The symbol id of the symbol wrt to which relocation needs
175*7fd79137SRobert Mustacchi to be performed for 'virt_addr'.
176*7fd79137SRobert Mustacchi offset_into_exception_tables: The start of exception tables for
177*7fd79137SRobert Mustacchi this function (indicated as an offset into the exception
178*7fd79137SRobert Mustacchi tables). A value of -1 indicates that there is no exception
179*7fd79137SRobert Mustacchi table entries associated with this function.
180*7fd79137SRobert Mustacchi exception_table_symbol: The symbol id of the section for exception
181*7fd79137SRobert Mustacchi tables wrt to which the offset_into_exception_tables will
182*7fd79137SRobert Mustacchi be relocated.
183*7fd79137SRobert Mustacchi --------------------------------------------------------------------------*/
184*7fd79137SRobert Mustacchi Dwarf_Unsigned
dwarf_add_frame_info(Dwarf_P_Debug dbg,Dwarf_P_Fde fde,Dwarf_P_Die die,Dwarf_Unsigned cie,Dwarf_Unsigned virt_addr,Dwarf_Unsigned code_len,Dwarf_Unsigned symidx,Dwarf_Signed offset_into_exception_tables,Dwarf_Unsigned exception_table_symbol,Dwarf_Error * error)185*7fd79137SRobert Mustacchi dwarf_add_frame_info(Dwarf_P_Debug dbg,
186*7fd79137SRobert Mustacchi Dwarf_P_Fde fde,
187*7fd79137SRobert Mustacchi Dwarf_P_Die die,
188*7fd79137SRobert Mustacchi Dwarf_Unsigned cie,
189*7fd79137SRobert Mustacchi Dwarf_Unsigned virt_addr,
190*7fd79137SRobert Mustacchi Dwarf_Unsigned code_len,
191*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx,
192*7fd79137SRobert Mustacchi Dwarf_Signed offset_into_exception_tables,
193*7fd79137SRobert Mustacchi Dwarf_Unsigned exception_table_symbol,
194*7fd79137SRobert Mustacchi Dwarf_Error * error)
195*7fd79137SRobert Mustacchi {
196*7fd79137SRobert Mustacchi
197*7fd79137SRobert Mustacchi return dwarf_add_frame_info_b(dbg, fde, die, cie, virt_addr,
198*7fd79137SRobert Mustacchi code_len, symidx,
199*7fd79137SRobert Mustacchi /* end_symbol */ 0,
200*7fd79137SRobert Mustacchi /* offset_from_end */ 0,
201*7fd79137SRobert Mustacchi offset_into_exception_tables,
202*7fd79137SRobert Mustacchi exception_table_symbol, error);
203*7fd79137SRobert Mustacchi
204*7fd79137SRobert Mustacchi }
205*7fd79137SRobert Mustacchi
206*7fd79137SRobert Mustacchi /*ARGSUSED*/ /* pretend all args used */
207*7fd79137SRobert Mustacchi Dwarf_Unsigned
dwarf_add_frame_info_b(Dwarf_P_Debug dbg,Dwarf_P_Fde fde,Dwarf_P_Die die,Dwarf_Unsigned cie,Dwarf_Unsigned virt_addr,Dwarf_Unsigned code_len,Dwarf_Unsigned symidx,Dwarf_Unsigned end_symidx,Dwarf_Unsigned offset_from_end_symbol,Dwarf_Signed offset_into_exception_tables,Dwarf_Unsigned exception_table_symbol,Dwarf_Error * error)208*7fd79137SRobert Mustacchi dwarf_add_frame_info_b(Dwarf_P_Debug dbg,
209*7fd79137SRobert Mustacchi Dwarf_P_Fde fde,
210*7fd79137SRobert Mustacchi Dwarf_P_Die die,
211*7fd79137SRobert Mustacchi Dwarf_Unsigned cie,
212*7fd79137SRobert Mustacchi Dwarf_Unsigned virt_addr,
213*7fd79137SRobert Mustacchi Dwarf_Unsigned code_len,
214*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx,
215*7fd79137SRobert Mustacchi Dwarf_Unsigned end_symidx,
216*7fd79137SRobert Mustacchi Dwarf_Unsigned offset_from_end_symbol,
217*7fd79137SRobert Mustacchi Dwarf_Signed offset_into_exception_tables,
218*7fd79137SRobert Mustacchi Dwarf_Unsigned exception_table_symbol,
219*7fd79137SRobert Mustacchi Dwarf_Error * error)
220*7fd79137SRobert Mustacchi {
221*7fd79137SRobert Mustacchi Dwarf_P_Fde curfde;
222*7fd79137SRobert Mustacchi
223*7fd79137SRobert Mustacchi fde->fde_die = die;
224*7fd79137SRobert Mustacchi fde->fde_cie = (long) cie;
225*7fd79137SRobert Mustacchi fde->fde_initloc = virt_addr;
226*7fd79137SRobert Mustacchi fde->fde_r_symidx = symidx;
227*7fd79137SRobert Mustacchi fde->fde_addr_range = code_len;
228*7fd79137SRobert Mustacchi fde->fde_offset_into_exception_tables =
229*7fd79137SRobert Mustacchi offset_into_exception_tables;
230*7fd79137SRobert Mustacchi fde->fde_exception_table_symbol = exception_table_symbol;
231*7fd79137SRobert Mustacchi fde->fde_end_symbol_offset = offset_from_end_symbol;
232*7fd79137SRobert Mustacchi fde->fde_end_symbol = end_symidx;
233*7fd79137SRobert Mustacchi fde->fde_dbg = dbg;
234*7fd79137SRobert Mustacchi
235*7fd79137SRobert Mustacchi curfde = dbg->de_last_fde;
236*7fd79137SRobert Mustacchi if (curfde == NULL) {
237*7fd79137SRobert Mustacchi dbg->de_frame_fdes = fde;
238*7fd79137SRobert Mustacchi dbg->de_last_fde = fde;
239*7fd79137SRobert Mustacchi dbg->de_n_fde = 1;
240*7fd79137SRobert Mustacchi } else {
241*7fd79137SRobert Mustacchi curfde->fde_next = fde;
242*7fd79137SRobert Mustacchi dbg->de_last_fde = fde;
243*7fd79137SRobert Mustacchi dbg->de_n_fde++;
244*7fd79137SRobert Mustacchi }
245*7fd79137SRobert Mustacchi return dbg->de_n_fde;
246*7fd79137SRobert Mustacchi }
247*7fd79137SRobert Mustacchi
248*7fd79137SRobert Mustacchi /* This is an alternate to inserting frame instructions
249*7fd79137SRobert Mustacchi one instruction at a time. But use either this
250*7fd79137SRobert Mustacchi or instruction level, not both in one fde. */
251*7fd79137SRobert Mustacchi int
dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg,Dwarf_P_Fde fde,Dwarf_Unsigned len,Dwarf_Ptr ibytes,Dwarf_Error * error)252*7fd79137SRobert Mustacchi dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg,
253*7fd79137SRobert Mustacchi Dwarf_P_Fde fde,Dwarf_Unsigned len, Dwarf_Ptr ibytes,
254*7fd79137SRobert Mustacchi Dwarf_Error *error)
255*7fd79137SRobert Mustacchi {
256*7fd79137SRobert Mustacchi if( len == 0) {
257*7fd79137SRobert Mustacchi return DW_DLV_OK;
258*7fd79137SRobert Mustacchi }
259*7fd79137SRobert Mustacchi if(fde->fde_block || fde->fde_inst) {
260*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DUPLICATE_INST_BLOCK,
261*7fd79137SRobert Mustacchi (int)DW_DLV_BADADDR);
262*7fd79137SRobert Mustacchi }
263*7fd79137SRobert Mustacchi fde->fde_block = (Dwarf_Ptr)_dwarf_p_get_alloc(dbg, len);
264*7fd79137SRobert Mustacchi memcpy(fde->fde_block,ibytes,len);
265*7fd79137SRobert Mustacchi fde->fde_inst_block_size = len;
266*7fd79137SRobert Mustacchi fde->fde_n_bytes += len;
267*7fd79137SRobert Mustacchi return DW_DLV_OK;
268*7fd79137SRobert Mustacchi }
269*7fd79137SRobert Mustacchi
270*7fd79137SRobert Mustacchi
271*7fd79137SRobert Mustacchi
272*7fd79137SRobert Mustacchi /*-------------------------------------------------------------------
273*7fd79137SRobert Mustacchi Create a new fde.
274*7fd79137SRobert Mustacchi ---------------------------------------------------------------------*/
275*7fd79137SRobert Mustacchi Dwarf_P_Fde
dwarf_new_fde(Dwarf_P_Debug dbg,Dwarf_Error * error)276*7fd79137SRobert Mustacchi dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error)
277*7fd79137SRobert Mustacchi {
278*7fd79137SRobert Mustacchi Dwarf_P_Fde fde;
279*7fd79137SRobert Mustacchi
280*7fd79137SRobert Mustacchi fde = (Dwarf_P_Fde)
281*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s));
282*7fd79137SRobert Mustacchi if (fde == NULL) {
283*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC,
284*7fd79137SRobert Mustacchi (Dwarf_P_Fde) DW_DLV_BADADDR);
285*7fd79137SRobert Mustacchi }
286*7fd79137SRobert Mustacchi
287*7fd79137SRobert Mustacchi fde->fde_uwordb_size = dbg->de_offset_size;
288*7fd79137SRobert Mustacchi
289*7fd79137SRobert Mustacchi return fde;
290*7fd79137SRobert Mustacchi }
291*7fd79137SRobert Mustacchi
292*7fd79137SRobert Mustacchi
293*7fd79137SRobert Mustacchi /*------------------------------------------------------------------------
294*7fd79137SRobert Mustacchi Add a cfe_offset instruction to the fde passed in.
295*7fd79137SRobert Mustacchi -------------------------------------------------------------------------*/
296*7fd79137SRobert Mustacchi Dwarf_P_Fde
dwarf_fde_cfa_offset(Dwarf_P_Fde fde,Dwarf_Unsigned reg,Dwarf_Signed offset,Dwarf_Error * error)297*7fd79137SRobert Mustacchi dwarf_fde_cfa_offset(Dwarf_P_Fde fde,
298*7fd79137SRobert Mustacchi Dwarf_Unsigned reg,
299*7fd79137SRobert Mustacchi Dwarf_Signed offset, Dwarf_Error * error)
300*7fd79137SRobert Mustacchi {
301*7fd79137SRobert Mustacchi Dwarf_Ubyte opc, regno;
302*7fd79137SRobert Mustacchi char *ptr;
303*7fd79137SRobert Mustacchi Dwarf_P_Frame_Pgm curinst;
304*7fd79137SRobert Mustacchi int nbytes;
305*7fd79137SRobert Mustacchi int res;
306*7fd79137SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED];
307*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg = fde->fde_dbg;
308*7fd79137SRobert Mustacchi
309*7fd79137SRobert Mustacchi curinst = (Dwarf_P_Frame_Pgm)
310*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
311*7fd79137SRobert Mustacchi if (curinst == NULL) {
312*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC,
313*7fd79137SRobert Mustacchi (Dwarf_P_Fde) DW_DLV_BADADDR);
314*7fd79137SRobert Mustacchi }
315*7fd79137SRobert Mustacchi opc = DW_CFA_offset;
316*7fd79137SRobert Mustacchi regno = reg;
317*7fd79137SRobert Mustacchi if (regno & 0xc0) {
318*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,
319*7fd79137SRobert Mustacchi (Dwarf_P_Fde) DW_DLV_BADADDR);
320*7fd79137SRobert Mustacchi }
321*7fd79137SRobert Mustacchi opc = opc | regno; /* lower 6 bits are register number */
322*7fd79137SRobert Mustacchi curinst->dfp_opcode = opc;
323*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(offset, &nbytes,
324*7fd79137SRobert Mustacchi buff1, sizeof(buff1));
325*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
326*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
327*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
328*7fd79137SRobert Mustacchi }
329*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
330*7fd79137SRobert Mustacchi if (ptr == NULL) {
331*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
332*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
333*7fd79137SRobert Mustacchi }
334*7fd79137SRobert Mustacchi memcpy(ptr, buff1, nbytes);
335*7fd79137SRobert Mustacchi
336*7fd79137SRobert Mustacchi curinst->dfp_args = ptr;
337*7fd79137SRobert Mustacchi curinst->dfp_nbytes = nbytes;
338*7fd79137SRobert Mustacchi curinst->dfp_next = NULL;
339*7fd79137SRobert Mustacchi
340*7fd79137SRobert Mustacchi _dwarf_pro_add_to_fde(fde, curinst);
341*7fd79137SRobert Mustacchi return fde;
342*7fd79137SRobert Mustacchi }
343*7fd79137SRobert Mustacchi
344*7fd79137SRobert Mustacchi /*
345*7fd79137SRobert Mustacchi Generic routine to add opcode to fde instructions. val1 and
346*7fd79137SRobert Mustacchi val2 are parameters whose interpretation depends on the 'op'.
347*7fd79137SRobert Mustacchi
348*7fd79137SRobert Mustacchi This does not work properly for DW_DLC_SYMBOLIC_RELOCATIONS
349*7fd79137SRobert Mustacchi for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as
350*7fd79137SRobert Mustacchi these ops normally are addresses or (DW_CFA_set_loc)
351*7fd79137SRobert Mustacchi or code lengths (DW_DVA_advance_loc*) and such must be
352*7fd79137SRobert Mustacchi represented with relocations and symbol indices for
353*7fd79137SRobert Mustacchi DW_DLC_SYMBOLIC_RELOCATIONS.
354*7fd79137SRobert Mustacchi
355*7fd79137SRobert Mustacchi This does not treat all DW_CFA instructions yet.
356*7fd79137SRobert Mustacchi
357*7fd79137SRobert Mustacchi For certain operations a val? value must be
358*7fd79137SRobert Mustacchi signed (though passed in as unsigned here).
359*7fd79137SRobert Mustacchi
360*7fd79137SRobert Mustacchi Currently this does not check that the frame
361*7fd79137SRobert Mustacchi version is 3(for dwarf3) or 4 (for dwarf4)
362*7fd79137SRobert Mustacchi when applying operations that are only valid for
363*7fd79137SRobert Mustacchi dwarf3 or dwarf4.
364*7fd79137SRobert Mustacchi
365*7fd79137SRobert Mustacchi */
366*7fd79137SRobert Mustacchi Dwarf_P_Fde
dwarf_add_fde_inst(Dwarf_P_Fde fde,Dwarf_Small op,Dwarf_Unsigned val1,Dwarf_Unsigned val2,Dwarf_Error * error)367*7fd79137SRobert Mustacchi dwarf_add_fde_inst(Dwarf_P_Fde fde,
368*7fd79137SRobert Mustacchi Dwarf_Small op,
369*7fd79137SRobert Mustacchi Dwarf_Unsigned val1,
370*7fd79137SRobert Mustacchi Dwarf_Unsigned val2, Dwarf_Error * error)
371*7fd79137SRobert Mustacchi {
372*7fd79137SRobert Mustacchi Dwarf_P_Frame_Pgm curinst;
373*7fd79137SRobert Mustacchi int nbytes, nbytes1, nbytes2;
374*7fd79137SRobert Mustacchi Dwarf_Ubyte db;
375*7fd79137SRobert Mustacchi Dwarf_Half dh;
376*7fd79137SRobert Mustacchi Dwarf_Word dw;
377*7fd79137SRobert Mustacchi Dwarf_Unsigned du;
378*7fd79137SRobert Mustacchi char *ptr;
379*7fd79137SRobert Mustacchi int res;
380*7fd79137SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED];
381*7fd79137SRobert Mustacchi char buff2[ENCODE_SPACE_NEEDED];
382*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg = fde->fde_dbg;
383*7fd79137SRobert Mustacchi /* This is a hack telling the code when to transform
384*7fd79137SRobert Mustacchi a value to a signed leb number. */
385*7fd79137SRobert Mustacchi int signed_second = 0;
386*7fd79137SRobert Mustacchi int signed_first = 0;
387*7fd79137SRobert Mustacchi
388*7fd79137SRobert Mustacchi
389*7fd79137SRobert Mustacchi nbytes = 0;
390*7fd79137SRobert Mustacchi ptr = NULL;
391*7fd79137SRobert Mustacchi curinst = (Dwarf_P_Frame_Pgm)
392*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
393*7fd79137SRobert Mustacchi if (curinst == NULL) {
394*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC);
395*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
396*7fd79137SRobert Mustacchi }
397*7fd79137SRobert Mustacchi
398*7fd79137SRobert Mustacchi switch (op) {
399*7fd79137SRobert Mustacchi
400*7fd79137SRobert Mustacchi case DW_CFA_advance_loc:
401*7fd79137SRobert Mustacchi if (val1 <= 0x3f) {
402*7fd79137SRobert Mustacchi db = val1;
403*7fd79137SRobert Mustacchi op |= db;
404*7fd79137SRobert Mustacchi }
405*7fd79137SRobert Mustacchi /* test not portable FIX */
406*7fd79137SRobert Mustacchi else if (val1 <= UCHAR_MAX) {
407*7fd79137SRobert Mustacchi op = DW_CFA_advance_loc1;
408*7fd79137SRobert Mustacchi db = val1;
409*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, 1);
410*7fd79137SRobert Mustacchi if (ptr == NULL) {
411*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
412*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
413*7fd79137SRobert Mustacchi }
414*7fd79137SRobert Mustacchi memcpy((void *) ptr, (const void *) &db, 1);
415*7fd79137SRobert Mustacchi nbytes = 1;
416*7fd79137SRobert Mustacchi }
417*7fd79137SRobert Mustacchi /* test not portable FIX */
418*7fd79137SRobert Mustacchi else if (val1 <= USHRT_MAX) {
419*7fd79137SRobert Mustacchi op = DW_CFA_advance_loc2;
420*7fd79137SRobert Mustacchi dh = val1;
421*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, 2);
422*7fd79137SRobert Mustacchi if (ptr == NULL) {
423*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
424*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
425*7fd79137SRobert Mustacchi }
426*7fd79137SRobert Mustacchi memcpy((void *) ptr, (const void *) &dh, 2);
427*7fd79137SRobert Mustacchi nbytes = 2;
428*7fd79137SRobert Mustacchi }
429*7fd79137SRobert Mustacchi /* test not portable FIX */
430*7fd79137SRobert Mustacchi else if (val1 <= ULONG_MAX) {
431*7fd79137SRobert Mustacchi op = DW_CFA_advance_loc4;
432*7fd79137SRobert Mustacchi dw = (Dwarf_Word) val1;
433*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, 4);
434*7fd79137SRobert Mustacchi if (ptr == NULL) {
435*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
436*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
437*7fd79137SRobert Mustacchi }
438*7fd79137SRobert Mustacchi memcpy((void *) ptr, (const void *) &dw, 4);
439*7fd79137SRobert Mustacchi nbytes = 4;
440*7fd79137SRobert Mustacchi } else {
441*7fd79137SRobert Mustacchi op = DW_CFA_MIPS_advance_loc8;
442*7fd79137SRobert Mustacchi du = val1;
443*7fd79137SRobert Mustacchi ptr =
444*7fd79137SRobert Mustacchi (char *) _dwarf_p_get_alloc(dbg,
445*7fd79137SRobert Mustacchi sizeof(Dwarf_Unsigned));
446*7fd79137SRobert Mustacchi if (ptr == NULL) {
447*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
448*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
449*7fd79137SRobert Mustacchi }
450*7fd79137SRobert Mustacchi memcpy((void *) ptr, (const void *) &du, 8);
451*7fd79137SRobert Mustacchi nbytes = 8;
452*7fd79137SRobert Mustacchi }
453*7fd79137SRobert Mustacchi break;
454*7fd79137SRobert Mustacchi
455*7fd79137SRobert Mustacchi case DW_CFA_offset:
456*7fd79137SRobert Mustacchi if (val1 <= MAX_6_BIT_VALUE) {
457*7fd79137SRobert Mustacchi db = val1;
458*7fd79137SRobert Mustacchi op |= db;
459*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val2, &nbytes,
460*7fd79137SRobert Mustacchi buff1, sizeof(buff1));
461*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
462*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
463*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
464*7fd79137SRobert Mustacchi }
465*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
466*7fd79137SRobert Mustacchi if (ptr == NULL) {
467*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
468*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
469*7fd79137SRobert Mustacchi }
470*7fd79137SRobert Mustacchi memcpy(ptr, buff1, nbytes);
471*7fd79137SRobert Mustacchi
472*7fd79137SRobert Mustacchi } else {
473*7fd79137SRobert Mustacchi op = DW_CFA_offset_extended;
474*7fd79137SRobert Mustacchi goto two_leb;
475*7fd79137SRobert Mustacchi }
476*7fd79137SRobert Mustacchi break;
477*7fd79137SRobert Mustacchi case DW_CFA_offset_extended_sf: /* DWARF3 */
478*7fd79137SRobert Mustacchi signed_second = 1;
479*7fd79137SRobert Mustacchi goto two_leb;
480*7fd79137SRobert Mustacchi case DW_CFA_offset_extended:
481*7fd79137SRobert Mustacchi goto two_leb;
482*7fd79137SRobert Mustacchi
483*7fd79137SRobert Mustacchi case DW_CFA_undefined:
484*7fd79137SRobert Mustacchi case DW_CFA_same_value:
485*7fd79137SRobert Mustacchi goto one_leb;
486*7fd79137SRobert Mustacchi
487*7fd79137SRobert Mustacchi case DW_CFA_val_offset:
488*7fd79137SRobert Mustacchi goto two_leb;
489*7fd79137SRobert Mustacchi case DW_CFA_val_offset_sf:
490*7fd79137SRobert Mustacchi signed_second = 1;
491*7fd79137SRobert Mustacchi goto two_leb;
492*7fd79137SRobert Mustacchi case DW_CFA_def_cfa_sf:
493*7fd79137SRobert Mustacchi signed_second = 1;
494*7fd79137SRobert Mustacchi goto two_leb;
495*7fd79137SRobert Mustacchi case DW_CFA_register:
496*7fd79137SRobert Mustacchi case DW_CFA_def_cfa:
497*7fd79137SRobert Mustacchi two_leb:
498*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
499*7fd79137SRobert Mustacchi buff1, sizeof(buff1));
500*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
501*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
502*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
503*7fd79137SRobert Mustacchi }
504*7fd79137SRobert Mustacchi if (!signed_second) {
505*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
506*7fd79137SRobert Mustacchi buff2, sizeof(buff2));
507*7fd79137SRobert Mustacchi } else {
508*7fd79137SRobert Mustacchi Dwarf_Signed val2s = val2;
509*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(val2s, &nbytes2,
510*7fd79137SRobert Mustacchi buff2, sizeof(buff2));
511*7fd79137SRobert Mustacchi }
512*7fd79137SRobert Mustacchi
513*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
514*7fd79137SRobert Mustacchi buff2, sizeof(buff2));
515*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
516*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
517*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
518*7fd79137SRobert Mustacchi }
519*7fd79137SRobert Mustacchi
520*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2);
521*7fd79137SRobert Mustacchi if (ptr == NULL) {
522*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
523*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
524*7fd79137SRobert Mustacchi }
525*7fd79137SRobert Mustacchi memcpy(ptr, buff1, nbytes1);
526*7fd79137SRobert Mustacchi memcpy(ptr + nbytes1, buff2, nbytes2);
527*7fd79137SRobert Mustacchi nbytes = nbytes1 + nbytes2;
528*7fd79137SRobert Mustacchi break;
529*7fd79137SRobert Mustacchi
530*7fd79137SRobert Mustacchi case DW_CFA_def_cfa_offset_sf: /* DWARF3 */
531*7fd79137SRobert Mustacchi signed_first = 1;
532*7fd79137SRobert Mustacchi goto one_leb;
533*7fd79137SRobert Mustacchi case DW_CFA_def_cfa_register:
534*7fd79137SRobert Mustacchi case DW_CFA_def_cfa_offset:
535*7fd79137SRobert Mustacchi one_leb:
536*7fd79137SRobert Mustacchi if(!signed_first) {
537*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
538*7fd79137SRobert Mustacchi buff1, sizeof(buff1));
539*7fd79137SRobert Mustacchi } else {
540*7fd79137SRobert Mustacchi Dwarf_Signed val1s = val1;
541*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(val1s, &nbytes,
542*7fd79137SRobert Mustacchi buff1, sizeof(buff1));
543*7fd79137SRobert Mustacchi }
544*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
545*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
546*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
547*7fd79137SRobert Mustacchi }
548*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
549*7fd79137SRobert Mustacchi if (ptr == NULL) {
550*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
551*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
552*7fd79137SRobert Mustacchi }
553*7fd79137SRobert Mustacchi memcpy(ptr, buff1, nbytes);
554*7fd79137SRobert Mustacchi break;
555*7fd79137SRobert Mustacchi case DW_CFA_def_cfa_expression: /* DWARF3 */
556*7fd79137SRobert Mustacchi /* FIXME: argument is dwarf expr, not handled yet. */
557*7fd79137SRobert Mustacchi case DW_CFA_expression: /* DWARF3 */
558*7fd79137SRobert Mustacchi /* First arg: ULEB reg num. 2nd arg dwarf expr in form block.
559*7fd79137SRobert Mustacchi FIXME: not handled yet. */
560*7fd79137SRobert Mustacchi case DW_CFA_val_expression: /* DWARF3f */
561*7fd79137SRobert Mustacchi /* First arg: ULEB reg num. 2nd arg dwarf expr in form block.
562*7fd79137SRobert Mustacchi FIXME: not handled yet. */
563*7fd79137SRobert Mustacchi default:
564*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR);
565*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR);
566*7fd79137SRobert Mustacchi }
567*7fd79137SRobert Mustacchi
568*7fd79137SRobert Mustacchi curinst->dfp_opcode = op;
569*7fd79137SRobert Mustacchi curinst->dfp_args = ptr;
570*7fd79137SRobert Mustacchi curinst->dfp_nbytes = nbytes;
571*7fd79137SRobert Mustacchi curinst->dfp_next = NULL;
572*7fd79137SRobert Mustacchi
573*7fd79137SRobert Mustacchi _dwarf_pro_add_to_fde(fde, curinst);
574*7fd79137SRobert Mustacchi return fde;
575*7fd79137SRobert Mustacchi }
576*7fd79137SRobert Mustacchi
577*7fd79137SRobert Mustacchi
578*7fd79137SRobert Mustacchi /*------------------------------------------------------------------------
579*7fd79137SRobert Mustacchi Instructions are added to an fde in the form of a linked
580*7fd79137SRobert Mustacchi list. This function manages the linked list.
581*7fd79137SRobert Mustacchi -------------------------------------------------------------------------*/
582*7fd79137SRobert Mustacchi void
_dwarf_pro_add_to_fde(Dwarf_P_Fde fde,Dwarf_P_Frame_Pgm curinst)583*7fd79137SRobert Mustacchi _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst)
584*7fd79137SRobert Mustacchi {
585*7fd79137SRobert Mustacchi if (fde->fde_last_inst) {
586*7fd79137SRobert Mustacchi fde->fde_last_inst->dfp_next = curinst;
587*7fd79137SRobert Mustacchi fde->fde_last_inst = curinst;
588*7fd79137SRobert Mustacchi fde->fde_n_inst++;
589*7fd79137SRobert Mustacchi fde->fde_n_bytes +=
590*7fd79137SRobert Mustacchi (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
591*7fd79137SRobert Mustacchi } else {
592*7fd79137SRobert Mustacchi fde->fde_last_inst = curinst;
593*7fd79137SRobert Mustacchi fde->fde_inst = curinst;
594*7fd79137SRobert Mustacchi fde->fde_n_inst = 1;
595*7fd79137SRobert Mustacchi fde->fde_n_bytes =
596*7fd79137SRobert Mustacchi (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
597*7fd79137SRobert Mustacchi }
598*7fd79137SRobert Mustacchi }
599