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