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