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