149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe 
307dc1947SRichard Lowe   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
4*4d9fdb46SRobert Mustacchi   Portions Copyright 2011-2017  David Anderson. All Rights Reserved.
5*4d9fdb46SRobert Mustacchi   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
6*4d9fdb46SRobert Mustacchi 
7*4d9fdb46SRobert Mustacchi   This program is free software; you can redistribute it
8*4d9fdb46SRobert Mustacchi   and/or modify it under the terms of version 2.1 of the
9*4d9fdb46SRobert Mustacchi   GNU Lesser General Public License as published by the Free
10*4d9fdb46SRobert Mustacchi   Software Foundation.
11*4d9fdb46SRobert Mustacchi 
12*4d9fdb46SRobert Mustacchi   This program is distributed in the hope that it would be
13*4d9fdb46SRobert Mustacchi   useful, but WITHOUT ANY WARRANTY; without even the implied
14*4d9fdb46SRobert Mustacchi   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15*4d9fdb46SRobert Mustacchi   PURPOSE.
16*4d9fdb46SRobert Mustacchi 
17*4d9fdb46SRobert Mustacchi   Further, this software is distributed without any warranty
18*4d9fdb46SRobert Mustacchi   that it is free of the rightful claim of any third person
19*4d9fdb46SRobert Mustacchi   regarding infringement or the like.  Any license provided
20*4d9fdb46SRobert Mustacchi   herein, whether implied or otherwise, applies only to this
21*4d9fdb46SRobert Mustacchi   software file.  Patent licenses, if any, provided herein
22*4d9fdb46SRobert Mustacchi   do not apply to combinations of this program with other
23*4d9fdb46SRobert Mustacchi   software, or any other product whatsoever.
24*4d9fdb46SRobert Mustacchi 
25*4d9fdb46SRobert Mustacchi   You should have received a copy of the GNU Lesser General
26*4d9fdb46SRobert Mustacchi   Public License along with this program; if not, write the
27*4d9fdb46SRobert Mustacchi   Free Software Foundation, Inc., 51 Franklin Street - Fifth
28*4d9fdb46SRobert Mustacchi   Floor, Boston MA 02110-1301, USA.
2949d3bc91SRichard Lowe 
3049d3bc91SRichard Lowe */
3149d3bc91SRichard Lowe 
3249d3bc91SRichard Lowe #include "config.h"
3349d3bc91SRichard Lowe #include "libdwarfdefs.h"
3449d3bc91SRichard Lowe #include <stdio.h>
3549d3bc91SRichard Lowe #include <string.h>
3649d3bc91SRichard Lowe #include <limits.h>
3749d3bc91SRichard Lowe #include "pro_incl.h"
38*4d9fdb46SRobert Mustacchi #include <stddef.h>
39*4d9fdb46SRobert Mustacchi #include "dwarf.h"
40*4d9fdb46SRobert Mustacchi #include "libdwarf.h"
41*4d9fdb46SRobert Mustacchi #include "pro_opaque.h"
42*4d9fdb46SRobert Mustacchi #include "pro_error.h"
43*4d9fdb46SRobert Mustacchi #include "pro_alloc.h"
44*4d9fdb46SRobert Mustacchi #include "pro_encode_nm.h"
4549d3bc91SRichard Lowe #include "pro_frame.h"
4649d3bc91SRichard Lowe 
47*4d9fdb46SRobert Mustacchi #define SIZEOFT16 2
48*4d9fdb46SRobert Mustacchi #define SIZEOFT32 4
49*4d9fdb46SRobert Mustacchi #define SIZEOFT64 8
50*4d9fdb46SRobert Mustacchi 
51*4d9fdb46SRobert Mustacchi #ifdef WORDS_BIGENDIAN
52*4d9fdb46SRobert Mustacchi #define ASNOUT(t,s,l)                       \
53*4d9fdb46SRobert Mustacchi     do {                                    \
54*4d9fdb46SRobert Mustacchi         unsigned sbyte = 0;                 \
55*4d9fdb46SRobert Mustacchi         const char *p = 0;                        \
56*4d9fdb46SRobert Mustacchi         if (l > sizeof(s)) {                \
57*4d9fdb46SRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\
58*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;            \
59*4d9fdb46SRobert Mustacchi         }                                   \
60*4d9fdb46SRobert Mustacchi         sbyte = sizeof(s) - l;              \
61*4d9fdb46SRobert Mustacchi         p = (const char *)(&s);             \
62*4d9fdb46SRobert Mustacchi         dbg->de_copy_word(t,(const void *)(p+sbyte),l);\
63*4d9fdb46SRobert Mustacchi     } while (0)
64*4d9fdb46SRobert Mustacchi #else /* LITTLEENDIAN */
65*4d9fdb46SRobert Mustacchi #define ASNOUT(t,s,l)                       \
66*4d9fdb46SRobert Mustacchi     do {                                    \
67*4d9fdb46SRobert Mustacchi         const char *p = 0;                  \
68*4d9fdb46SRobert Mustacchi         if (l > sizeof(s)) {                \
69*4d9fdb46SRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\
70*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;            \
71*4d9fdb46SRobert Mustacchi         }                                   \
72*4d9fdb46SRobert Mustacchi         p = (const char *)(&s);             \
73*4d9fdb46SRobert Mustacchi         dbg->de_copy_word(t,(const void *)p,l);  \
74*4d9fdb46SRobert Mustacchi     } while (0)
75*4d9fdb46SRobert Mustacchi #endif /* ENDIANNESS */
76*4d9fdb46SRobert Mustacchi 
77*4d9fdb46SRobert Mustacchi 
7849d3bc91SRichard Lowe static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde,
79*4d9fdb46SRobert Mustacchi     Dwarf_P_Frame_Pgm inst);
80*4d9fdb46SRobert Mustacchi 
81*4d9fdb46SRobert Mustacchi /*  This function adds a cie struct to the debug pointer. Its in the
82*4d9fdb46SRobert Mustacchi     form of a linked list.
83*4d9fdb46SRobert Mustacchi     augmenter: string reps augmentation (implementation defined)
84*4d9fdb46SRobert Mustacchi     code_align: alignment of code
85*4d9fdb46SRobert Mustacchi     data_align: alignment of data
86*4d9fdb46SRobert Mustacchi     init_bytes: byts having initial instructions
87*4d9fdb46SRobert Mustacchi     init_n_bytes: number of bytes of initial instructions */
88*4d9fdb46SRobert Mustacchi 
89*4d9fdb46SRobert Mustacchi 
9049d3bc91SRichard Lowe 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)9149d3bc91SRichard Lowe dwarf_add_frame_cie(Dwarf_P_Debug dbg,
92*4d9fdb46SRobert Mustacchi     char *augmenter,
93*4d9fdb46SRobert Mustacchi     Dwarf_Small code_align,
94*4d9fdb46SRobert Mustacchi     Dwarf_Small data_align,
95*4d9fdb46SRobert Mustacchi     Dwarf_Small return_reg,
96*4d9fdb46SRobert Mustacchi     Dwarf_Ptr init_bytes,
97*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned init_n_bytes,
98*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
99*4d9fdb46SRobert Mustacchi {
100*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index = 0;
101*4d9fdb46SRobert Mustacchi     int res = 0;
102*4d9fdb46SRobert Mustacchi 
103*4d9fdb46SRobert Mustacchi     res = dwarf_add_frame_cie_a(dbg,augmenter, code_align,
104*4d9fdb46SRobert Mustacchi         data_align,return_reg,init_bytes,
105*4d9fdb46SRobert Mustacchi         init_n_bytes,
106*4d9fdb46SRobert Mustacchi         &index,error);
107*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
108*4d9fdb46SRobert Mustacchi         return DW_DLV_NOCOUNT;
109*4d9fdb46SRobert Mustacchi     }
110*4d9fdb46SRobert Mustacchi     return index;
111*4d9fdb46SRobert Mustacchi }
112*4d9fdb46SRobert Mustacchi 
113*4d9fdb46SRobert Mustacchi 
114*4d9fdb46SRobert Mustacchi int
dwarf_add_frame_cie_a(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_Unsigned * cie_index_out,Dwarf_Error * error)115*4d9fdb46SRobert Mustacchi dwarf_add_frame_cie_a(Dwarf_P_Debug dbg,
116*4d9fdb46SRobert Mustacchi     char *augmenter,
117*4d9fdb46SRobert Mustacchi     Dwarf_Small code_align,
118*4d9fdb46SRobert Mustacchi     Dwarf_Small data_align,
119*4d9fdb46SRobert Mustacchi     Dwarf_Small return_reg,
120*4d9fdb46SRobert Mustacchi     Dwarf_Ptr init_bytes,
121*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned init_n_bytes,
122*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * cie_index_out,
123*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
12449d3bc91SRichard Lowe {
12549d3bc91SRichard Lowe     Dwarf_P_Cie curcie;
126*4d9fdb46SRobert Mustacchi     char *tmpaug = 0;
12749d3bc91SRichard Lowe 
12849d3bc91SRichard Lowe     if (dbg->de_frame_cies == NULL) {
12907dc1947SRichard Lowe         dbg->de_frame_cies = (Dwarf_P_Cie)
13007dc1947SRichard Lowe             _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
13107dc1947SRichard Lowe         if (dbg->de_frame_cies == NULL) {
132*4d9fdb46SRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR);
13307dc1947SRichard Lowe         }
13407dc1947SRichard Lowe         curcie = dbg->de_frame_cies;
13507dc1947SRichard Lowe         dbg->de_n_cie = 1;
13607dc1947SRichard Lowe         dbg->de_last_cie = curcie;
13749d3bc91SRichard Lowe     } else {
13807dc1947SRichard Lowe         curcie = dbg->de_last_cie;
13907dc1947SRichard Lowe         curcie->cie_next = (Dwarf_P_Cie)
14007dc1947SRichard Lowe             _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
14107dc1947SRichard Lowe         if (curcie->cie_next == NULL) {
142*4d9fdb46SRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR);
14307dc1947SRichard Lowe         }
14407dc1947SRichard Lowe         curcie = curcie->cie_next;
14507dc1947SRichard Lowe         dbg->de_n_cie++;
14607dc1947SRichard Lowe         dbg->de_last_cie = curcie;
14749d3bc91SRichard Lowe     }
148*4d9fdb46SRobert Mustacchi     curcie->cie_version = 1;
149*4d9fdb46SRobert Mustacchi     if (dbg->de_output_version > 2) {
150*4d9fdb46SRobert Mustacchi         curcie->cie_version = dbg->de_output_version;
151*4d9fdb46SRobert Mustacchi     } else {
152*4d9fdb46SRobert Mustacchi         /*  V2 dwarf has debug_frame as version 1, there
153*4d9fdb46SRobert Mustacchi             is no 2 used in this section. */
154*4d9fdb46SRobert Mustacchi         curcie->cie_version = 1;
155*4d9fdb46SRobert Mustacchi     }
156*4d9fdb46SRobert Mustacchi     tmpaug = (char *)_dwarf_p_get_alloc(dbg,strlen(augmenter)+1);
157*4d9fdb46SRobert Mustacchi     if (!tmpaug) {
158*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR);
159*4d9fdb46SRobert Mustacchi     }
160*4d9fdb46SRobert Mustacchi     strcpy(tmpaug,augmenter);
161*4d9fdb46SRobert Mustacchi     curcie->cie_aug = tmpaug;
16249d3bc91SRichard Lowe     curcie->cie_code_align = code_align;
16349d3bc91SRichard Lowe     curcie->cie_data_align = data_align;
16449d3bc91SRichard Lowe     curcie->cie_ret_reg = return_reg;
16549d3bc91SRichard Lowe     curcie->cie_inst = (char *) init_bytes;
16649d3bc91SRichard Lowe     curcie->cie_inst_bytes = (long) init_n_bytes;
16749d3bc91SRichard Lowe     curcie->cie_next = NULL;
168*4d9fdb46SRobert Mustacchi     *cie_index_out =  dbg->de_n_cie;
169*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
17049d3bc91SRichard Lowe }
17149d3bc91SRichard Lowe 
17249d3bc91SRichard Lowe 
173*4d9fdb46SRobert Mustacchi /*  This functions adds a fde struct to the debug pointer. Its in the
174*4d9fdb46SRobert Mustacchi     form of a linked list.
175*4d9fdb46SRobert Mustacchi     die: subprogram/function die corresponding to this fde
176*4d9fdb46SRobert Mustacchi     cie: cie referred to by this fde, obtained from call to
177*4d9fdb46SRobert Mustacchi         add_frame_cie() routine.
178*4d9fdb46SRobert Mustacchi     virt_addr: beginning address
179*4d9fdb46SRobert Mustacchi     code_len: length of code reps by the fde */
180*4d9fdb46SRobert Mustacchi /*ARGSUSED*/                   /* pretend all args used */
181*4d9fdb46SRobert 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)18249d3bc91SRichard Lowe dwarf_add_frame_fde(Dwarf_P_Debug dbg,
183*4d9fdb46SRobert Mustacchi     Dwarf_P_Fde fde,
184*4d9fdb46SRobert Mustacchi     Dwarf_P_Die die,
185*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cie,
186*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned virt_addr,
187*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned code_len,
188*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned symidx, Dwarf_Error * error)
18949d3bc91SRichard Lowe {
190*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index = 0;
191*4d9fdb46SRobert Mustacchi     int res = 0;
192*4d9fdb46SRobert Mustacchi 
193*4d9fdb46SRobert Mustacchi     res = dwarf_add_frame_fde_c(dbg, fde, die, cie, virt_addr,
194*4d9fdb46SRobert Mustacchi         code_len, symidx, 0, 0,&index, error);
195*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
196*4d9fdb46SRobert Mustacchi         return DW_DLV_NOCOUNT;
197*4d9fdb46SRobert Mustacchi     }
198*4d9fdb46SRobert Mustacchi     return index;
19949d3bc91SRichard Lowe }
20049d3bc91SRichard Lowe 
201*4d9fdb46SRobert Mustacchi /*  There is no dwarf_add_frame_fde_a */
20249d3bc91SRichard Lowe /*ARGSUSED10*/
20349d3bc91SRichard Lowe 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)20449d3bc91SRichard Lowe dwarf_add_frame_fde_b(Dwarf_P_Debug dbg,
205*4d9fdb46SRobert Mustacchi     Dwarf_P_Fde fde,
206*4d9fdb46SRobert Mustacchi     Dwarf_P_Die die,
207*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cie,
208*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned virt_addr,
209*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned code_len,
210*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned symidx,
211*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned symidx_of_end,
212*4d9fdb46SRobert Mustacchi     Dwarf_Addr offset_from_end_sym,
213*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
214*4d9fdb46SRobert Mustacchi {
215*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index = 0;
216*4d9fdb46SRobert Mustacchi     int res = 0;
217*4d9fdb46SRobert Mustacchi 
218*4d9fdb46SRobert Mustacchi     res = dwarf_add_frame_fde_c(dbg,fde,die,cie,
219*4d9fdb46SRobert Mustacchi         virt_addr,code_len,symidx,symidx_of_end,
220*4d9fdb46SRobert Mustacchi         offset_from_end_sym,&index,error);
221*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
222*4d9fdb46SRobert Mustacchi         return DW_DLV_NOCOUNT;
223*4d9fdb46SRobert Mustacchi     }
224*4d9fdb46SRobert Mustacchi     return index;
225*4d9fdb46SRobert Mustacchi }
226*4d9fdb46SRobert Mustacchi 
227*4d9fdb46SRobert Mustacchi /*  New December 2018 */
228*4d9fdb46SRobert Mustacchi int
dwarf_add_frame_fde_c(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_Unsigned * index_to_fde,UNUSEDARG Dwarf_Error * error)229*4d9fdb46SRobert Mustacchi dwarf_add_frame_fde_c(Dwarf_P_Debug dbg,
230*4d9fdb46SRobert Mustacchi     Dwarf_P_Fde fde,
231*4d9fdb46SRobert Mustacchi     Dwarf_P_Die die,
232*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cie,
233*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned virt_addr,
234*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned code_len,
235*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned symidx,
236*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned symidx_of_end,
237*4d9fdb46SRobert Mustacchi     Dwarf_Addr offset_from_end_sym,
238*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *index_to_fde,
239*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Error * error)
24049d3bc91SRichard Lowe {
24149d3bc91SRichard Lowe     Dwarf_P_Fde curfde;
24249d3bc91SRichard Lowe 
24349d3bc91SRichard Lowe     fde->fde_die = die;
24449d3bc91SRichard Lowe     fde->fde_cie = (long) cie;
24549d3bc91SRichard Lowe     fde->fde_initloc = virt_addr;
24649d3bc91SRichard Lowe     fde->fde_r_symidx = symidx;
24749d3bc91SRichard Lowe     fde->fde_addr_range = code_len;
24849d3bc91SRichard Lowe     fde->fde_offset_into_exception_tables = DW_DLX_NO_EH_OFFSET;
24949d3bc91SRichard Lowe     fde->fde_exception_table_symbol = 0;
25049d3bc91SRichard Lowe     fde->fde_end_symbol_offset = offset_from_end_sym;
25149d3bc91SRichard Lowe     fde->fde_end_symbol = symidx_of_end;
25207dc1947SRichard Lowe     fde->fde_dbg = dbg;
25349d3bc91SRichard Lowe 
25449d3bc91SRichard Lowe     curfde = dbg->de_last_fde;
25549d3bc91SRichard Lowe     if (curfde == NULL) {
25607dc1947SRichard Lowe         dbg->de_frame_fdes = fde;
25707dc1947SRichard Lowe         dbg->de_last_fde = fde;
25807dc1947SRichard Lowe         dbg->de_n_fde = 1;
25949d3bc91SRichard Lowe     } else {
26007dc1947SRichard Lowe         curfde->fde_next = fde;
26107dc1947SRichard Lowe         dbg->de_last_fde = fde;
26207dc1947SRichard Lowe         dbg->de_n_fde++;
26349d3bc91SRichard Lowe     }
264*4d9fdb46SRobert Mustacchi     *index_to_fde = dbg->de_n_fde;
265*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
26649d3bc91SRichard Lowe }
26749d3bc91SRichard Lowe 
268*4d9fdb46SRobert Mustacchi /*  This function adds information to an fde. The fde is
269*4d9fdb46SRobert Mustacchi     linked into the linked list of fde's maintained in the Dwarf_P_Debug
270*4d9fdb46SRobert Mustacchi     structure.
271*4d9fdb46SRobert Mustacchi     dbg: The debug descriptor.
272*4d9fdb46SRobert Mustacchi     fde: The fde to be added.
273*4d9fdb46SRobert Mustacchi     die: subprogram/function die corresponding to this fde
274*4d9fdb46SRobert Mustacchi     cie: cie referred to by this fde, obtained from call to
275*4d9fdb46SRobert Mustacchi         add_frame_cie() routine.
276*4d9fdb46SRobert Mustacchi     virt_addr: beginning address
277*4d9fdb46SRobert Mustacchi     code_len: length of code reps by the fde
278*4d9fdb46SRobert Mustacchi     symidx: The symbol id of the symbol wrt to which relocation needs
279*4d9fdb46SRobert Mustacchi         to be performed for 'virt_addr'.
280*4d9fdb46SRobert Mustacchi     offset_into_exception_tables: The start of exception tables for
281*4d9fdb46SRobert Mustacchi         this function (indicated as an offset into the exception
282*4d9fdb46SRobert Mustacchi         tables). A value of -1 indicates that there is no exception
283*4d9fdb46SRobert Mustacchi         table entries associated with this function.
284*4d9fdb46SRobert Mustacchi     exception_table_symbol: The symbol id of the section for exception
285*4d9fdb46SRobert Mustacchi         tables wrt to which the offset_into_exception_tables will
286*4d9fdb46SRobert Mustacchi         be relocated. */
28749d3bc91SRichard Lowe 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)28849d3bc91SRichard Lowe dwarf_add_frame_info(Dwarf_P_Debug dbg,
289*4d9fdb46SRobert Mustacchi     Dwarf_P_Fde fde,
290*4d9fdb46SRobert Mustacchi     Dwarf_P_Die die,
291*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cie,
292*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned virt_addr,
293*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned code_len,
294*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned symidx,
295*4d9fdb46SRobert Mustacchi     Dwarf_Signed offset_into_exception_tables,
296*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned exception_table_symbol,
297*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
29849d3bc91SRichard Lowe {
299*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned fde_index = 0;
300*4d9fdb46SRobert Mustacchi     int res = 0;
301*4d9fdb46SRobert Mustacchi 
302*4d9fdb46SRobert Mustacchi     res = dwarf_add_frame_info_c(dbg, fde, die, cie, virt_addr,
303*4d9fdb46SRobert Mustacchi         code_len, symidx,
304*4d9fdb46SRobert Mustacchi         /* end_symbol */ 0,
305*4d9fdb46SRobert Mustacchi         /* offset_from_end */ 0,
306*4d9fdb46SRobert Mustacchi         offset_into_exception_tables,
307*4d9fdb46SRobert Mustacchi         exception_table_symbol,
308*4d9fdb46SRobert Mustacchi         &fde_index, error);
309*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
310*4d9fdb46SRobert Mustacchi         return DW_DLV_NOCOUNT;
311*4d9fdb46SRobert Mustacchi     }
312*4d9fdb46SRobert Mustacchi     return fde_index;
31349d3bc91SRichard Lowe }
31449d3bc91SRichard Lowe 
315*4d9fdb46SRobert Mustacchi /*ARGSUSED*/                   /* pretend all args used */
31607dc1947SRichard Lowe 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)31749d3bc91SRichard Lowe dwarf_add_frame_info_b(Dwarf_P_Debug dbg,
318*4d9fdb46SRobert Mustacchi     Dwarf_P_Fde fde,
319*4d9fdb46SRobert Mustacchi     Dwarf_P_Die die,
320*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cie,
321*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned virt_addr,
322*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned code_len,
323*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned symidx,
324*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned end_symidx,
325*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset_from_end_symbol,
326*4d9fdb46SRobert Mustacchi     Dwarf_Signed offset_into_exception_tables,
327*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned exception_table_symbol,
328*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Error * error)
329*4d9fdb46SRobert Mustacchi {
330*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned fde_index = 0;
331*4d9fdb46SRobert Mustacchi     int res = 0;
332*4d9fdb46SRobert Mustacchi 
333*4d9fdb46SRobert Mustacchi     res = dwarf_add_frame_info_c(dbg, fde, die, cie, virt_addr,
334*4d9fdb46SRobert Mustacchi         code_len, symidx, end_symidx,
335*4d9fdb46SRobert Mustacchi         offset_from_end_symbol,
336*4d9fdb46SRobert Mustacchi         offset_into_exception_tables,
337*4d9fdb46SRobert Mustacchi         exception_table_symbol,
338*4d9fdb46SRobert Mustacchi         &fde_index, error);
339*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
340*4d9fdb46SRobert Mustacchi         return DW_DLV_NOCOUNT;
341*4d9fdb46SRobert Mustacchi     }
342*4d9fdb46SRobert Mustacchi     return fde_index;
343*4d9fdb46SRobert Mustacchi }
344*4d9fdb46SRobert Mustacchi 
345*4d9fdb46SRobert Mustacchi int
dwarf_add_frame_info_c(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_Unsigned * fde_index_out,UNUSEDARG Dwarf_Error * error)346*4d9fdb46SRobert Mustacchi dwarf_add_frame_info_c(Dwarf_P_Debug dbg,
347*4d9fdb46SRobert Mustacchi     Dwarf_P_Fde fde,
348*4d9fdb46SRobert Mustacchi     Dwarf_P_Die die,
349*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cie,
350*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned virt_addr,
351*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned code_len,
352*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned symidx,
353*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned end_symidx,
354*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset_from_end_symbol,
355*4d9fdb46SRobert Mustacchi     Dwarf_Signed offset_into_exception_tables,
356*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned exception_table_symbol,
357*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *fde_index_out,
358*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Error * error)
35949d3bc91SRichard Lowe {
36049d3bc91SRichard Lowe     Dwarf_P_Fde curfde;
36149d3bc91SRichard Lowe 
36249d3bc91SRichard Lowe     fde->fde_die = die;
36349d3bc91SRichard Lowe     fde->fde_cie = (long) cie;
36449d3bc91SRichard Lowe     fde->fde_initloc = virt_addr;
36549d3bc91SRichard Lowe     fde->fde_r_symidx = symidx;
36649d3bc91SRichard Lowe     fde->fde_addr_range = code_len;
36749d3bc91SRichard Lowe     fde->fde_offset_into_exception_tables =
36807dc1947SRichard Lowe         offset_into_exception_tables;
36949d3bc91SRichard Lowe     fde->fde_exception_table_symbol = exception_table_symbol;
37049d3bc91SRichard Lowe     fde->fde_end_symbol_offset = offset_from_end_symbol;
37149d3bc91SRichard Lowe     fde->fde_end_symbol = end_symidx;
37207dc1947SRichard Lowe     fde->fde_dbg = dbg;
37349d3bc91SRichard Lowe 
37449d3bc91SRichard Lowe     curfde = dbg->de_last_fde;
37549d3bc91SRichard Lowe     if (curfde == NULL) {
37607dc1947SRichard Lowe         dbg->de_frame_fdes = fde;
37707dc1947SRichard Lowe         dbg->de_last_fde = fde;
37807dc1947SRichard Lowe         dbg->de_n_fde = 1;
37949d3bc91SRichard Lowe     } else {
38007dc1947SRichard Lowe         curfde->fde_next = fde;
38107dc1947SRichard Lowe         dbg->de_last_fde = fde;
38207dc1947SRichard Lowe         dbg->de_n_fde++;
38349d3bc91SRichard Lowe     }
384*4d9fdb46SRobert Mustacchi     *fde_index_out = dbg->de_n_fde;
385*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
38649d3bc91SRichard Lowe }
38749d3bc91SRichard Lowe 
38807dc1947SRichard Lowe /* This is an alternate to inserting frame instructions
38907dc1947SRichard Lowe    one instruction at a time.  But use either this
39007dc1947SRichard Lowe    or instruction level, not both in one fde. */
39107dc1947SRichard Lowe int
dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg,Dwarf_P_Fde fde,Dwarf_Unsigned len,Dwarf_Ptr ibytes,Dwarf_Error * error)39207dc1947SRichard Lowe dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg,
39307dc1947SRichard Lowe     Dwarf_P_Fde fde,Dwarf_Unsigned len, Dwarf_Ptr ibytes,
39407dc1947SRichard Lowe     Dwarf_Error *error)
39507dc1947SRichard Lowe {
396*4d9fdb46SRobert Mustacchi     if (len == 0) {
39707dc1947SRichard Lowe         return DW_DLV_OK;
39807dc1947SRichard Lowe     }
399*4d9fdb46SRobert Mustacchi     if (fde->fde_block || fde->fde_inst) {
40007dc1947SRichard Lowe         DWARF_P_DBG_ERROR(dbg, DW_DLE_DUPLICATE_INST_BLOCK,
401*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
40207dc1947SRichard Lowe     }
40307dc1947SRichard Lowe     fde->fde_block = (Dwarf_Ptr)_dwarf_p_get_alloc(dbg, len);
40407dc1947SRichard Lowe     memcpy(fde->fde_block,ibytes,len);
40507dc1947SRichard Lowe     fde->fde_inst_block_size = len;
40607dc1947SRichard Lowe     fde->fde_n_bytes += len;
40707dc1947SRichard Lowe     return DW_DLV_OK;
40807dc1947SRichard Lowe }
40907dc1947SRichard Lowe 
41049d3bc91SRichard Lowe 
411*4d9fdb46SRobert Mustacchi 
412*4d9fdb46SRobert Mustacchi /* Create a new fde. */
41349d3bc91SRichard Lowe Dwarf_P_Fde
dwarf_new_fde(Dwarf_P_Debug dbg,Dwarf_Error * error)41449d3bc91SRichard Lowe dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error)
415*4d9fdb46SRobert Mustacchi {
416*4d9fdb46SRobert Mustacchi     Dwarf_P_Fde fde = 0;
417*4d9fdb46SRobert Mustacchi     int res = 0;
418*4d9fdb46SRobert Mustacchi 
419*4d9fdb46SRobert Mustacchi     res = dwarf_new_fde_a(dbg,&fde,error);
420*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
421*4d9fdb46SRobert Mustacchi         return (Dwarf_P_Fde) DW_DLV_BADADDR;
422*4d9fdb46SRobert Mustacchi     }
423*4d9fdb46SRobert Mustacchi     return fde;
424*4d9fdb46SRobert Mustacchi }
425*4d9fdb46SRobert Mustacchi int
dwarf_new_fde_a(Dwarf_P_Debug dbg,Dwarf_P_Fde * fde_out,Dwarf_Error * error)426*4d9fdb46SRobert Mustacchi dwarf_new_fde_a(Dwarf_P_Debug dbg,
427*4d9fdb46SRobert Mustacchi     Dwarf_P_Fde *fde_out,
428*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
42949d3bc91SRichard Lowe {
43049d3bc91SRichard Lowe     Dwarf_P_Fde fde;
43149d3bc91SRichard Lowe 
43249d3bc91SRichard Lowe     fde = (Dwarf_P_Fde)
43307dc1947SRichard Lowe         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s));
43449d3bc91SRichard Lowe     if (fde == NULL) {
435*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC, DW_DLV_ERROR);
43649d3bc91SRichard Lowe     }
437*4d9fdb46SRobert Mustacchi     fde->fde_dbg = dbg;
438*4d9fdb46SRobert Mustacchi     fde->fde_uwordb_size = dbg->de_dwarf_offset_size;
439*4d9fdb46SRobert Mustacchi     *fde_out = fde;
440*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
44149d3bc91SRichard Lowe }
44249d3bc91SRichard Lowe 
44307dc1947SRichard Lowe 
444*4d9fdb46SRobert Mustacchi /*  Add a cfe_offset instruction to the fde passed in. */
44549d3bc91SRichard Lowe Dwarf_P_Fde
dwarf_fde_cfa_offset(Dwarf_P_Fde fde,Dwarf_Unsigned reg,Dwarf_Signed offset,Dwarf_Error * error)44649d3bc91SRichard Lowe dwarf_fde_cfa_offset(Dwarf_P_Fde fde,
447*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned reg,
448*4d9fdb46SRobert Mustacchi     Dwarf_Signed offset,
449*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
450*4d9fdb46SRobert Mustacchi {
451*4d9fdb46SRobert Mustacchi     int res = 0;
452*4d9fdb46SRobert Mustacchi 
453*4d9fdb46SRobert Mustacchi     res = dwarf_fde_cfa_offset_a(fde,reg,offset,error);
454*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
455*4d9fdb46SRobert Mustacchi         return (Dwarf_P_Fde) DW_DLV_BADADDR;
456*4d9fdb46SRobert Mustacchi     }
457*4d9fdb46SRobert Mustacchi     return fde;
458*4d9fdb46SRobert Mustacchi }
459*4d9fdb46SRobert Mustacchi 
460*4d9fdb46SRobert Mustacchi 
461*4d9fdb46SRobert Mustacchi int
dwarf_fde_cfa_offset_a(Dwarf_P_Fde fde,Dwarf_Unsigned reg,Dwarf_Signed offset,Dwarf_Error * error)462*4d9fdb46SRobert Mustacchi dwarf_fde_cfa_offset_a(Dwarf_P_Fde fde,
463*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned reg,
464*4d9fdb46SRobert Mustacchi     Dwarf_Signed offset,
465*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
46649d3bc91SRichard Lowe {
46749d3bc91SRichard Lowe     Dwarf_Ubyte opc, regno;
468*4d9fdb46SRobert Mustacchi     char *ptr = 0;
46949d3bc91SRichard Lowe     Dwarf_P_Frame_Pgm curinst;
470*4d9fdb46SRobert Mustacchi     int nbytes = 0;
471*4d9fdb46SRobert Mustacchi     int res = 0;
47249d3bc91SRichard Lowe     char buff1[ENCODE_SPACE_NEEDED];
47307dc1947SRichard Lowe     Dwarf_P_Debug dbg = fde->fde_dbg;
47449d3bc91SRichard Lowe 
47549d3bc91SRichard Lowe     curinst = (Dwarf_P_Frame_Pgm)
47607dc1947SRichard Lowe         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
47749d3bc91SRichard Lowe     if (curinst == NULL) {
478*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC, DW_DLV_ERROR);
47949d3bc91SRichard Lowe     }
48049d3bc91SRichard Lowe     opc = DW_CFA_offset;
48149d3bc91SRichard Lowe     regno = reg;
48249d3bc91SRichard Lowe     if (regno & 0xc0) {
483*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,DW_DLV_ERROR);
48449d3bc91SRichard Lowe     }
48507dc1947SRichard Lowe     opc = opc | regno;          /* lower 6 bits are register number */
48649d3bc91SRichard Lowe     curinst->dfp_opcode = opc;
48749d3bc91SRichard Lowe     res = _dwarf_pro_encode_leb128_nm(offset, &nbytes,
488*4d9fdb46SRobert Mustacchi         buff1, sizeof(buff1));
48949d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
49007dc1947SRichard Lowe         _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
491*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
49249d3bc91SRichard Lowe     }
49307dc1947SRichard Lowe     ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
49449d3bc91SRichard Lowe     if (ptr == NULL) {
49507dc1947SRichard Lowe         _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
496*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
49749d3bc91SRichard Lowe     }
49849d3bc91SRichard Lowe     memcpy(ptr, buff1, nbytes);
49949d3bc91SRichard Lowe 
50049d3bc91SRichard Lowe     curinst->dfp_args = ptr;
50149d3bc91SRichard Lowe     curinst->dfp_nbytes = nbytes;
50249d3bc91SRichard Lowe     curinst->dfp_next = NULL;
50349d3bc91SRichard Lowe 
50449d3bc91SRichard Lowe     _dwarf_pro_add_to_fde(fde, curinst);
505*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
50649d3bc91SRichard Lowe }
50749d3bc91SRichard Lowe 
508*4d9fdb46SRobert Mustacchi /*  Generic routine to add opcode to fde instructions. val1 and
50949d3bc91SRichard Lowe     val2 are parameters whose interpretation depends on the 'op'.
51049d3bc91SRichard Lowe 
51149d3bc91SRichard Lowe     This does not work properly for  DW_DLC_SYMBOLIC_RELOCATIONS
51249d3bc91SRichard Lowe     for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as
513*4d9fdb46SRobert Mustacchi     these ops normally are addresses or (DW_CFA_set_loc)
51449d3bc91SRichard Lowe     or code lengths (DW_DVA_advance_loc*) and such must be
51549d3bc91SRichard Lowe     represented with relocations and symbol indices for
51649d3bc91SRichard Lowe     DW_DLC_SYMBOLIC_RELOCATIONS.
51749d3bc91SRichard Lowe 
51807dc1947SRichard Lowe     This does not treat all DW_CFA instructions yet.
51907dc1947SRichard Lowe 
52007dc1947SRichard Lowe     For certain operations a val? value must be
52107dc1947SRichard Lowe     signed (though passed in as unsigned here).
52207dc1947SRichard Lowe 
523*4d9fdb46SRobert Mustacchi     Does not check that the frame
524*4d9fdb46SRobert Mustacchi     version is 3(for dwarf3) or 4 (for dwarf4) or 5
52507dc1947SRichard Lowe     when applying operations that are only valid for
526*4d9fdb46SRobert Mustacchi     particular versions. */
52749d3bc91SRichard Lowe Dwarf_P_Fde
dwarf_add_fde_inst(Dwarf_P_Fde fde,Dwarf_Small op,Dwarf_Unsigned val1,Dwarf_Unsigned val2,Dwarf_Error * error)52849d3bc91SRichard Lowe dwarf_add_fde_inst(Dwarf_P_Fde fde,
529*4d9fdb46SRobert Mustacchi     Dwarf_Small op,
530*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned val1,
531*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned val2, Dwarf_Error * error)
532*4d9fdb46SRobert Mustacchi {
533*4d9fdb46SRobert Mustacchi     int res = 0;
534*4d9fdb46SRobert Mustacchi 
535*4d9fdb46SRobert Mustacchi     res = dwarf_add_fde_inst_a(fde,op,val1,val2,error);
536*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
537*4d9fdb46SRobert Mustacchi         return ((Dwarf_P_Fde) DW_DLV_BADADDR);
538*4d9fdb46SRobert Mustacchi     }
539*4d9fdb46SRobert Mustacchi     return fde;
540*4d9fdb46SRobert Mustacchi }
541*4d9fdb46SRobert Mustacchi 
542*4d9fdb46SRobert Mustacchi /*  December 2018. A more sensible return value. */
543*4d9fdb46SRobert Mustacchi int
dwarf_add_fde_inst_a(Dwarf_P_Fde fde,Dwarf_Small op,Dwarf_Unsigned val1,Dwarf_Unsigned val2,Dwarf_Error * error)544*4d9fdb46SRobert Mustacchi dwarf_add_fde_inst_a(Dwarf_P_Fde fde,
545*4d9fdb46SRobert Mustacchi     Dwarf_Small op,
546*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned val1,
547*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned val2,
548*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
54949d3bc91SRichard Lowe {
55049d3bc91SRichard Lowe     Dwarf_P_Frame_Pgm curinst;
551*4d9fdb46SRobert Mustacchi     int nbytes = 0;
552*4d9fdb46SRobert Mustacchi     int nbytes1 = 0;
553*4d9fdb46SRobert Mustacchi     int nbytes2 = 0;
554*4d9fdb46SRobert Mustacchi     Dwarf_Ubyte db = 0;
555*4d9fdb46SRobert Mustacchi     Dwarf_Half dh = 0;
556*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned du = 0;
557*4d9fdb46SRobert Mustacchi     char *ptr = 0;
558*4d9fdb46SRobert Mustacchi     int res = 0;
55949d3bc91SRichard Lowe     char buff1[ENCODE_SPACE_NEEDED];
56049d3bc91SRichard Lowe     char buff2[ENCODE_SPACE_NEEDED];
56107dc1947SRichard Lowe     Dwarf_P_Debug dbg = fde->fde_dbg;
562*4d9fdb46SRobert Mustacchi     /*  This is a hack telling the code when to transform
563*4d9fdb46SRobert Mustacchi         a value to a signed leb number. */
56407dc1947SRichard Lowe     int signed_second = 0;
56507dc1947SRichard Lowe     int signed_first = 0;
56649d3bc91SRichard Lowe 
56749d3bc91SRichard Lowe 
568*4d9fdb46SRobert Mustacchi     buff1[0] = 0;
569*4d9fdb46SRobert Mustacchi     buff2[0] = 0;
57049d3bc91SRichard Lowe     curinst = (Dwarf_P_Frame_Pgm)
57107dc1947SRichard Lowe         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
57249d3bc91SRichard Lowe     if (curinst == NULL) {
57307dc1947SRichard Lowe         _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC);
574*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
57549d3bc91SRichard Lowe     }
57649d3bc91SRichard Lowe     switch (op) {
57749d3bc91SRichard Lowe 
578*4d9fdb46SRobert Mustacchi     case DW_CFA_advance_loc: {
57907dc1947SRichard Lowe         if (val1 <= 0x3f) {
58007dc1947SRichard Lowe             db = val1;
58107dc1947SRichard Lowe             op |= db;
582*4d9fdb46SRobert Mustacchi         } else if (!(val1& ~0xff)) {
58307dc1947SRichard Lowe             op = DW_CFA_advance_loc1;
58407dc1947SRichard Lowe             db = val1;
58507dc1947SRichard Lowe             ptr = (char *) _dwarf_p_get_alloc(dbg, 1);
58607dc1947SRichard Lowe             if (ptr == NULL) {
58707dc1947SRichard Lowe                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
588*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
58907dc1947SRichard Lowe             }
59007dc1947SRichard Lowe             memcpy((void *) ptr, (const void *) &db, 1);
59107dc1947SRichard Lowe             nbytes = 1;
592*4d9fdb46SRobert Mustacchi         } else if (!(val1& (~(Dwarf_Unsigned)0xffff))) {
593*4d9fdb46SRobert Mustacchi             if (sizeof(dh) < SIZEOFT16) {
594*4d9fdb46SRobert Mustacchi                 _dwarf_p_error(dbg, error,
595*4d9fdb46SRobert Mustacchi                     DW_DLE_DEBUG_FRAME_LENGTH_BAD);
596*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
597*4d9fdb46SRobert Mustacchi             }
59807dc1947SRichard Lowe             op = DW_CFA_advance_loc2;
59907dc1947SRichard Lowe             dh = val1;
600*4d9fdb46SRobert Mustacchi             ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT16);
60107dc1947SRichard Lowe             if (ptr == NULL) {
60207dc1947SRichard Lowe                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
603*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
604*4d9fdb46SRobert Mustacchi             }
605*4d9fdb46SRobert Mustacchi             /*  No byte swapping, assuming running at
606*4d9fdb46SRobert Mustacchi                 target endianness. */
607*4d9fdb46SRobert Mustacchi             ASNOUT((void *) ptr, dh, SIZEOFT16);
608*4d9fdb46SRobert Mustacchi             nbytes = SIZEOFT16;
609*4d9fdb46SRobert Mustacchi         } else if (!(val1& ~(Dwarf_Unsigned)0xffffffff)) {
610*4d9fdb46SRobert Mustacchi             if (sizeof(du) < SIZEOFT32) {
611*4d9fdb46SRobert Mustacchi                 _dwarf_p_error(dbg, error,
612*4d9fdb46SRobert Mustacchi                     DW_DLE_DEBUG_FRAME_LENGTH_BAD);
613*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
61407dc1947SRichard Lowe             }
61507dc1947SRichard Lowe             op = DW_CFA_advance_loc4;
616*4d9fdb46SRobert Mustacchi             du = val1;
617*4d9fdb46SRobert Mustacchi             ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT32);
61807dc1947SRichard Lowe             if (ptr == NULL) {
61907dc1947SRichard Lowe                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
620*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
62107dc1947SRichard Lowe             }
622*4d9fdb46SRobert Mustacchi             ASNOUT((void *) ptr, du, SIZEOFT32);
623*4d9fdb46SRobert Mustacchi             nbytes = SIZEOFT32;
62407dc1947SRichard Lowe         } else {
625*4d9fdb46SRobert Mustacchi             if (sizeof(du) < SIZEOFT64) {
626*4d9fdb46SRobert Mustacchi                 _dwarf_p_error(dbg, error,
627*4d9fdb46SRobert Mustacchi                     DW_DLE_DEBUG_FRAME_LENGTH_BAD);
628*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
629*4d9fdb46SRobert Mustacchi             }
63007dc1947SRichard Lowe             op = DW_CFA_MIPS_advance_loc8;
63107dc1947SRichard Lowe             du = val1;
632*4d9fdb46SRobert Mustacchi             ptr = (char *) _dwarf_p_get_alloc(dbg,
633*4d9fdb46SRobert Mustacchi                 SIZEOFT64);
63407dc1947SRichard Lowe             if (ptr == NULL) {
63507dc1947SRichard Lowe                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
636*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
63707dc1947SRichard Lowe             }
638*4d9fdb46SRobert Mustacchi             /*  No byte swapping, assuming running at
639*4d9fdb46SRobert Mustacchi                 target endianness. */
640*4d9fdb46SRobert Mustacchi             ASNOUT((void *) ptr, du, SIZEOFT64);
641*4d9fdb46SRobert Mustacchi             nbytes = SIZEOFT64;
64207dc1947SRichard Lowe         }
64307dc1947SRichard Lowe         break;
644*4d9fdb46SRobert Mustacchi     }
64549d3bc91SRichard Lowe     case DW_CFA_offset:
64607dc1947SRichard Lowe         if (val1 <= MAX_6_BIT_VALUE) {
64707dc1947SRichard Lowe             db = val1;
64807dc1947SRichard Lowe             op |= db;
64907dc1947SRichard Lowe             res = _dwarf_pro_encode_leb128_nm(val2, &nbytes,
650*4d9fdb46SRobert Mustacchi                 buff1, sizeof(buff1));
65107dc1947SRichard Lowe             if (res != DW_DLV_OK) {
65207dc1947SRichard Lowe                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
653*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
65407dc1947SRichard Lowe             }
65507dc1947SRichard Lowe             ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
65607dc1947SRichard Lowe             if (ptr == NULL) {
65707dc1947SRichard Lowe                 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
658*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
65907dc1947SRichard Lowe             }
66007dc1947SRichard Lowe             memcpy(ptr, buff1, nbytes);
66107dc1947SRichard Lowe 
66207dc1947SRichard Lowe         } else {
66307dc1947SRichard Lowe             op = DW_CFA_offset_extended;
66407dc1947SRichard Lowe             goto two_leb;
66507dc1947SRichard Lowe         }
66607dc1947SRichard Lowe         break;
66707dc1947SRichard Lowe     case DW_CFA_offset_extended_sf: /* DWARF3 */
668*4d9fdb46SRobert Mustacchi         signed_second = 1;
669*4d9fdb46SRobert Mustacchi         goto two_leb;
67007dc1947SRichard Lowe     case DW_CFA_offset_extended:
671*4d9fdb46SRobert Mustacchi         goto two_leb;
67249d3bc91SRichard Lowe 
67349d3bc91SRichard Lowe     case DW_CFA_undefined:
67449d3bc91SRichard Lowe     case DW_CFA_same_value:
67507dc1947SRichard Lowe         goto one_leb;
67607dc1947SRichard Lowe 
67707dc1947SRichard Lowe     case DW_CFA_val_offset:
678*4d9fdb46SRobert Mustacchi         goto two_leb;
67907dc1947SRichard Lowe     case DW_CFA_val_offset_sf:
680*4d9fdb46SRobert Mustacchi         signed_second = 1;
681*4d9fdb46SRobert Mustacchi         goto two_leb;
68207dc1947SRichard Lowe     case DW_CFA_def_cfa_sf:
683*4d9fdb46SRobert Mustacchi         signed_second = 1;
684*4d9fdb46SRobert Mustacchi         goto two_leb;
68549d3bc91SRichard Lowe     case DW_CFA_register:
68649d3bc91SRichard Lowe     case DW_CFA_def_cfa:
68707dc1947SRichard Lowe     two_leb:
68807dc1947SRichard Lowe         res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
689*4d9fdb46SRobert Mustacchi             buff1, sizeof(buff1));
69007dc1947SRichard Lowe         if (res != DW_DLV_OK) {
69107dc1947SRichard Lowe             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
692*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
69307dc1947SRichard Lowe         }
69407dc1947SRichard Lowe         if (!signed_second) {
695*4d9fdb46SRobert Mustacchi             res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
696*4d9fdb46SRobert Mustacchi                 buff2, sizeof(buff2));
69707dc1947SRichard Lowe         } else {
69807dc1947SRichard Lowe             Dwarf_Signed val2s = val2;
69907dc1947SRichard Lowe             res = _dwarf_pro_encode_signed_leb128_nm(val2s, &nbytes2,
700*4d9fdb46SRobert Mustacchi                 buff2, sizeof(buff2));
701*4d9fdb46SRobert Mustacchi         }
702*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
703*4d9fdb46SRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
704*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
70507dc1947SRichard Lowe         }
70607dc1947SRichard Lowe 
70707dc1947SRichard Lowe         res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
708*4d9fdb46SRobert Mustacchi             buff2, sizeof(buff2));
70907dc1947SRichard Lowe         if (res != DW_DLV_OK) {
71007dc1947SRichard Lowe             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
711*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
71207dc1947SRichard Lowe         }
71307dc1947SRichard Lowe 
71407dc1947SRichard Lowe         ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2);
71507dc1947SRichard Lowe         if (ptr == NULL) {
71607dc1947SRichard Lowe             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
717*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
71807dc1947SRichard Lowe         }
71907dc1947SRichard Lowe         memcpy(ptr, buff1, nbytes1);
72007dc1947SRichard Lowe         memcpy(ptr + nbytes1, buff2, nbytes2);
72107dc1947SRichard Lowe         nbytes = nbytes1 + nbytes2;
72207dc1947SRichard Lowe         break;
72307dc1947SRichard Lowe 
72407dc1947SRichard Lowe     case DW_CFA_def_cfa_offset_sf: /* DWARF3 */
72507dc1947SRichard Lowe         signed_first = 1;
72607dc1947SRichard Lowe         goto one_leb;
72749d3bc91SRichard Lowe     case DW_CFA_def_cfa_register:
72849d3bc91SRichard Lowe     case DW_CFA_def_cfa_offset:
72907dc1947SRichard Lowe     one_leb:
730*4d9fdb46SRobert Mustacchi         if (!signed_first) {
73107dc1947SRichard Lowe             res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
732*4d9fdb46SRobert Mustacchi                 buff1, sizeof(buff1));
73307dc1947SRichard Lowe         } else {
73407dc1947SRichard Lowe             Dwarf_Signed val1s = val1;
73507dc1947SRichard Lowe             res = _dwarf_pro_encode_signed_leb128_nm(val1s, &nbytes,
736*4d9fdb46SRobert Mustacchi                 buff1, sizeof(buff1));
73707dc1947SRichard Lowe         }
73807dc1947SRichard Lowe         if (res != DW_DLV_OK) {
73907dc1947SRichard Lowe             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
740*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
74107dc1947SRichard Lowe         }
74207dc1947SRichard Lowe         ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
74307dc1947SRichard Lowe         if (ptr == NULL) {
74407dc1947SRichard Lowe             _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
745*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
74607dc1947SRichard Lowe         }
74707dc1947SRichard Lowe         memcpy(ptr, buff1, nbytes);
74807dc1947SRichard Lowe         break;
74907dc1947SRichard Lowe     case DW_CFA_def_cfa_expression: /* DWARF3 */
750*4d9fdb46SRobert Mustacchi         /*  FIXME: argument is dwarf expr, not handled yet. */
75107dc1947SRichard Lowe     case DW_CFA_expression: /* DWARF3 */
752*4d9fdb46SRobert Mustacchi         /*  First arg: ULEB reg num. 2nd arg dwarf expr in form block.
753*4d9fdb46SRobert Mustacchi             FIXME: not handled yet. */
75407dc1947SRichard Lowe     case DW_CFA_val_expression: /* DWARF3f */
755*4d9fdb46SRobert Mustacchi         /*  First arg: ULEB reg num. 2nd arg dwarf expr in form block.
756*4d9fdb46SRobert Mustacchi             FIXME: not handled yet. */
75749d3bc91SRichard Lowe     default:
75807dc1947SRichard Lowe         _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR);
759*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
76049d3bc91SRichard Lowe     }
76149d3bc91SRichard Lowe 
76249d3bc91SRichard Lowe     curinst->dfp_opcode = op;
76349d3bc91SRichard Lowe     curinst->dfp_args = ptr;
76449d3bc91SRichard Lowe     curinst->dfp_nbytes = nbytes;
76549d3bc91SRichard Lowe     curinst->dfp_next = NULL;
76649d3bc91SRichard Lowe     _dwarf_pro_add_to_fde(fde, curinst);
767*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
76849d3bc91SRichard Lowe }
76949d3bc91SRichard Lowe 
77049d3bc91SRichard Lowe 
771*4d9fdb46SRobert Mustacchi /*  Instructions are added to an fde in the form of a linked
772*4d9fdb46SRobert Mustacchi     list. This function manages the linked list. */
77349d3bc91SRichard Lowe void
_dwarf_pro_add_to_fde(Dwarf_P_Fde fde,Dwarf_P_Frame_Pgm curinst)77449d3bc91SRichard Lowe _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst)
77549d3bc91SRichard Lowe {
77649d3bc91SRichard Lowe     if (fde->fde_last_inst) {
77707dc1947SRichard Lowe         fde->fde_last_inst->dfp_next = curinst;
77807dc1947SRichard Lowe         fde->fde_last_inst = curinst;
77907dc1947SRichard Lowe         fde->fde_n_inst++;
78007dc1947SRichard Lowe         fde->fde_n_bytes +=
78107dc1947SRichard Lowe             (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
78249d3bc91SRichard Lowe     } else {
78307dc1947SRichard Lowe         fde->fde_last_inst = curinst;
78407dc1947SRichard Lowe         fde->fde_inst = curinst;
78507dc1947SRichard Lowe         fde->fde_n_inst = 1;
78607dc1947SRichard Lowe         fde->fde_n_bytes =
78707dc1947SRichard Lowe             (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
78849d3bc91SRichard Lowe     }
78949d3bc91SRichard Lowe }
790