xref: /illumos-gate/usr/src/lib/libdwarf/common/pro_frame.c (revision bc1f688b4872ace323eaddbb1a6365d054e7bf56)
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 function 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 /* This is an alternate to inserting frame instructions
249    one instruction at a time.  But use either this
250    or instruction level, not both in one fde. */
251 int
252 dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg,
253     Dwarf_P_Fde fde,Dwarf_Unsigned len, Dwarf_Ptr ibytes,
254     Dwarf_Error *error)
255 {
256     if( len == 0) {
257         return DW_DLV_OK;
258     }
259     if(fde->fde_block || fde->fde_inst) {
260         DWARF_P_DBG_ERROR(dbg, DW_DLE_DUPLICATE_INST_BLOCK,
261             (int)DW_DLV_BADADDR);
262     }
263     fde->fde_block = (Dwarf_Ptr)_dwarf_p_get_alloc(dbg, len);
264     memcpy(fde->fde_block,ibytes,len);
265     fde->fde_inst_block_size = len;
266     fde->fde_n_bytes += len;
267     return DW_DLV_OK;
268 }
269 
270 
271 
272 /*-------------------------------------------------------------------
273         Create a new fde.
274 ---------------------------------------------------------------------*/
275 Dwarf_P_Fde
276 dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error)
277 {
278     Dwarf_P_Fde fde;
279 
280     fde = (Dwarf_P_Fde)
281         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s));
282     if (fde == NULL) {
283         DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC,
284                           (Dwarf_P_Fde) DW_DLV_BADADDR);
285     }
286 
287     fde->fde_uwordb_size = dbg->de_offset_size;
288 
289     return fde;
290 }
291 
292 
293 /*------------------------------------------------------------------------
294         Add a cfe_offset instruction to the fde passed in.
295 -------------------------------------------------------------------------*/
296 Dwarf_P_Fde
297 dwarf_fde_cfa_offset(Dwarf_P_Fde fde,
298                      Dwarf_Unsigned reg,
299                      Dwarf_Signed offset, Dwarf_Error * error)
300 {
301     Dwarf_Ubyte opc, regno;
302     char *ptr;
303     Dwarf_P_Frame_Pgm curinst;
304     int nbytes;
305     int res;
306     char buff1[ENCODE_SPACE_NEEDED];
307     Dwarf_P_Debug dbg = fde->fde_dbg;
308 
309     curinst = (Dwarf_P_Frame_Pgm)
310         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
311     if (curinst == NULL) {
312         DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC,
313                           (Dwarf_P_Fde) DW_DLV_BADADDR);
314     }
315     opc = DW_CFA_offset;
316     regno = reg;
317     if (regno & 0xc0) {
318         DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,
319                           (Dwarf_P_Fde) DW_DLV_BADADDR);
320     }
321     opc = opc | regno;          /* lower 6 bits are register number */
322     curinst->dfp_opcode = opc;
323     res = _dwarf_pro_encode_leb128_nm(offset, &nbytes,
324                                       buff1, sizeof(buff1));
325     if (res != DW_DLV_OK) {
326         _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
327         return ((Dwarf_P_Fde) DW_DLV_BADADDR);
328     }
329     ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
330     if (ptr == NULL) {
331         _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
332         return ((Dwarf_P_Fde) DW_DLV_BADADDR);
333     }
334     memcpy(ptr, buff1, nbytes);
335 
336     curinst->dfp_args = ptr;
337     curinst->dfp_nbytes = nbytes;
338     curinst->dfp_next = NULL;
339 
340     _dwarf_pro_add_to_fde(fde, curinst);
341     return fde;
342 }
343 
344 /*
345     Generic routine to add opcode to fde instructions. val1 and
346     val2 are parameters whose interpretation depends on the 'op'.
347 
348     This does not work properly for  DW_DLC_SYMBOLIC_RELOCATIONS
349     for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as
350     these ops normally are addresses or (DW_CFA_set_loc)
351     or code lengths (DW_DVA_advance_loc*) and such must be
352     represented with relocations and symbol indices for
353     DW_DLC_SYMBOLIC_RELOCATIONS.
354 
355     This does not treat all DW_CFA instructions yet.
356 
357     For certain operations a val? value must be
358     signed (though passed in as unsigned here).
359 
360     Currently this does not check that the frame
361     version is 3(for dwarf3) or 4 (for dwarf4)
362     when applying operations that are only valid for
363     dwarf3 or dwarf4.
364 
365 */
366 Dwarf_P_Fde
367 dwarf_add_fde_inst(Dwarf_P_Fde fde,
368                    Dwarf_Small op,
369                    Dwarf_Unsigned val1,
370                    Dwarf_Unsigned val2, Dwarf_Error * error)
371 {
372     Dwarf_P_Frame_Pgm curinst;
373     int nbytes, nbytes1, nbytes2;
374     Dwarf_Ubyte db;
375     Dwarf_Half dh;
376     Dwarf_Word dw;
377     Dwarf_Unsigned du;
378     char *ptr;
379     int res;
380     char buff1[ENCODE_SPACE_NEEDED];
381     char buff2[ENCODE_SPACE_NEEDED];
382     Dwarf_P_Debug dbg = fde->fde_dbg;
383     /* This is a hack telling the code when to transform
384        a value to a signed leb number. */
385     int signed_second = 0;
386     int signed_first = 0;
387 
388 
389     nbytes = 0;
390     ptr = NULL;
391     curinst = (Dwarf_P_Frame_Pgm)
392         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
393     if (curinst == NULL) {
394         _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC);
395         return ((Dwarf_P_Fde) DW_DLV_BADADDR);
396     }
397 
398     switch (op) {
399 
400     case DW_CFA_advance_loc:
401         if (val1 <= 0x3f) {
402             db = val1;
403             op |= db;
404         }
405         /* test not portable FIX */
406         else if (val1 <= UCHAR_MAX) {
407             op = DW_CFA_advance_loc1;
408             db = val1;
409             ptr = (char *) _dwarf_p_get_alloc(dbg, 1);
410             if (ptr == NULL) {
411                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
412                 return ((Dwarf_P_Fde) DW_DLV_BADADDR);
413             }
414             memcpy((void *) ptr, (const void *) &db, 1);
415             nbytes = 1;
416         }
417         /* test not portable FIX */
418         else if (val1 <= USHRT_MAX) {
419             op = DW_CFA_advance_loc2;
420             dh = val1;
421             ptr = (char *) _dwarf_p_get_alloc(dbg, 2);
422             if (ptr == NULL) {
423                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
424                 return ((Dwarf_P_Fde) DW_DLV_BADADDR);
425             }
426             memcpy((void *) ptr, (const void *) &dh, 2);
427             nbytes = 2;
428         }
429         /* test not portable FIX */
430         else if (val1 <= ULONG_MAX) {
431             op = DW_CFA_advance_loc4;
432             dw = (Dwarf_Word) val1;
433             ptr = (char *) _dwarf_p_get_alloc(dbg, 4);
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((void *) ptr, (const void *) &dw, 4);
439             nbytes = 4;
440         } else {
441             op = DW_CFA_MIPS_advance_loc8;
442             du = val1;
443             ptr =
444                 (char *) _dwarf_p_get_alloc(dbg,
445                                             sizeof(Dwarf_Unsigned));
446             if (ptr == NULL) {
447                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
448                 return ((Dwarf_P_Fde) DW_DLV_BADADDR);
449             }
450             memcpy((void *) ptr, (const void *) &du, 8);
451             nbytes = 8;
452         }
453         break;
454 
455     case DW_CFA_offset:
456         if (val1 <= MAX_6_BIT_VALUE) {
457             db = val1;
458             op |= db;
459             res = _dwarf_pro_encode_leb128_nm(val2, &nbytes,
460                                               buff1, sizeof(buff1));
461             if (res != DW_DLV_OK) {
462                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
463                 return ((Dwarf_P_Fde) DW_DLV_BADADDR);
464             }
465             ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
466             if (ptr == NULL) {
467                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
468                 return ((Dwarf_P_Fde) DW_DLV_BADADDR);
469             }
470             memcpy(ptr, buff1, nbytes);
471 
472         } else {
473             op = DW_CFA_offset_extended;
474             goto two_leb;
475         }
476         break;
477     case DW_CFA_offset_extended_sf: /* DWARF3 */
478             signed_second = 1;
479             goto two_leb;
480     case DW_CFA_offset_extended:
481             goto two_leb;
482 
483     case DW_CFA_undefined:
484     case DW_CFA_same_value:
485         goto one_leb;
486 
487     case DW_CFA_val_offset:
488          goto two_leb;
489     case DW_CFA_val_offset_sf:
490          signed_second = 1;
491          goto two_leb;
492     case DW_CFA_def_cfa_sf:
493          signed_second = 1;
494          goto two_leb;
495     case DW_CFA_register:
496     case DW_CFA_def_cfa:
497     two_leb:
498         res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
499                                           buff1, sizeof(buff1));
500         if (res != DW_DLV_OK) {
501             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
502             return ((Dwarf_P_Fde) DW_DLV_BADADDR);
503         }
504         if (!signed_second) {
505                 res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
506                                               buff2, sizeof(buff2));
507         } else {
508             Dwarf_Signed val2s = val2;
509             res = _dwarf_pro_encode_signed_leb128_nm(val2s, &nbytes2,
510                                               buff2, sizeof(buff2));
511         }
512 
513         res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
514                                           buff2, sizeof(buff2));
515         if (res != DW_DLV_OK) {
516             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
517             return ((Dwarf_P_Fde) DW_DLV_BADADDR);
518         }
519 
520         ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2);
521         if (ptr == NULL) {
522             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
523             return ((Dwarf_P_Fde) DW_DLV_BADADDR);
524         }
525         memcpy(ptr, buff1, nbytes1);
526         memcpy(ptr + nbytes1, buff2, nbytes2);
527         nbytes = nbytes1 + nbytes2;
528         break;
529 
530     case DW_CFA_def_cfa_offset_sf: /* DWARF3 */
531         signed_first = 1;
532         goto one_leb;
533     case DW_CFA_def_cfa_register:
534     case DW_CFA_def_cfa_offset:
535     one_leb:
536         if(!signed_first) {
537             res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
538                                           buff1, sizeof(buff1));
539         } else {
540             Dwarf_Signed val1s = val1;
541             res = _dwarf_pro_encode_signed_leb128_nm(val1s, &nbytes,
542                                           buff1, sizeof(buff1));
543         }
544         if (res != DW_DLV_OK) {
545             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
546             return ((Dwarf_P_Fde) DW_DLV_BADADDR);
547         }
548         ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
549         if (ptr == NULL) {
550             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
551             return ((Dwarf_P_Fde) DW_DLV_BADADDR);
552         }
553         memcpy(ptr, buff1, nbytes);
554         break;
555     case DW_CFA_def_cfa_expression: /* DWARF3 */
556         /* FIXME: argument is dwarf expr, not handled yet. */
557     case DW_CFA_expression: /* DWARF3 */
558         /* First arg: ULEB reg num. 2nd arg dwarf expr in form block.
559            FIXME: not handled yet. */
560     case DW_CFA_val_expression: /* DWARF3f */
561         /* First arg: ULEB reg num. 2nd arg dwarf expr in form block.
562            FIXME: not handled yet. */
563     default:
564         _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR);
565         return ((Dwarf_P_Fde) DW_DLV_BADADDR);
566     }
567 
568     curinst->dfp_opcode = op;
569     curinst->dfp_args = ptr;
570     curinst->dfp_nbytes = nbytes;
571     curinst->dfp_next = NULL;
572 
573     _dwarf_pro_add_to_fde(fde, curinst);
574     return fde;
575 }
576 
577 
578 /*------------------------------------------------------------------------
579         Instructions are added to an fde in the form of a linked
580         list. This function manages the linked list.
581 -------------------------------------------------------------------------*/
582 void
583 _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst)
584 {
585     if (fde->fde_last_inst) {
586         fde->fde_last_inst->dfp_next = curinst;
587         fde->fde_last_inst = curinst;
588         fde->fde_n_inst++;
589         fde->fde_n_bytes +=
590             (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
591     } else {
592         fde->fde_last_inst = curinst;
593         fde->fde_inst = curinst;
594         fde->fde_n_inst = 1;
595         fde->fde_n_bytes =
596             (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
597     }
598 }
599