xref: /titanic_50/usr/src/lib/libdwarf/common/pro_section.c (revision f3e7f55e73a39377d55a030f124cc86b3b66a9cc)
1*f3e7f55eSRobert Mustacchi /*
2*f3e7f55eSRobert Mustacchi 
3*f3e7f55eSRobert Mustacchi   Copyright (C) 2000,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
4*f3e7f55eSRobert Mustacchi   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
5*f3e7f55eSRobert Mustacchi   Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
6*f3e7f55eSRobert Mustacchi 
7*f3e7f55eSRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
8*f3e7f55eSRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
9*f3e7f55eSRobert Mustacchi   as published by the Free Software Foundation.
10*f3e7f55eSRobert Mustacchi 
11*f3e7f55eSRobert Mustacchi   This program is distributed in the hope that it would be useful, but
12*f3e7f55eSRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
13*f3e7f55eSRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14*f3e7f55eSRobert Mustacchi 
15*f3e7f55eSRobert Mustacchi   Further, this software is distributed without any warranty that it is
16*f3e7f55eSRobert Mustacchi   free of the rightful claim of any third person regarding infringement
17*f3e7f55eSRobert Mustacchi   or the like.  Any license provided herein, whether implied or
18*f3e7f55eSRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
19*f3e7f55eSRobert Mustacchi   any, provided herein do not apply to combinations of this program with
20*f3e7f55eSRobert Mustacchi   other software, or any other product whatsoever.
21*f3e7f55eSRobert Mustacchi 
22*f3e7f55eSRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
23*f3e7f55eSRobert Mustacchi   License along with this program; if not, write the Free Software
24*f3e7f55eSRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25*f3e7f55eSRobert Mustacchi   USA.
26*f3e7f55eSRobert Mustacchi 
27*f3e7f55eSRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
28*f3e7f55eSRobert Mustacchi   Mountain View, CA 94043, or:
29*f3e7f55eSRobert Mustacchi 
30*f3e7f55eSRobert Mustacchi   http://www.sgi.com
31*f3e7f55eSRobert Mustacchi 
32*f3e7f55eSRobert Mustacchi   For further information regarding this notice, see:
33*f3e7f55eSRobert Mustacchi 
34*f3e7f55eSRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
35*f3e7f55eSRobert Mustacchi 
36*f3e7f55eSRobert Mustacchi */
37*f3e7f55eSRobert Mustacchi /*
38*f3e7f55eSRobert Mustacchi    SGI has moved from the Crittenden Lane address.
39*f3e7f55eSRobert Mustacchi */
40*f3e7f55eSRobert Mustacchi 
41*f3e7f55eSRobert Mustacchi 
42*f3e7f55eSRobert Mustacchi 
43*f3e7f55eSRobert Mustacchi 
44*f3e7f55eSRobert Mustacchi 
45*f3e7f55eSRobert Mustacchi #include "config.h"
46*f3e7f55eSRobert Mustacchi #include "libdwarfdefs.h"
47*f3e7f55eSRobert Mustacchi #include <stdio.h>
48*f3e7f55eSRobert Mustacchi #include <string.h>
49*f3e7f55eSRobert Mustacchi #ifdef   HAVE_ELFACCESS_H
50*f3e7f55eSRobert Mustacchi #include <elfaccess.h>
51*f3e7f55eSRobert Mustacchi #endif
52*f3e7f55eSRobert Mustacchi #include "pro_incl.h"
53*f3e7f55eSRobert Mustacchi #include "pro_section.h"
54*f3e7f55eSRobert Mustacchi #include "pro_line.h"
55*f3e7f55eSRobert Mustacchi #include "pro_frame.h"
56*f3e7f55eSRobert Mustacchi #include "pro_die.h"
57*f3e7f55eSRobert Mustacchi #include "pro_macinfo.h"
58*f3e7f55eSRobert Mustacchi #include "pro_types.h"
59*f3e7f55eSRobert Mustacchi 
60*f3e7f55eSRobert Mustacchi #ifndef SHF_MIPS_NOSTRIP
61*f3e7f55eSRobert Mustacchi /* if this is not defined, we probably don't need it: just use 0 */
62*f3e7f55eSRobert Mustacchi #define SHF_MIPS_NOSTRIP 0
63*f3e7f55eSRobert Mustacchi #endif
64*f3e7f55eSRobert Mustacchi #ifndef R_MIPS_NONE
65*f3e7f55eSRobert Mustacchi #define R_MIPS_NONE 0
66*f3e7f55eSRobert Mustacchi #endif
67*f3e7f55eSRobert Mustacchi 
68*f3e7f55eSRobert Mustacchi #ifndef TRUE
69*f3e7f55eSRobert Mustacchi #define TRUE 1
70*f3e7f55eSRobert Mustacchi #endif
71*f3e7f55eSRobert Mustacchi #ifndef FALSE
72*f3e7f55eSRobert Mustacchi #define FALSE 0
73*f3e7f55eSRobert Mustacchi #endif
74*f3e7f55eSRobert Mustacchi 
75*f3e7f55eSRobert Mustacchi /* must match up with pro_section.h defines of DEBUG_INFO etc
76*f3e7f55eSRobert Mustacchi and sectnames (below).  REL_SEC_PREFIX is either ".rel" or ".rela"
77*f3e7f55eSRobert Mustacchi see pro_incl.h
78*f3e7f55eSRobert Mustacchi */
79*f3e7f55eSRobert Mustacchi char *_dwarf_rel_section_names[] = {
80*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_info",
81*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_line",
82*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_abbrev",     /* no relocations on this, really */
83*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_frame",
84*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_aranges",
85*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_pubnames",
86*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_str",
87*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_funcnames",  /* sgi extension */
88*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_typenames",  /* sgi extension */
89*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_varnames",   /* sgi extension */
90*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_weaknames",  /* sgi extension */
91*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_macinfo",
92*f3e7f55eSRobert Mustacchi     REL_SEC_PREFIX ".debug_loc"
93*f3e7f55eSRobert Mustacchi };
94*f3e7f55eSRobert Mustacchi 
95*f3e7f55eSRobert Mustacchi /* names of sections. Ensure that it matches the defines
96*f3e7f55eSRobert Mustacchi    in pro_section.h, in the same order
97*f3e7f55eSRobert Mustacchi    Must match also _dwarf_rel_section_names above
98*f3e7f55eSRobert Mustacchi */
99*f3e7f55eSRobert Mustacchi char *_dwarf_sectnames[] = {
100*f3e7f55eSRobert Mustacchi     ".debug_info",
101*f3e7f55eSRobert Mustacchi     ".debug_line",
102*f3e7f55eSRobert Mustacchi     ".debug_abbrev",
103*f3e7f55eSRobert Mustacchi     ".debug_frame",
104*f3e7f55eSRobert Mustacchi     ".debug_aranges",
105*f3e7f55eSRobert Mustacchi     ".debug_pubnames",
106*f3e7f55eSRobert Mustacchi     ".debug_str",
107*f3e7f55eSRobert Mustacchi     ".debug_funcnames",         /* sgi extension */
108*f3e7f55eSRobert Mustacchi     ".debug_typenames",         /* sgi extension */
109*f3e7f55eSRobert Mustacchi     ".debug_varnames",          /* sgi extension */
110*f3e7f55eSRobert Mustacchi     ".debug_weaknames",         /* sgi extension */
111*f3e7f55eSRobert Mustacchi     ".debug_macinfo",
112*f3e7f55eSRobert Mustacchi     ".debug_loc"
113*f3e7f55eSRobert Mustacchi };
114*f3e7f55eSRobert Mustacchi 
115*f3e7f55eSRobert Mustacchi 
116*f3e7f55eSRobert Mustacchi 
117*f3e7f55eSRobert Mustacchi 
118*f3e7f55eSRobert Mustacchi static Dwarf_Ubyte std_opcode_len[] = { 0,      /* DW_LNS_copy */
119*f3e7f55eSRobert Mustacchi     1,                          /* DW_LNS_advance_pc */
120*f3e7f55eSRobert Mustacchi     1,                          /* DW_LNS_advance_line */
121*f3e7f55eSRobert Mustacchi     1,                          /* DW_LNS_set_file */
122*f3e7f55eSRobert Mustacchi     1,                          /* DW_LNS_set_column */
123*f3e7f55eSRobert Mustacchi     0,                          /* DW_LNS_negate_stmt */
124*f3e7f55eSRobert Mustacchi     0,                          /* DW_LNS_set_basic_block */
125*f3e7f55eSRobert Mustacchi     0,                          /* DW_LNS_const_add_pc */
126*f3e7f55eSRobert Mustacchi     1,                          /* DW_LNS_fixed_advance_pc */
127*f3e7f55eSRobert Mustacchi };
128*f3e7f55eSRobert Mustacchi 
129*f3e7f55eSRobert Mustacchi /* struct to hold relocation entries. Its mantained as a linked
130*f3e7f55eSRobert Mustacchi    list of relocation structs, and will then be written at as a
131*f3e7f55eSRobert Mustacchi    whole into the relocation section. Whether its 32 bit or
132*f3e7f55eSRobert Mustacchi    64 bit will be obtained from Dwarf_Debug pointer.
133*f3e7f55eSRobert Mustacchi */
134*f3e7f55eSRobert Mustacchi 
135*f3e7f55eSRobert Mustacchi typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel;
136*f3e7f55eSRobert Mustacchi struct Dwarf_P_Rel_s {
137*f3e7f55eSRobert Mustacchi     Dwarf_P_Rel dr_next;
138*f3e7f55eSRobert Mustacchi     void *dr_rel_datap;
139*f3e7f55eSRobert Mustacchi };
140*f3e7f55eSRobert Mustacchi typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head;
141*f3e7f55eSRobert Mustacchi struct Dwarf_P_Rel_Head_s {
142*f3e7f55eSRobert Mustacchi     struct Dwarf_P_Rel_s *drh_head;
143*f3e7f55eSRobert Mustacchi     struct Dwarf_P_Rel_s *drh_tail;
144*f3e7f55eSRobert Mustacchi };
145*f3e7f55eSRobert Mustacchi 
146*f3e7f55eSRobert Mustacchi static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
147*f3e7f55eSRobert Mustacchi                                          Dwarf_Error * error);
148*f3e7f55eSRobert Mustacchi static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
149*f3e7f55eSRobert Mustacchi                                           Dwarf_Error * error);
150*f3e7f55eSRobert Mustacchi static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
151*f3e7f55eSRobert Mustacchi                                          Dwarf_Error * error);
152*f3e7f55eSRobert Mustacchi static Dwarf_P_Abbrev _dwarf_pro_getabbrev(Dwarf_P_Die, Dwarf_P_Abbrev);
153*f3e7f55eSRobert Mustacchi static int _dwarf_pro_match_attr
154*f3e7f55eSRobert Mustacchi     (Dwarf_P_Attribute, Dwarf_P_Abbrev, int no_attr);
155*f3e7f55eSRobert Mustacchi 
156*f3e7f55eSRobert Mustacchi /* these macros used as return value for below functions */
157*f3e7f55eSRobert Mustacchi #define         OPC_INCS_ZERO           -1
158*f3e7f55eSRobert Mustacchi #define         OPC_OUT_OF_RANGE        -2
159*f3e7f55eSRobert Mustacchi #define         LINE_OUT_OF_RANGE       -3
160*f3e7f55eSRobert Mustacchi static int _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv);
161*f3e7f55eSRobert Mustacchi 
162*f3e7f55eSRobert Mustacchi 
163*f3e7f55eSRobert Mustacchi /* BEGIN_LEN_SIZE is the size of the 'length' field in total.
164*f3e7f55eSRobert Mustacchi    Which may be 4,8, or 12 bytes!
165*f3e7f55eSRobert Mustacchi    4 is standard DWARF2.
166*f3e7f55eSRobert Mustacchi    8 is non-standard MIPS-IRIX 64-bit.
167*f3e7f55eSRobert Mustacchi    12 is standard DWARF3 for 64 bit offsets.
168*f3e7f55eSRobert Mustacchi    Used in various routines: local variable names
169*f3e7f55eSRobert Mustacchi    must match the names here.
170*f3e7f55eSRobert Mustacchi */
171*f3e7f55eSRobert Mustacchi #define BEGIN_LEN_SIZE (uwordb_size + extension_size)
172*f3e7f55eSRobert Mustacchi 
173*f3e7f55eSRobert Mustacchi /*
174*f3e7f55eSRobert Mustacchi         Return TRUE if we need the section, FALSE otherwise
175*f3e7f55eSRobert Mustacchi 
176*f3e7f55eSRobert Mustacchi         If any of the 'line-data-related' calls were made
177*f3e7f55eSRobert Mustacchi         including file or directory entries,
178*f3e7f55eSRobert Mustacchi         produce .debug_line .
179*f3e7f55eSRobert Mustacchi 
180*f3e7f55eSRobert Mustacchi */
181*f3e7f55eSRobert Mustacchi static int
dwarf_need_debug_line_section(Dwarf_P_Debug dbg)182*f3e7f55eSRobert Mustacchi dwarf_need_debug_line_section(Dwarf_P_Debug dbg)
183*f3e7f55eSRobert Mustacchi {
184*f3e7f55eSRobert Mustacchi     if (dbg->de_lines == NULL && dbg->de_file_entries == NULL
185*f3e7f55eSRobert Mustacchi         && dbg->de_inc_dirs == NULL) {
186*f3e7f55eSRobert Mustacchi         return FALSE;
187*f3e7f55eSRobert Mustacchi     }
188*f3e7f55eSRobert Mustacchi     return TRUE;
189*f3e7f55eSRobert Mustacchi }
190*f3e7f55eSRobert Mustacchi 
191*f3e7f55eSRobert Mustacchi /*
192*f3e7f55eSRobert Mustacchi     Convert debug information to  a format such that
193*f3e7f55eSRobert Mustacchi     it can be written on disk.
194*f3e7f55eSRobert Mustacchi     Called exactly once per execution.
195*f3e7f55eSRobert Mustacchi */
196*f3e7f55eSRobert Mustacchi Dwarf_Signed
dwarf_transform_to_disk_form(Dwarf_P_Debug dbg,Dwarf_Error * error)197*f3e7f55eSRobert Mustacchi dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error)
198*f3e7f55eSRobert Mustacchi {
199*f3e7f55eSRobert Mustacchi     /*
200*f3e7f55eSRobert Mustacchi        Section data in written out in a number of buffers. Each
201*f3e7f55eSRobert Mustacchi        _generate_*() function returns a cumulative count of buffers for
202*f3e7f55eSRobert Mustacchi        all the sections. get_section_bytes() returns pointers to these
203*f3e7f55eSRobert Mustacchi        buffers one at a time. */
204*f3e7f55eSRobert Mustacchi     int nbufs = 0;
205*f3e7f55eSRobert Mustacchi     int sect = 0;
206*f3e7f55eSRobert Mustacchi     int err = 0;
207*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned du = 0;
208*f3e7f55eSRobert Mustacchi 
209*f3e7f55eSRobert Mustacchi     if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
210*f3e7f55eSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT);
211*f3e7f55eSRobert Mustacchi     }
212*f3e7f55eSRobert Mustacchi 
213*f3e7f55eSRobert Mustacchi     /* Create dwarf section headers */
214*f3e7f55eSRobert Mustacchi     for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) {
215*f3e7f55eSRobert Mustacchi         long flags = 0;
216*f3e7f55eSRobert Mustacchi 
217*f3e7f55eSRobert Mustacchi         switch (sect) {
218*f3e7f55eSRobert Mustacchi 
219*f3e7f55eSRobert Mustacchi         case DEBUG_INFO:
220*f3e7f55eSRobert Mustacchi             if (dbg->de_dies == NULL)
221*f3e7f55eSRobert Mustacchi                 continue;
222*f3e7f55eSRobert Mustacchi             break;
223*f3e7f55eSRobert Mustacchi 
224*f3e7f55eSRobert Mustacchi         case DEBUG_LINE:
225*f3e7f55eSRobert Mustacchi             if (dwarf_need_debug_line_section(dbg) == FALSE) {
226*f3e7f55eSRobert Mustacchi                 continue;
227*f3e7f55eSRobert Mustacchi             }
228*f3e7f55eSRobert Mustacchi             break;
229*f3e7f55eSRobert Mustacchi 
230*f3e7f55eSRobert Mustacchi         case DEBUG_ABBREV:
231*f3e7f55eSRobert Mustacchi             if (dbg->de_dies == NULL)
232*f3e7f55eSRobert Mustacchi                 continue;
233*f3e7f55eSRobert Mustacchi             break;
234*f3e7f55eSRobert Mustacchi 
235*f3e7f55eSRobert Mustacchi         case DEBUG_FRAME:
236*f3e7f55eSRobert Mustacchi             if (dbg->de_frame_cies == NULL)
237*f3e7f55eSRobert Mustacchi                 continue;
238*f3e7f55eSRobert Mustacchi             flags = SHF_MIPS_NOSTRIP;
239*f3e7f55eSRobert Mustacchi             break;
240*f3e7f55eSRobert Mustacchi 
241*f3e7f55eSRobert Mustacchi         case DEBUG_ARANGES:
242*f3e7f55eSRobert Mustacchi             if (dbg->de_arange == NULL)
243*f3e7f55eSRobert Mustacchi                 continue;
244*f3e7f55eSRobert Mustacchi             break;
245*f3e7f55eSRobert Mustacchi 
246*f3e7f55eSRobert Mustacchi         case DEBUG_PUBNAMES:
247*f3e7f55eSRobert Mustacchi             if (dbg->de_simple_name_headers[dwarf_snk_pubname].
248*f3e7f55eSRobert Mustacchi                 sn_head == NULL)
249*f3e7f55eSRobert Mustacchi                 continue;
250*f3e7f55eSRobert Mustacchi             break;
251*f3e7f55eSRobert Mustacchi 
252*f3e7f55eSRobert Mustacchi         case DEBUG_STR:
253*f3e7f55eSRobert Mustacchi             if (dbg->de_strings == NULL)
254*f3e7f55eSRobert Mustacchi                 continue;
255*f3e7f55eSRobert Mustacchi             break;
256*f3e7f55eSRobert Mustacchi 
257*f3e7f55eSRobert Mustacchi         case DEBUG_FUNCNAMES:
258*f3e7f55eSRobert Mustacchi             if (dbg->de_simple_name_headers[dwarf_snk_funcname].
259*f3e7f55eSRobert Mustacchi                 sn_head == NULL)
260*f3e7f55eSRobert Mustacchi                 continue;
261*f3e7f55eSRobert Mustacchi             break;
262*f3e7f55eSRobert Mustacchi 
263*f3e7f55eSRobert Mustacchi         case DEBUG_TYPENAMES:
264*f3e7f55eSRobert Mustacchi             if (dbg->de_simple_name_headers[dwarf_snk_typename].
265*f3e7f55eSRobert Mustacchi                 sn_head == NULL)
266*f3e7f55eSRobert Mustacchi                 continue;
267*f3e7f55eSRobert Mustacchi             break;
268*f3e7f55eSRobert Mustacchi 
269*f3e7f55eSRobert Mustacchi         case DEBUG_VARNAMES:
270*f3e7f55eSRobert Mustacchi             if (dbg->de_simple_name_headers[dwarf_snk_varname].
271*f3e7f55eSRobert Mustacchi                 sn_head == NULL)
272*f3e7f55eSRobert Mustacchi                 continue;
273*f3e7f55eSRobert Mustacchi             break;
274*f3e7f55eSRobert Mustacchi 
275*f3e7f55eSRobert Mustacchi         case DEBUG_WEAKNAMES:
276*f3e7f55eSRobert Mustacchi             if (dbg->de_simple_name_headers[dwarf_snk_weakname].
277*f3e7f55eSRobert Mustacchi                 sn_head == NULL)
278*f3e7f55eSRobert Mustacchi                 continue;
279*f3e7f55eSRobert Mustacchi             break;
280*f3e7f55eSRobert Mustacchi 
281*f3e7f55eSRobert Mustacchi         case DEBUG_MACINFO:
282*f3e7f55eSRobert Mustacchi             if (dbg->de_first_macinfo == NULL)
283*f3e7f55eSRobert Mustacchi                 continue;
284*f3e7f55eSRobert Mustacchi             break;
285*f3e7f55eSRobert Mustacchi         case DEBUG_LOC:
286*f3e7f55eSRobert Mustacchi             /* not handled yet */
287*f3e7f55eSRobert Mustacchi             continue;
288*f3e7f55eSRobert Mustacchi         default:
289*f3e7f55eSRobert Mustacchi             /* logic error: missing a case */
290*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT);
291*f3e7f55eSRobert Mustacchi         }
292*f3e7f55eSRobert Mustacchi         {
293*f3e7f55eSRobert Mustacchi             int new_base_elf_sect;
294*f3e7f55eSRobert Mustacchi 
295*f3e7f55eSRobert Mustacchi             if (dbg->de_callback_func_b) {
296*f3e7f55eSRobert Mustacchi                 new_base_elf_sect =
297*f3e7f55eSRobert Mustacchi                     dbg->de_callback_func_b(_dwarf_sectnames[sect],
298*f3e7f55eSRobert Mustacchi                         /* rec size */ 1,
299*f3e7f55eSRobert Mustacchi                         SECTION_TYPE,
300*f3e7f55eSRobert Mustacchi                         flags, SHN_UNDEF, 0, &du, &err);
301*f3e7f55eSRobert Mustacchi 
302*f3e7f55eSRobert Mustacchi             } else {
303*f3e7f55eSRobert Mustacchi                 int name_idx = 0;
304*f3e7f55eSRobert Mustacchi                 new_base_elf_sect = dbg->de_callback_func(
305*f3e7f55eSRobert Mustacchi                     _dwarf_sectnames[sect],
306*f3e7f55eSRobert Mustacchi                     dbg->de_relocation_record_size,
307*f3e7f55eSRobert Mustacchi                     SECTION_TYPE, flags,
308*f3e7f55eSRobert Mustacchi                     SHN_UNDEF, 0,
309*f3e7f55eSRobert Mustacchi                     &name_idx, &err);
310*f3e7f55eSRobert Mustacchi                 du = name_idx;
311*f3e7f55eSRobert Mustacchi             }
312*f3e7f55eSRobert Mustacchi             if (new_base_elf_sect == -1) {
313*f3e7f55eSRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR,
314*f3e7f55eSRobert Mustacchi                                   DW_DLV_NOCOUNT);
315*f3e7f55eSRobert Mustacchi             }
316*f3e7f55eSRobert Mustacchi             dbg->de_elf_sects[sect] = new_base_elf_sect;
317*f3e7f55eSRobert Mustacchi 
318*f3e7f55eSRobert Mustacchi             dbg->de_sect_name_idx[sect] = du;
319*f3e7f55eSRobert Mustacchi         }
320*f3e7f55eSRobert Mustacchi     }
321*f3e7f55eSRobert Mustacchi 
322*f3e7f55eSRobert Mustacchi     nbufs = 0;
323*f3e7f55eSRobert Mustacchi 
324*f3e7f55eSRobert Mustacchi     /*
325*f3e7f55eSRobert Mustacchi        Changing the order in which the sections are generated may cause
326*f3e7f55eSRobert Mustacchi        problems because of relocations. */
327*f3e7f55eSRobert Mustacchi 
328*f3e7f55eSRobert Mustacchi     if (dwarf_need_debug_line_section(dbg) == TRUE) {
329*f3e7f55eSRobert Mustacchi         nbufs = _dwarf_pro_generate_debugline(dbg, error);
330*f3e7f55eSRobert Mustacchi         if (nbufs < 0) {
331*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR,
332*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
333*f3e7f55eSRobert Mustacchi         }
334*f3e7f55eSRobert Mustacchi     }
335*f3e7f55eSRobert Mustacchi 
336*f3e7f55eSRobert Mustacchi     if (dbg->de_frame_cies) {
337*f3e7f55eSRobert Mustacchi         nbufs = _dwarf_pro_generate_debugframe(dbg, error);
338*f3e7f55eSRobert Mustacchi         if (nbufs < 0) {
339*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR,
340*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
341*f3e7f55eSRobert Mustacchi         }
342*f3e7f55eSRobert Mustacchi     }
343*f3e7f55eSRobert Mustacchi     if (dbg->de_first_macinfo) {
344*f3e7f55eSRobert Mustacchi         nbufs = _dwarf_pro_transform_macro_info_to_disk(dbg, error);
345*f3e7f55eSRobert Mustacchi         if (nbufs < 0) {
346*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGMACINFO_ERROR,
347*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
348*f3e7f55eSRobert Mustacchi         }
349*f3e7f55eSRobert Mustacchi     }
350*f3e7f55eSRobert Mustacchi 
351*f3e7f55eSRobert Mustacchi     if (dbg->de_dies) {
352*f3e7f55eSRobert Mustacchi         nbufs = _dwarf_pro_generate_debuginfo(dbg, error);
353*f3e7f55eSRobert Mustacchi         if (nbufs < 0) {
354*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
355*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
356*f3e7f55eSRobert Mustacchi         }
357*f3e7f55eSRobert Mustacchi     }
358*f3e7f55eSRobert Mustacchi 
359*f3e7f55eSRobert Mustacchi     if (dbg->de_arange) {
360*f3e7f55eSRobert Mustacchi         nbufs = _dwarf_transform_arange_to_disk(dbg, error);
361*f3e7f55eSRobert Mustacchi         if (nbufs < 0) {
362*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
363*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
364*f3e7f55eSRobert Mustacchi         }
365*f3e7f55eSRobert Mustacchi     }
366*f3e7f55eSRobert Mustacchi 
367*f3e7f55eSRobert Mustacchi     if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) {
368*f3e7f55eSRobert Mustacchi         nbufs = _dwarf_transform_simplename_to_disk(dbg,
369*f3e7f55eSRobert Mustacchi                                                     dwarf_snk_pubname,
370*f3e7f55eSRobert Mustacchi                                                     DEBUG_PUBNAMES,
371*f3e7f55eSRobert Mustacchi                                                     error);
372*f3e7f55eSRobert Mustacchi 
373*f3e7f55eSRobert Mustacchi 
374*f3e7f55eSRobert Mustacchi         if (nbufs < 0) {
375*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
376*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
377*f3e7f55eSRobert Mustacchi         }
378*f3e7f55eSRobert Mustacchi     }
379*f3e7f55eSRobert Mustacchi 
380*f3e7f55eSRobert Mustacchi     if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) {
381*f3e7f55eSRobert Mustacchi         nbufs = _dwarf_transform_simplename_to_disk(dbg,
382*f3e7f55eSRobert Mustacchi                                                     dwarf_snk_funcname,
383*f3e7f55eSRobert Mustacchi                                                     DEBUG_FUNCNAMES,
384*f3e7f55eSRobert Mustacchi                                                     error);
385*f3e7f55eSRobert Mustacchi         if (nbufs < 0) {
386*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
387*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
388*f3e7f55eSRobert Mustacchi         }
389*f3e7f55eSRobert Mustacchi     }
390*f3e7f55eSRobert Mustacchi 
391*f3e7f55eSRobert Mustacchi     if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) {
392*f3e7f55eSRobert Mustacchi         nbufs = _dwarf_transform_simplename_to_disk(dbg,
393*f3e7f55eSRobert Mustacchi                                                     dwarf_snk_typename,
394*f3e7f55eSRobert Mustacchi                                                     DEBUG_TYPENAMES,
395*f3e7f55eSRobert Mustacchi                                                     error);
396*f3e7f55eSRobert Mustacchi         if (nbufs < 0) {
397*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
398*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
399*f3e7f55eSRobert Mustacchi         }
400*f3e7f55eSRobert Mustacchi     }
401*f3e7f55eSRobert Mustacchi 
402*f3e7f55eSRobert Mustacchi     if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) {
403*f3e7f55eSRobert Mustacchi         nbufs = _dwarf_transform_simplename_to_disk(dbg,
404*f3e7f55eSRobert Mustacchi                                                     dwarf_snk_varname,
405*f3e7f55eSRobert Mustacchi                                                     DEBUG_VARNAMES,
406*f3e7f55eSRobert Mustacchi                                                     error);
407*f3e7f55eSRobert Mustacchi 
408*f3e7f55eSRobert Mustacchi         if (nbufs < 0) {
409*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
410*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
411*f3e7f55eSRobert Mustacchi         }
412*f3e7f55eSRobert Mustacchi     }
413*f3e7f55eSRobert Mustacchi 
414*f3e7f55eSRobert Mustacchi     if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) {
415*f3e7f55eSRobert Mustacchi         nbufs = _dwarf_transform_simplename_to_disk(dbg,
416*f3e7f55eSRobert Mustacchi             dwarf_snk_weakname, DEBUG_WEAKNAMES, error);
417*f3e7f55eSRobert Mustacchi         if (nbufs < 0) {
418*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
419*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
420*f3e7f55eSRobert Mustacchi         }
421*f3e7f55eSRobert Mustacchi     }
422*f3e7f55eSRobert Mustacchi 
423*f3e7f55eSRobert Mustacchi     {
424*f3e7f55eSRobert Mustacchi         Dwarf_Signed new_secs = 0;
425*f3e7f55eSRobert Mustacchi         int res = 0;
426*f3e7f55eSRobert Mustacchi 
427*f3e7f55eSRobert Mustacchi         res = dbg->de_transform_relocs_to_disk(dbg, &new_secs);
428*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
429*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
430*f3e7f55eSRobert Mustacchi                               DW_DLV_NOCOUNT);
431*f3e7f55eSRobert Mustacchi         }
432*f3e7f55eSRobert Mustacchi         nbufs += new_secs;
433*f3e7f55eSRobert Mustacchi     }
434*f3e7f55eSRobert Mustacchi     return nbufs;
435*f3e7f55eSRobert Mustacchi }
436*f3e7f55eSRobert Mustacchi 
437*f3e7f55eSRobert Mustacchi 
438*f3e7f55eSRobert Mustacchi /*---------------------------------------------------------------
439*f3e7f55eSRobert Mustacchi         Generate debug_line section
440*f3e7f55eSRobert Mustacchi ---------------------------------------------------------------*/
441*f3e7f55eSRobert Mustacchi static int
_dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,Dwarf_Error * error)442*f3e7f55eSRobert Mustacchi _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error)
443*f3e7f55eSRobert Mustacchi {
444*f3e7f55eSRobert Mustacchi     Dwarf_P_Inc_Dir curdir = 0;
445*f3e7f55eSRobert Mustacchi     Dwarf_P_F_Entry curentry = 0;
446*f3e7f55eSRobert Mustacchi     Dwarf_P_Line curline = 0;
447*f3e7f55eSRobert Mustacchi     Dwarf_P_Line prevline = 0;
448*f3e7f55eSRobert Mustacchi 
449*f3e7f55eSRobert Mustacchi     /* all data named cur* are used to loop thru linked lists */
450*f3e7f55eSRobert Mustacchi 
451*f3e7f55eSRobert Mustacchi     int sum_bytes = 0;
452*f3e7f55eSRobert Mustacchi     int prolog_size = 0;
453*f3e7f55eSRobert Mustacchi     unsigned char *data = 0;    /* holds disk form data */
454*f3e7f55eSRobert Mustacchi     int elfsectno = 0;
455*f3e7f55eSRobert Mustacchi     unsigned char *start_line_sec = 0;  /* pointer to the buffer at
456*f3e7f55eSRobert Mustacchi                                            section start */
457*f3e7f55eSRobert Mustacchi     /* temps for memcpy */
458*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned du = 0;
459*f3e7f55eSRobert Mustacchi     Dwarf_Ubyte db = 0;
460*f3e7f55eSRobert Mustacchi     Dwarf_Half dh = 0;
461*f3e7f55eSRobert Mustacchi     int res = 0;
462*f3e7f55eSRobert Mustacchi     int uwordb_size = dbg->de_offset_size;
463*f3e7f55eSRobert Mustacchi     int extension_size = dbg->de_64bit_extension ? 4 : 0;
464*f3e7f55eSRobert Mustacchi     int upointer_size = dbg->de_pointer_size;
465*f3e7f55eSRobert Mustacchi     char buff1[ENCODE_SPACE_NEEDED];
466*f3e7f55eSRobert Mustacchi 
467*f3e7f55eSRobert Mustacchi 
468*f3e7f55eSRobert Mustacchi 
469*f3e7f55eSRobert Mustacchi     sum_bytes = 0;
470*f3e7f55eSRobert Mustacchi 
471*f3e7f55eSRobert Mustacchi     elfsectno = dbg->de_elf_sects[DEBUG_LINE];
472*f3e7f55eSRobert Mustacchi 
473*f3e7f55eSRobert Mustacchi     /* include directories */
474*f3e7f55eSRobert Mustacchi     curdir = dbg->de_inc_dirs;
475*f3e7f55eSRobert Mustacchi     while (curdir) {
476*f3e7f55eSRobert Mustacchi         prolog_size += strlen(curdir->did_name) + 1;
477*f3e7f55eSRobert Mustacchi         curdir = curdir->did_next;
478*f3e7f55eSRobert Mustacchi     }
479*f3e7f55eSRobert Mustacchi     prolog_size++;              /* last null following last directory
480*f3e7f55eSRobert Mustacchi                                    entry. */
481*f3e7f55eSRobert Mustacchi 
482*f3e7f55eSRobert Mustacchi     /* file entries */
483*f3e7f55eSRobert Mustacchi     curentry = dbg->de_file_entries;
484*f3e7f55eSRobert Mustacchi     while (curentry) {
485*f3e7f55eSRobert Mustacchi         prolog_size +=
486*f3e7f55eSRobert Mustacchi             strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes;
487*f3e7f55eSRobert Mustacchi         curentry = curentry->dfe_next;
488*f3e7f55eSRobert Mustacchi     }
489*f3e7f55eSRobert Mustacchi     prolog_size++;              /* last null byte */
490*f3e7f55eSRobert Mustacchi 
491*f3e7f55eSRobert Mustacchi 
492*f3e7f55eSRobert Mustacchi     prolog_size += BEGIN_LEN_SIZE + sizeof_uhalf(dbg) + /* version # */
493*f3e7f55eSRobert Mustacchi         uwordb_size +           /* header length */
494*f3e7f55eSRobert Mustacchi         sizeof_ubyte(dbg) +     /* min_instr length */
495*f3e7f55eSRobert Mustacchi         sizeof_ubyte(dbg) +     /* default is_stmt */
496*f3e7f55eSRobert Mustacchi         sizeof_ubyte(dbg) +     /* linebase */
497*f3e7f55eSRobert Mustacchi         sizeof_ubyte(dbg) +     /* linerange */
498*f3e7f55eSRobert Mustacchi         sizeof_ubyte(dbg);      /* opcode base */
499*f3e7f55eSRobert Mustacchi 
500*f3e7f55eSRobert Mustacchi     /* length of table specifying # of opnds */
501*f3e7f55eSRobert Mustacchi     prolog_size += sizeof(std_opcode_len);
502*f3e7f55eSRobert Mustacchi 
503*f3e7f55eSRobert Mustacchi     GET_CHUNK(dbg, elfsectno, data, prolog_size, error);
504*f3e7f55eSRobert Mustacchi     start_line_sec = data;
505*f3e7f55eSRobert Mustacchi 
506*f3e7f55eSRobert Mustacchi     /* copy over the data */
507*f3e7f55eSRobert Mustacchi     /* total_length */
508*f3e7f55eSRobert Mustacchi     du = 0;
509*f3e7f55eSRobert Mustacchi     if (extension_size) {
510*f3e7f55eSRobert Mustacchi         Dwarf_Word x = DISTINGUISHED_VALUE;
511*f3e7f55eSRobert Mustacchi 
512*f3e7f55eSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &x,
513*f3e7f55eSRobert Mustacchi                         sizeof(x), extension_size);
514*f3e7f55eSRobert Mustacchi         data += extension_size;
515*f3e7f55eSRobert Mustacchi     }
516*f3e7f55eSRobert Mustacchi 
517*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
518*f3e7f55eSRobert Mustacchi                     sizeof(du), uwordb_size);
519*f3e7f55eSRobert Mustacchi     data += uwordb_size;
520*f3e7f55eSRobert Mustacchi 
521*f3e7f55eSRobert Mustacchi     dh = VERSION;
522*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh,
523*f3e7f55eSRobert Mustacchi                     sizeof(dh), sizeof(Dwarf_Half));
524*f3e7f55eSRobert Mustacchi     data += sizeof(Dwarf_Half);
525*f3e7f55eSRobert Mustacchi 
526*f3e7f55eSRobert Mustacchi     /* header length */
527*f3e7f55eSRobert Mustacchi     du = prolog_size - (BEGIN_LEN_SIZE + sizeof(Dwarf_Half) +
528*f3e7f55eSRobert Mustacchi                         uwordb_size);
529*f3e7f55eSRobert Mustacchi     {
530*f3e7f55eSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
531*f3e7f55eSRobert Mustacchi                         sizeof(du), uwordb_size);
532*f3e7f55eSRobert Mustacchi         data += uwordb_size;
533*f3e7f55eSRobert Mustacchi     }
534*f3e7f55eSRobert Mustacchi     db = MIN_INST_LENGTH;
535*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
536*f3e7f55eSRobert Mustacchi                     sizeof(db), sizeof(Dwarf_Ubyte));
537*f3e7f55eSRobert Mustacchi     data += sizeof(Dwarf_Ubyte);
538*f3e7f55eSRobert Mustacchi     db = DEFAULT_IS_STMT;
539*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
540*f3e7f55eSRobert Mustacchi                     sizeof(db), sizeof(Dwarf_Ubyte));
541*f3e7f55eSRobert Mustacchi     data += sizeof(Dwarf_Ubyte);
542*f3e7f55eSRobert Mustacchi     db = (Dwarf_Ubyte) LINE_BASE;
543*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
544*f3e7f55eSRobert Mustacchi                     sizeof(db), sizeof(Dwarf_Ubyte));
545*f3e7f55eSRobert Mustacchi     data += sizeof(Dwarf_Ubyte);
546*f3e7f55eSRobert Mustacchi     db = LINE_RANGE;
547*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
548*f3e7f55eSRobert Mustacchi                     sizeof(db), sizeof(Dwarf_Ubyte));
549*f3e7f55eSRobert Mustacchi     data += sizeof(Dwarf_Ubyte);
550*f3e7f55eSRobert Mustacchi     db = OPCODE_BASE;
551*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
552*f3e7f55eSRobert Mustacchi                     sizeof(db), sizeof(Dwarf_Ubyte));
553*f3e7f55eSRobert Mustacchi     data += sizeof(Dwarf_Ubyte);
554*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len,
555*f3e7f55eSRobert Mustacchi                     sizeof(std_opcode_len), sizeof(std_opcode_len));
556*f3e7f55eSRobert Mustacchi     data += sizeof(std_opcode_len);
557*f3e7f55eSRobert Mustacchi 
558*f3e7f55eSRobert Mustacchi     /* copy over include directories */
559*f3e7f55eSRobert Mustacchi     curdir = dbg->de_inc_dirs;
560*f3e7f55eSRobert Mustacchi     while (curdir) {
561*f3e7f55eSRobert Mustacchi         strcpy((char *) data, curdir->did_name);
562*f3e7f55eSRobert Mustacchi         data += strlen(curdir->did_name) + 1;
563*f3e7f55eSRobert Mustacchi         curdir = curdir->did_next;
564*f3e7f55eSRobert Mustacchi     }
565*f3e7f55eSRobert Mustacchi     *data = '\0';               /* last null */
566*f3e7f55eSRobert Mustacchi     data++;
567*f3e7f55eSRobert Mustacchi 
568*f3e7f55eSRobert Mustacchi     /* copy file entries */
569*f3e7f55eSRobert Mustacchi     curentry = dbg->de_file_entries;
570*f3e7f55eSRobert Mustacchi     while (curentry) {
571*f3e7f55eSRobert Mustacchi         strcpy((char *) data, curentry->dfe_name);
572*f3e7f55eSRobert Mustacchi         data += strlen(curentry->dfe_name) + 1;
573*f3e7f55eSRobert Mustacchi         /* copies of leb numbers, no endian issues */
574*f3e7f55eSRobert Mustacchi         memcpy((void *) data,
575*f3e7f55eSRobert Mustacchi                (const void *) curentry->dfe_args, curentry->dfe_nbytes);
576*f3e7f55eSRobert Mustacchi         data += curentry->dfe_nbytes;
577*f3e7f55eSRobert Mustacchi         curentry = curentry->dfe_next;
578*f3e7f55eSRobert Mustacchi     }
579*f3e7f55eSRobert Mustacchi     *data = '\0';
580*f3e7f55eSRobert Mustacchi     data++;
581*f3e7f55eSRobert Mustacchi 
582*f3e7f55eSRobert Mustacchi     sum_bytes += prolog_size;
583*f3e7f55eSRobert Mustacchi 
584*f3e7f55eSRobert Mustacchi     curline = dbg->de_lines;
585*f3e7f55eSRobert Mustacchi     prevline = (Dwarf_P_Line)
586*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
587*f3e7f55eSRobert Mustacchi     if (prevline == NULL) {
588*f3e7f55eSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, -1);
589*f3e7f55eSRobert Mustacchi     }
590*f3e7f55eSRobert Mustacchi     _dwarf_pro_reg_init(prevline);
591*f3e7f55eSRobert Mustacchi     /* generate opcodes for line numbers */
592*f3e7f55eSRobert Mustacchi     while (curline) {
593*f3e7f55eSRobert Mustacchi         int nbytes;
594*f3e7f55eSRobert Mustacchi         char *arg;
595*f3e7f55eSRobert Mustacchi         int opc;
596*f3e7f55eSRobert Mustacchi         int no_lns_copy;        /* if lns copy opcode doesnt need to be
597*f3e7f55eSRobert Mustacchi                                    generated, if special opcode or end
598*f3e7f55eSRobert Mustacchi                                    sequence */
599*f3e7f55eSRobert Mustacchi         Dwarf_Unsigned addr_adv;
600*f3e7f55eSRobert Mustacchi         int line_adv;           /* supposed to be a reasonably small
601*f3e7f55eSRobert Mustacchi                                    number, so the size should not be a
602*f3e7f55eSRobert Mustacchi                                    problem. ? */
603*f3e7f55eSRobert Mustacchi 
604*f3e7f55eSRobert Mustacchi         no_lns_copy = 0;
605*f3e7f55eSRobert Mustacchi         if (curline->dpl_opc != 0) {
606*f3e7f55eSRobert Mustacchi             int inst_bytes;     /* no of bytes in extended opcode */
607*f3e7f55eSRobert Mustacchi             char *str;          /* hold leb encoded inst_bytes */
608*f3e7f55eSRobert Mustacchi             int str_nbytes;     /* no of bytes in str */
609*f3e7f55eSRobert Mustacchi 
610*f3e7f55eSRobert Mustacchi             switch (curline->dpl_opc) {
611*f3e7f55eSRobert Mustacchi             case DW_LNE_end_sequence:
612*f3e7f55eSRobert Mustacchi 
613*f3e7f55eSRobert Mustacchi                 /* Advance pc to end of text section. */
614*f3e7f55eSRobert Mustacchi                 addr_adv = curline->dpl_address - prevline->dpl_address;
615*f3e7f55eSRobert Mustacchi                 if (addr_adv > 0) {
616*f3e7f55eSRobert Mustacchi                     db = DW_LNS_advance_pc;
617*f3e7f55eSRobert Mustacchi                     res =
618*f3e7f55eSRobert Mustacchi                         _dwarf_pro_encode_leb128_nm(addr_adv /
619*f3e7f55eSRobert Mustacchi                                                     MIN_INST_LENGTH,
620*f3e7f55eSRobert Mustacchi                                                     &nbytes, buff1,
621*f3e7f55eSRobert Mustacchi                                                     sizeof(buff1));
622*f3e7f55eSRobert Mustacchi                     if (res != DW_DLV_OK) {
623*f3e7f55eSRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
624*f3e7f55eSRobert Mustacchi                     }
625*f3e7f55eSRobert Mustacchi                     GET_CHUNK(dbg, elfsectno, data,
626*f3e7f55eSRobert Mustacchi                               nbytes + sizeof(Dwarf_Ubyte), error);
627*f3e7f55eSRobert Mustacchi                     WRITE_UNALIGNED(dbg, (void *) data,
628*f3e7f55eSRobert Mustacchi                                     (const void *) &db, sizeof(db),
629*f3e7f55eSRobert Mustacchi                                     sizeof(Dwarf_Ubyte));
630*f3e7f55eSRobert Mustacchi                     data += sizeof(Dwarf_Ubyte);
631*f3e7f55eSRobert Mustacchi                     /* leb, no endianness issue */
632*f3e7f55eSRobert Mustacchi                     memcpy((void *) data, (const void *) buff1, nbytes);
633*f3e7f55eSRobert Mustacchi                     data += nbytes + sizeof(Dwarf_Ubyte);
634*f3e7f55eSRobert Mustacchi                     sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
635*f3e7f55eSRobert Mustacchi                     prevline->dpl_address = curline->dpl_address;
636*f3e7f55eSRobert Mustacchi                 }
637*f3e7f55eSRobert Mustacchi 
638*f3e7f55eSRobert Mustacchi                 /* first null byte */
639*f3e7f55eSRobert Mustacchi                 db = 0;
640*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
641*f3e7f55eSRobert Mustacchi                           error);
642*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
643*f3e7f55eSRobert Mustacchi                                 sizeof(db), sizeof(Dwarf_Ubyte));
644*f3e7f55eSRobert Mustacchi                 data += sizeof(Dwarf_Ubyte);
645*f3e7f55eSRobert Mustacchi                 sum_bytes += sizeof(Dwarf_Ubyte);
646*f3e7f55eSRobert Mustacchi 
647*f3e7f55eSRobert Mustacchi                 /* write length of extended opcode */
648*f3e7f55eSRobert Mustacchi                 inst_bytes = sizeof(Dwarf_Ubyte);
649*f3e7f55eSRobert Mustacchi                 res =
650*f3e7f55eSRobert Mustacchi                     _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes,
651*f3e7f55eSRobert Mustacchi                                                 buff1, sizeof(buff1));
652*f3e7f55eSRobert Mustacchi                 if (res != DW_DLV_OK) {
653*f3e7f55eSRobert Mustacchi                     DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
654*f3e7f55eSRobert Mustacchi                 }
655*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data, str_nbytes, error);
656*f3e7f55eSRobert Mustacchi                 memcpy((void *) data, (const void *) buff1, str_nbytes);
657*f3e7f55eSRobert Mustacchi                 data += str_nbytes;
658*f3e7f55eSRobert Mustacchi                 sum_bytes += str_nbytes;
659*f3e7f55eSRobert Mustacchi 
660*f3e7f55eSRobert Mustacchi                 /* write extended opcode */
661*f3e7f55eSRobert Mustacchi                 db = DW_LNE_end_sequence;
662*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
663*f3e7f55eSRobert Mustacchi                           error);
664*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
665*f3e7f55eSRobert Mustacchi                                 sizeof(db), sizeof(Dwarf_Ubyte));
666*f3e7f55eSRobert Mustacchi                 data += sizeof(Dwarf_Ubyte);
667*f3e7f55eSRobert Mustacchi                 sum_bytes += sizeof(Dwarf_Ubyte);
668*f3e7f55eSRobert Mustacchi                 /* reset value to original values */
669*f3e7f55eSRobert Mustacchi                 _dwarf_pro_reg_init(prevline);
670*f3e7f55eSRobert Mustacchi                 no_lns_copy = 1;
671*f3e7f55eSRobert Mustacchi                 /* this is set only for end_sequence, so that a
672*f3e7f55eSRobert Mustacchi                    dw_lns_copy is not generated */
673*f3e7f55eSRobert Mustacchi                 break;
674*f3e7f55eSRobert Mustacchi 
675*f3e7f55eSRobert Mustacchi             case DW_LNE_set_address:
676*f3e7f55eSRobert Mustacchi 
677*f3e7f55eSRobert Mustacchi                 /* first null byte */
678*f3e7f55eSRobert Mustacchi                 db = 0;
679*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
680*f3e7f55eSRobert Mustacchi                           error);
681*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
682*f3e7f55eSRobert Mustacchi                                 sizeof(db), sizeof(Dwarf_Ubyte));
683*f3e7f55eSRobert Mustacchi                 data += sizeof(Dwarf_Ubyte);
684*f3e7f55eSRobert Mustacchi                 sum_bytes += sizeof(Dwarf_Ubyte);
685*f3e7f55eSRobert Mustacchi 
686*f3e7f55eSRobert Mustacchi                 /* write length of extended opcode */
687*f3e7f55eSRobert Mustacchi                 inst_bytes = sizeof(Dwarf_Ubyte) + upointer_size;
688*f3e7f55eSRobert Mustacchi                 res =
689*f3e7f55eSRobert Mustacchi                     _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes,
690*f3e7f55eSRobert Mustacchi                                                 buff1, sizeof(buff1));
691*f3e7f55eSRobert Mustacchi                 if (res != DW_DLV_OK) {
692*f3e7f55eSRobert Mustacchi                     DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
693*f3e7f55eSRobert Mustacchi                 }
694*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data, str_nbytes, error);
695*f3e7f55eSRobert Mustacchi                 str = buff1;
696*f3e7f55eSRobert Mustacchi                 /* leb number, no endian issue */
697*f3e7f55eSRobert Mustacchi                 memcpy((void *) data, (const void *) str, str_nbytes);
698*f3e7f55eSRobert Mustacchi                 data += str_nbytes;
699*f3e7f55eSRobert Mustacchi                 sum_bytes += str_nbytes;
700*f3e7f55eSRobert Mustacchi 
701*f3e7f55eSRobert Mustacchi                 /* write extended opcode */
702*f3e7f55eSRobert Mustacchi                 db = DW_LNE_set_address;
703*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data, upointer_size +
704*f3e7f55eSRobert Mustacchi                           sizeof(Dwarf_Ubyte), error);
705*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
706*f3e7f55eSRobert Mustacchi                                 sizeof(db), sizeof(Dwarf_Ubyte));
707*f3e7f55eSRobert Mustacchi                 data += sizeof(Dwarf_Ubyte);
708*f3e7f55eSRobert Mustacchi                 sum_bytes += sizeof(Dwarf_Ubyte);
709*f3e7f55eSRobert Mustacchi 
710*f3e7f55eSRobert Mustacchi                 /* reloc for address */
711*f3e7f55eSRobert Mustacchi                 res = dbg->de_reloc_name(dbg, DEBUG_LINE,
712*f3e7f55eSRobert Mustacchi                     sum_bytes,  /* r_offset  */
713*f3e7f55eSRobert Mustacchi                     curline->dpl_r_symidx,
714*f3e7f55eSRobert Mustacchi                     dwarf_drt_data_reloc,
715*f3e7f55eSRobert Mustacchi                     uwordb_size);
716*f3e7f55eSRobert Mustacchi                 if (res != DW_DLV_OK) {
717*f3e7f55eSRobert Mustacchi                     DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
718*f3e7f55eSRobert Mustacchi                 }
719*f3e7f55eSRobert Mustacchi 
720*f3e7f55eSRobert Mustacchi                 /* write offset (address) */
721*f3e7f55eSRobert Mustacchi                 du = curline->dpl_address;
722*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
723*f3e7f55eSRobert Mustacchi                                 sizeof(du), upointer_size);
724*f3e7f55eSRobert Mustacchi                 data += upointer_size;
725*f3e7f55eSRobert Mustacchi                 sum_bytes += upointer_size;
726*f3e7f55eSRobert Mustacchi                 prevline->dpl_address = curline->dpl_address;
727*f3e7f55eSRobert Mustacchi                 no_lns_copy = 1;
728*f3e7f55eSRobert Mustacchi                 break;
729*f3e7f55eSRobert Mustacchi             }
730*f3e7f55eSRobert Mustacchi         } else {
731*f3e7f55eSRobert Mustacchi             if (curline->dpl_file != prevline->dpl_file) {
732*f3e7f55eSRobert Mustacchi                 db = DW_LNS_set_file;
733*f3e7f55eSRobert Mustacchi                 res =
734*f3e7f55eSRobert Mustacchi                     _dwarf_pro_encode_leb128_nm(curline->dpl_file,
735*f3e7f55eSRobert Mustacchi                                                 &nbytes, buff1,
736*f3e7f55eSRobert Mustacchi                                                 sizeof(buff1));
737*f3e7f55eSRobert Mustacchi                 if (res != DW_DLV_OK) {
738*f3e7f55eSRobert Mustacchi                     DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
739*f3e7f55eSRobert Mustacchi                 }
740*f3e7f55eSRobert Mustacchi                 arg = buff1;
741*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data,
742*f3e7f55eSRobert Mustacchi                           nbytes + sizeof(Dwarf_Ubyte), error);
743*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
744*f3e7f55eSRobert Mustacchi                                 sizeof(db), sizeof(Dwarf_Ubyte));
745*f3e7f55eSRobert Mustacchi                 data += sizeof(Dwarf_Ubyte);
746*f3e7f55eSRobert Mustacchi                 memcpy((void *) data, (const void *) arg, nbytes);
747*f3e7f55eSRobert Mustacchi                 data += nbytes;
748*f3e7f55eSRobert Mustacchi                 sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
749*f3e7f55eSRobert Mustacchi                 prevline->dpl_file = curline->dpl_file;
750*f3e7f55eSRobert Mustacchi             }
751*f3e7f55eSRobert Mustacchi             if (curline->dpl_column != prevline->dpl_column) {
752*f3e7f55eSRobert Mustacchi                 db = DW_LNS_set_column;
753*f3e7f55eSRobert Mustacchi                 res = _dwarf_pro_encode_leb128_nm(curline->dpl_column,
754*f3e7f55eSRobert Mustacchi                                                   &nbytes,
755*f3e7f55eSRobert Mustacchi                                                   buff1, sizeof(buff1));
756*f3e7f55eSRobert Mustacchi                 if (res != DW_DLV_OK) {
757*f3e7f55eSRobert Mustacchi                     DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
758*f3e7f55eSRobert Mustacchi                 }
759*f3e7f55eSRobert Mustacchi 
760*f3e7f55eSRobert Mustacchi                 arg = buff1;
761*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data,
762*f3e7f55eSRobert Mustacchi                           nbytes + sizeof(Dwarf_Ubyte), error);
763*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
764*f3e7f55eSRobert Mustacchi                                 sizeof(db), sizeof(Dwarf_Ubyte));
765*f3e7f55eSRobert Mustacchi                 data += sizeof(Dwarf_Ubyte);
766*f3e7f55eSRobert Mustacchi                 memcpy((void *) data, (const void *) arg, nbytes);
767*f3e7f55eSRobert Mustacchi                 data += nbytes;
768*f3e7f55eSRobert Mustacchi                 sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
769*f3e7f55eSRobert Mustacchi                 prevline->dpl_column = curline->dpl_column;
770*f3e7f55eSRobert Mustacchi             }
771*f3e7f55eSRobert Mustacchi             if (curline->dpl_is_stmt != prevline->dpl_is_stmt) {
772*f3e7f55eSRobert Mustacchi                 db = DW_LNS_negate_stmt;
773*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
774*f3e7f55eSRobert Mustacchi                           error);
775*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
776*f3e7f55eSRobert Mustacchi                                 sizeof(db), sizeof(Dwarf_Ubyte));
777*f3e7f55eSRobert Mustacchi                 data += sizeof(Dwarf_Ubyte);
778*f3e7f55eSRobert Mustacchi                 sum_bytes += sizeof(Dwarf_Ubyte);
779*f3e7f55eSRobert Mustacchi                 prevline->dpl_is_stmt = curline->dpl_is_stmt;
780*f3e7f55eSRobert Mustacchi             }
781*f3e7f55eSRobert Mustacchi             if (curline->dpl_basic_block == true &&
782*f3e7f55eSRobert Mustacchi                 prevline->dpl_basic_block == false) {
783*f3e7f55eSRobert Mustacchi                 db = DW_LNS_set_basic_block;
784*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
785*f3e7f55eSRobert Mustacchi                           error);
786*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
787*f3e7f55eSRobert Mustacchi                                 sizeof(db), sizeof(Dwarf_Ubyte));
788*f3e7f55eSRobert Mustacchi                 data += sizeof(Dwarf_Ubyte);
789*f3e7f55eSRobert Mustacchi                 sum_bytes += sizeof(Dwarf_Ubyte);
790*f3e7f55eSRobert Mustacchi                 prevline->dpl_basic_block = curline->dpl_basic_block;
791*f3e7f55eSRobert Mustacchi             }
792*f3e7f55eSRobert Mustacchi             addr_adv = curline->dpl_address - prevline->dpl_address;
793*f3e7f55eSRobert Mustacchi 
794*f3e7f55eSRobert Mustacchi             line_adv = (int) (curline->dpl_line - prevline->dpl_line);
795*f3e7f55eSRobert Mustacchi             if ((addr_adv % MIN_INST_LENGTH) != 0) {
796*f3e7f55eSRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, -1);
797*f3e7f55eSRobert Mustacchi             }
798*f3e7f55eSRobert Mustacchi             if ((opc = _dwarf_pro_get_opc(addr_adv, line_adv)) > 0) {
799*f3e7f55eSRobert Mustacchi                 no_lns_copy = 1;
800*f3e7f55eSRobert Mustacchi                 db = opc;
801*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
802*f3e7f55eSRobert Mustacchi                           error);
803*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
804*f3e7f55eSRobert Mustacchi                                 sizeof(db), sizeof(Dwarf_Ubyte));
805*f3e7f55eSRobert Mustacchi                 data += sizeof(Dwarf_Ubyte);
806*f3e7f55eSRobert Mustacchi                 sum_bytes += sizeof(Dwarf_Ubyte);
807*f3e7f55eSRobert Mustacchi                 prevline->dpl_basic_block = false;
808*f3e7f55eSRobert Mustacchi                 prevline->dpl_address = curline->dpl_address;
809*f3e7f55eSRobert Mustacchi                 prevline->dpl_line = curline->dpl_line;
810*f3e7f55eSRobert Mustacchi             } else {
811*f3e7f55eSRobert Mustacchi                 if (addr_adv > 0) {
812*f3e7f55eSRobert Mustacchi                     db = DW_LNS_advance_pc;
813*f3e7f55eSRobert Mustacchi                     res =
814*f3e7f55eSRobert Mustacchi                         _dwarf_pro_encode_leb128_nm(addr_adv /
815*f3e7f55eSRobert Mustacchi                                                     MIN_INST_LENGTH,
816*f3e7f55eSRobert Mustacchi                                                     &nbytes, buff1,
817*f3e7f55eSRobert Mustacchi                                                     sizeof(buff1));
818*f3e7f55eSRobert Mustacchi                     if (res != DW_DLV_OK) {
819*f3e7f55eSRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
820*f3e7f55eSRobert Mustacchi                     }
821*f3e7f55eSRobert Mustacchi 
822*f3e7f55eSRobert Mustacchi                     arg = buff1;
823*f3e7f55eSRobert Mustacchi                     GET_CHUNK(dbg, elfsectno, data,
824*f3e7f55eSRobert Mustacchi                               nbytes + sizeof(Dwarf_Ubyte), error);
825*f3e7f55eSRobert Mustacchi                     WRITE_UNALIGNED(dbg, (void *) data,
826*f3e7f55eSRobert Mustacchi                                     (const void *) &db,
827*f3e7f55eSRobert Mustacchi                                     sizeof(db), sizeof(Dwarf_Ubyte));
828*f3e7f55eSRobert Mustacchi                     data += sizeof(Dwarf_Ubyte);
829*f3e7f55eSRobert Mustacchi                     memcpy((void *) data, (const void *) arg, nbytes);
830*f3e7f55eSRobert Mustacchi                     data += nbytes + sizeof(Dwarf_Ubyte);
831*f3e7f55eSRobert Mustacchi                     sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
832*f3e7f55eSRobert Mustacchi                     prevline->dpl_basic_block = false;
833*f3e7f55eSRobert Mustacchi                     prevline->dpl_address = curline->dpl_address;
834*f3e7f55eSRobert Mustacchi                 }
835*f3e7f55eSRobert Mustacchi                 if (line_adv != 0) {
836*f3e7f55eSRobert Mustacchi                     db = DW_LNS_advance_line;
837*f3e7f55eSRobert Mustacchi                     res = _dwarf_pro_encode_signed_leb128_nm(line_adv,
838*f3e7f55eSRobert Mustacchi                                                              &nbytes,
839*f3e7f55eSRobert Mustacchi                                                              buff1,
840*f3e7f55eSRobert Mustacchi                                                              sizeof
841*f3e7f55eSRobert Mustacchi                                                              (buff1));
842*f3e7f55eSRobert Mustacchi                     if (res != DW_DLV_OK) {
843*f3e7f55eSRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
844*f3e7f55eSRobert Mustacchi                     }
845*f3e7f55eSRobert Mustacchi 
846*f3e7f55eSRobert Mustacchi                     arg = buff1;
847*f3e7f55eSRobert Mustacchi                     GET_CHUNK(dbg, elfsectno, data,
848*f3e7f55eSRobert Mustacchi                               nbytes + sizeof(Dwarf_Ubyte), error);
849*f3e7f55eSRobert Mustacchi                     WRITE_UNALIGNED(dbg, (void *) data,
850*f3e7f55eSRobert Mustacchi                                     (const void *) &db, sizeof(db),
851*f3e7f55eSRobert Mustacchi                                     sizeof(Dwarf_Ubyte));
852*f3e7f55eSRobert Mustacchi                     data += sizeof(Dwarf_Ubyte);
853*f3e7f55eSRobert Mustacchi                     memcpy((void *) data, (const void *) arg, nbytes);
854*f3e7f55eSRobert Mustacchi                     data += nbytes + sizeof(Dwarf_Ubyte);
855*f3e7f55eSRobert Mustacchi                     sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
856*f3e7f55eSRobert Mustacchi                     prevline->dpl_basic_block = false;
857*f3e7f55eSRobert Mustacchi                     prevline->dpl_line = curline->dpl_line;
858*f3e7f55eSRobert Mustacchi                 }
859*f3e7f55eSRobert Mustacchi             }
860*f3e7f55eSRobert Mustacchi         }                       /* ends else for opc != 0 */
861*f3e7f55eSRobert Mustacchi         if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq
862*f3e7f55eSRobert Mustacchi                                    generate a matrix line */
863*f3e7f55eSRobert Mustacchi             db = DW_LNS_copy;
864*f3e7f55eSRobert Mustacchi             GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), error);
865*f3e7f55eSRobert Mustacchi             WRITE_UNALIGNED(dbg, (void *) data,
866*f3e7f55eSRobert Mustacchi                             (const void *) &db,
867*f3e7f55eSRobert Mustacchi                             sizeof(db), sizeof(Dwarf_Ubyte));
868*f3e7f55eSRobert Mustacchi             data += sizeof(Dwarf_Ubyte);
869*f3e7f55eSRobert Mustacchi             sum_bytes += sizeof(Dwarf_Ubyte);
870*f3e7f55eSRobert Mustacchi             prevline->dpl_basic_block = false;
871*f3e7f55eSRobert Mustacchi         }
872*f3e7f55eSRobert Mustacchi         curline = curline->dpl_next;
873*f3e7f55eSRobert Mustacchi     }
874*f3e7f55eSRobert Mustacchi 
875*f3e7f55eSRobert Mustacchi     /* write total length field */
876*f3e7f55eSRobert Mustacchi     du = sum_bytes - BEGIN_LEN_SIZE;
877*f3e7f55eSRobert Mustacchi     {
878*f3e7f55eSRobert Mustacchi         start_line_sec += extension_size;
879*f3e7f55eSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) start_line_sec,
880*f3e7f55eSRobert Mustacchi                         (const void *) &du, sizeof(du), uwordb_size);
881*f3e7f55eSRobert Mustacchi     }
882*f3e7f55eSRobert Mustacchi 
883*f3e7f55eSRobert Mustacchi     return (int) dbg->de_n_debug_sect;
884*f3e7f55eSRobert Mustacchi }
885*f3e7f55eSRobert Mustacchi 
886*f3e7f55eSRobert Mustacchi /*---------------------------------------------------------------
887*f3e7f55eSRobert Mustacchi         Generate debug_frame section
888*f3e7f55eSRobert Mustacchi ---------------------------------------------------------------*/
889*f3e7f55eSRobert Mustacchi static int
_dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,Dwarf_Error * error)890*f3e7f55eSRobert Mustacchi _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error)
891*f3e7f55eSRobert Mustacchi {
892*f3e7f55eSRobert Mustacchi     int elfsectno = 0;
893*f3e7f55eSRobert Mustacchi     int i = 0;
894*f3e7f55eSRobert Mustacchi     int firsttime = 1;
895*f3e7f55eSRobert Mustacchi     int pad = 0;     /* Pad for padding to align cies and fdes */
896*f3e7f55eSRobert Mustacchi     Dwarf_P_Cie curcie = 0;
897*f3e7f55eSRobert Mustacchi     Dwarf_P_Fde curfde = 0;
898*f3e7f55eSRobert Mustacchi     unsigned char *data = 0;
899*f3e7f55eSRobert Mustacchi     Dwarf_sfixed dsw = 0;
900*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned du = 0;
901*f3e7f55eSRobert Mustacchi     Dwarf_Ubyte db = 0;
902*f3e7f55eSRobert Mustacchi     long *cie_offs = 0;   /* Holds byte offsets for links to fde's */
903*f3e7f55eSRobert Mustacchi     unsigned long cie_length = 0;
904*f3e7f55eSRobert Mustacchi     int cie_no = 0;
905*f3e7f55eSRobert Mustacchi     int uwordb_size = dbg->de_offset_size;
906*f3e7f55eSRobert Mustacchi     int extension_size = dbg->de_64bit_extension ? 4 : 0;
907*f3e7f55eSRobert Mustacchi     int upointer_size = dbg->de_pointer_size;
908*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned cur_off = 0; /* current offset of written data, held
909*f3e7f55eSRobert Mustacchi                                    for relocation info */
910*f3e7f55eSRobert Mustacchi 
911*f3e7f55eSRobert Mustacchi     elfsectno = dbg->de_elf_sects[DEBUG_FRAME];
912*f3e7f55eSRobert Mustacchi 
913*f3e7f55eSRobert Mustacchi     curcie = dbg->de_frame_cies;
914*f3e7f55eSRobert Mustacchi     cie_length = 0;
915*f3e7f55eSRobert Mustacchi     cur_off = 0;
916*f3e7f55eSRobert Mustacchi     cie_offs = (long *)
917*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie);
918*f3e7f55eSRobert Mustacchi     if (cie_offs == NULL) {
919*f3e7f55eSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
920*f3e7f55eSRobert Mustacchi     }
921*f3e7f55eSRobert Mustacchi     /* Generate cie number as we go along.  This writes
922*f3e7f55eSRobert Mustacchi        all CIEs first before any FDEs, which is rather
923*f3e7f55eSRobert Mustacchi        different from the order a compiler might like (which
924*f3e7f55eSRobert Mustacchi        might be each CIE followed by its FDEs then the next CIE, and
925*f3e7f55eSRobert Mustacchi        so on). */
926*f3e7f55eSRobert Mustacchi     cie_no = 1;
927*f3e7f55eSRobert Mustacchi     while (curcie) {
928*f3e7f55eSRobert Mustacchi         char *code_al = 0;
929*f3e7f55eSRobert Mustacchi         int c_bytes = 0;
930*f3e7f55eSRobert Mustacchi         char *data_al = 0;
931*f3e7f55eSRobert Mustacchi         int d_bytes = 0;
932*f3e7f55eSRobert Mustacchi         int res = 0;
933*f3e7f55eSRobert Mustacchi         char buff1[ENCODE_SPACE_NEEDED];
934*f3e7f55eSRobert Mustacchi         char buff2[ENCODE_SPACE_NEEDED];
935*f3e7f55eSRobert Mustacchi         char buff3[ENCODE_SPACE_NEEDED];
936*f3e7f55eSRobert Mustacchi         char *augmentation = 0;
937*f3e7f55eSRobert Mustacchi         char *augmented_al = 0;
938*f3e7f55eSRobert Mustacchi         long augmented_fields_length = 0;
939*f3e7f55eSRobert Mustacchi         int a_bytes = 0;
940*f3e7f55eSRobert Mustacchi 
941*f3e7f55eSRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align,
942*f3e7f55eSRobert Mustacchi                                           &c_bytes,
943*f3e7f55eSRobert Mustacchi                                           buff1, sizeof(buff1));
944*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
945*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
946*f3e7f55eSRobert Mustacchi         }
947*f3e7f55eSRobert Mustacchi         /* Before April 1999, the following was using an unsigned
948*f3e7f55eSRobert Mustacchi            encode. That worked ok even though the decoder used the
949*f3e7f55eSRobert Mustacchi            correct signed leb read, but doing the encode correctly
950*f3e7f55eSRobert Mustacchi            (according to the dwarf spec) saves space in the output file
951*f3e7f55eSRobert Mustacchi            and is completely compatible.
952*f3e7f55eSRobert Mustacchi 
953*f3e7f55eSRobert Mustacchi            Note the actual stored amount on MIPS was 10 bytes (!) to
954*f3e7f55eSRobert Mustacchi            store the value -4. (hex)fc ffffffff ffffffff 01 The
955*f3e7f55eSRobert Mustacchi            libdwarf consumer consumed all 10 bytes too!
956*f3e7f55eSRobert Mustacchi 
957*f3e7f55eSRobert Mustacchi            old version res =
958*f3e7f55eSRobert Mustacchi            _dwarf_pro_encode_leb128_nm(curcie->cie_data_align,
959*f3e7f55eSRobert Mustacchi 
960*f3e7f55eSRobert Mustacchi            below is corrected signed version. */
961*f3e7f55eSRobert Mustacchi         res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align,
962*f3e7f55eSRobert Mustacchi                                                  &d_bytes,
963*f3e7f55eSRobert Mustacchi                                                  buff2, sizeof(buff2));
964*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
965*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
966*f3e7f55eSRobert Mustacchi         }
967*f3e7f55eSRobert Mustacchi         code_al = buff1;
968*f3e7f55eSRobert Mustacchi         data_al = buff2;
969*f3e7f55eSRobert Mustacchi 
970*f3e7f55eSRobert Mustacchi         /* get the correct offset */
971*f3e7f55eSRobert Mustacchi         if (firsttime) {
972*f3e7f55eSRobert Mustacchi             cie_offs[cie_no - 1] = 0;
973*f3e7f55eSRobert Mustacchi             firsttime = 0;
974*f3e7f55eSRobert Mustacchi         } else {
975*f3e7f55eSRobert Mustacchi             cie_offs[cie_no - 1] = cie_offs[cie_no - 2] +
976*f3e7f55eSRobert Mustacchi                 (long) cie_length + BEGIN_LEN_SIZE;
977*f3e7f55eSRobert Mustacchi         }
978*f3e7f55eSRobert Mustacchi         cie_no++;
979*f3e7f55eSRobert Mustacchi         augmentation = curcie->cie_aug;
980*f3e7f55eSRobert Mustacchi         if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
981*f3e7f55eSRobert Mustacchi             augmented_fields_length = 0;
982*f3e7f55eSRobert Mustacchi             res = _dwarf_pro_encode_leb128_nm(augmented_fields_length,
983*f3e7f55eSRobert Mustacchi                                               &a_bytes, buff3,
984*f3e7f55eSRobert Mustacchi                                               sizeof(buff3));
985*f3e7f55eSRobert Mustacchi             augmented_al = buff3;
986*f3e7f55eSRobert Mustacchi             if (res != DW_DLV_OK) {
987*f3e7f55eSRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
988*f3e7f55eSRobert Mustacchi             }
989*f3e7f55eSRobert Mustacchi             cie_length = uwordb_size +  /* cie_id */
990*f3e7f55eSRobert Mustacchi                 sizeof(Dwarf_Ubyte) +   /* cie version */
991*f3e7f55eSRobert Mustacchi                 strlen(curcie->cie_aug) + 1 +   /* augmentation */
992*f3e7f55eSRobert Mustacchi                 c_bytes +       /* code alignment factor */
993*f3e7f55eSRobert Mustacchi                 d_bytes +       /* data alignment factor */
994*f3e7f55eSRobert Mustacchi                 sizeof(Dwarf_Ubyte) +   /* return reg address */
995*f3e7f55eSRobert Mustacchi                 a_bytes +       /* augmentation length */
996*f3e7f55eSRobert Mustacchi                 curcie->cie_inst_bytes;
997*f3e7f55eSRobert Mustacchi         } else {
998*f3e7f55eSRobert Mustacchi             cie_length = uwordb_size +  /* cie_id */
999*f3e7f55eSRobert Mustacchi                 sizeof(Dwarf_Ubyte) +   /* cie version */
1000*f3e7f55eSRobert Mustacchi                 strlen(curcie->cie_aug) + 1 +   /* augmentation */
1001*f3e7f55eSRobert Mustacchi                 c_bytes + d_bytes + sizeof(Dwarf_Ubyte) +       /* return
1002*f3e7f55eSRobert Mustacchi                                                                    reg
1003*f3e7f55eSRobert Mustacchi                                                                    address
1004*f3e7f55eSRobert Mustacchi                                                                  */
1005*f3e7f55eSRobert Mustacchi                 curcie->cie_inst_bytes;
1006*f3e7f55eSRobert Mustacchi         }
1007*f3e7f55eSRobert Mustacchi         pad = (int) PADDING(cie_length, upointer_size);
1008*f3e7f55eSRobert Mustacchi         cie_length += pad;
1009*f3e7f55eSRobert Mustacchi         GET_CHUNK(dbg, elfsectno, data, cie_length +
1010*f3e7f55eSRobert Mustacchi                   BEGIN_LEN_SIZE, error);
1011*f3e7f55eSRobert Mustacchi         if (extension_size) {
1012*f3e7f55eSRobert Mustacchi             Dwarf_Unsigned x = DISTINGUISHED_VALUE;
1013*f3e7f55eSRobert Mustacchi 
1014*f3e7f55eSRobert Mustacchi             WRITE_UNALIGNED(dbg, (void *) data,
1015*f3e7f55eSRobert Mustacchi                             (const void *) &x,
1016*f3e7f55eSRobert Mustacchi                             sizeof(x), extension_size);
1017*f3e7f55eSRobert Mustacchi             data += extension_size;
1018*f3e7f55eSRobert Mustacchi 
1019*f3e7f55eSRobert Mustacchi         }
1020*f3e7f55eSRobert Mustacchi         du = cie_length;
1021*f3e7f55eSRobert Mustacchi         /* total length of cie */
1022*f3e7f55eSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) data,
1023*f3e7f55eSRobert Mustacchi                         (const void *) &du, sizeof(du), uwordb_size);
1024*f3e7f55eSRobert Mustacchi         data += uwordb_size;
1025*f3e7f55eSRobert Mustacchi 
1026*f3e7f55eSRobert Mustacchi         /* cie-id is a special value. */
1027*f3e7f55eSRobert Mustacchi         du = DW_CIE_ID;
1028*f3e7f55eSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
1029*f3e7f55eSRobert Mustacchi                         sizeof(du), uwordb_size);
1030*f3e7f55eSRobert Mustacchi         data += uwordb_size;
1031*f3e7f55eSRobert Mustacchi 
1032*f3e7f55eSRobert Mustacchi         db = curcie->cie_version;
1033*f3e7f55eSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1034*f3e7f55eSRobert Mustacchi                         sizeof(db), sizeof(Dwarf_Ubyte));
1035*f3e7f55eSRobert Mustacchi         data += sizeof(Dwarf_Ubyte);
1036*f3e7f55eSRobert Mustacchi         strcpy((char *) data, curcie->cie_aug);
1037*f3e7f55eSRobert Mustacchi         data += strlen(curcie->cie_aug) + 1;
1038*f3e7f55eSRobert Mustacchi         memcpy((void *) data, (const void *) code_al, c_bytes);
1039*f3e7f55eSRobert Mustacchi         data += c_bytes;
1040*f3e7f55eSRobert Mustacchi         memcpy((void *) data, (const void *) data_al, d_bytes);
1041*f3e7f55eSRobert Mustacchi         data += d_bytes;
1042*f3e7f55eSRobert Mustacchi         db = curcie->cie_ret_reg;
1043*f3e7f55eSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1044*f3e7f55eSRobert Mustacchi                         sizeof(db), sizeof(Dwarf_Ubyte));
1045*f3e7f55eSRobert Mustacchi         data += sizeof(Dwarf_Ubyte);
1046*f3e7f55eSRobert Mustacchi 
1047*f3e7f55eSRobert Mustacchi         if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
1048*f3e7f55eSRobert Mustacchi             memcpy((void *) data, (const void *) augmented_al, a_bytes);
1049*f3e7f55eSRobert Mustacchi             data += a_bytes;
1050*f3e7f55eSRobert Mustacchi         }
1051*f3e7f55eSRobert Mustacchi         memcpy((void *) data, (const void *) curcie->cie_inst,
1052*f3e7f55eSRobert Mustacchi                curcie->cie_inst_bytes);
1053*f3e7f55eSRobert Mustacchi         data += curcie->cie_inst_bytes;
1054*f3e7f55eSRobert Mustacchi         for (i = 0; i < pad; i++) {
1055*f3e7f55eSRobert Mustacchi             *data = DW_CFA_nop;
1056*f3e7f55eSRobert Mustacchi             data++;
1057*f3e7f55eSRobert Mustacchi         }
1058*f3e7f55eSRobert Mustacchi         curcie = curcie->cie_next;
1059*f3e7f55eSRobert Mustacchi     }
1060*f3e7f55eSRobert Mustacchi     /* calculate current offset */
1061*f3e7f55eSRobert Mustacchi     cur_off = cie_offs[cie_no - 2] + cie_length + BEGIN_LEN_SIZE;
1062*f3e7f55eSRobert Mustacchi 
1063*f3e7f55eSRobert Mustacchi     /* write out fde's */
1064*f3e7f55eSRobert Mustacchi     curfde = dbg->de_frame_fdes;
1065*f3e7f55eSRobert Mustacchi     while (curfde) {
1066*f3e7f55eSRobert Mustacchi         Dwarf_P_Frame_Pgm curinst = 0;
1067*f3e7f55eSRobert Mustacchi         long fde_length = 0;
1068*f3e7f55eSRobert Mustacchi         int pad = 0;
1069*f3e7f55eSRobert Mustacchi         Dwarf_P_Cie cie_ptr = 0;
1070*f3e7f55eSRobert Mustacchi         Dwarf_Word cie_index = 0;
1071*f3e7f55eSRobert Mustacchi         Dwarf_Word index = 0;
1072*f3e7f55eSRobert Mustacchi         int oet_length = 0;
1073*f3e7f55eSRobert Mustacchi         int afl_length = 0;
1074*f3e7f55eSRobert Mustacchi         int res = 0;
1075*f3e7f55eSRobert Mustacchi         int v0_augmentation = 0;
1076*f3e7f55eSRobert Mustacchi #if 0
1077*f3e7f55eSRobert Mustacchi         unsigned char *fde_start_point = 0;
1078*f3e7f55eSRobert Mustacchi #endif
1079*f3e7f55eSRobert Mustacchi         char afl_buff[ENCODE_SPACE_NEEDED];
1080*f3e7f55eSRobert Mustacchi 
1081*f3e7f55eSRobert Mustacchi         /* Find the CIE associated with this fde. */
1082*f3e7f55eSRobert Mustacchi         cie_ptr = dbg->de_frame_cies;
1083*f3e7f55eSRobert Mustacchi         cie_index = curfde->fde_cie;
1084*f3e7f55eSRobert Mustacchi         index = 1;              /* The cie_index of the first cie is 1,
1085*f3e7f55eSRobert Mustacchi                                    not 0. */
1086*f3e7f55eSRobert Mustacchi         while (cie_ptr && index < cie_index) {
1087*f3e7f55eSRobert Mustacchi             cie_ptr = cie_ptr->cie_next;
1088*f3e7f55eSRobert Mustacchi             index++;
1089*f3e7f55eSRobert Mustacchi         }
1090*f3e7f55eSRobert Mustacchi         if (cie_ptr == NULL) {
1091*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, -1);
1092*f3e7f55eSRobert Mustacchi         }
1093*f3e7f55eSRobert Mustacchi 
1094*f3e7f55eSRobert Mustacchi         if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) {
1095*f3e7f55eSRobert Mustacchi             v0_augmentation = 1;
1096*f3e7f55eSRobert Mustacchi             oet_length = sizeof(Dwarf_sfixed);
1097*f3e7f55eSRobert Mustacchi             /* encode the length of augmented fields. */
1098*f3e7f55eSRobert Mustacchi             res = _dwarf_pro_encode_leb128_nm(oet_length,
1099*f3e7f55eSRobert Mustacchi                                               &afl_length, afl_buff,
1100*f3e7f55eSRobert Mustacchi                                               sizeof(afl_buff));
1101*f3e7f55eSRobert Mustacchi             if (res != DW_DLV_OK) {
1102*f3e7f55eSRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
1103*f3e7f55eSRobert Mustacchi             }
1104*f3e7f55eSRobert Mustacchi 
1105*f3e7f55eSRobert Mustacchi             fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie
1106*f3e7f55eSRobert Mustacchi                                                                    pointer
1107*f3e7f55eSRobert Mustacchi                                                                  */
1108*f3e7f55eSRobert Mustacchi                 upointer_size + /* initial loc */
1109*f3e7f55eSRobert Mustacchi                 upointer_size + /* address range */
1110*f3e7f55eSRobert Mustacchi                 afl_length +    /* augmented field length */
1111*f3e7f55eSRobert Mustacchi                 oet_length;     /* exception_table offset */
1112*f3e7f55eSRobert Mustacchi         } else {
1113*f3e7f55eSRobert Mustacchi             fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie
1114*f3e7f55eSRobert Mustacchi                                                                    pointer
1115*f3e7f55eSRobert Mustacchi                                                                  */
1116*f3e7f55eSRobert Mustacchi                 upointer_size + /* initial loc */
1117*f3e7f55eSRobert Mustacchi                 upointer_size;  /* address range */
1118*f3e7f55eSRobert Mustacchi         }
1119*f3e7f55eSRobert Mustacchi 
1120*f3e7f55eSRobert Mustacchi 
1121*f3e7f55eSRobert Mustacchi         if (curfde->fde_die) {
1122*f3e7f55eSRobert Mustacchi             /* IRIX/MIPS extension:
1123*f3e7f55eSRobert Mustacchi                Using fde offset, generate DW_AT_MIPS_fde attribute for the
1124*f3e7f55eSRobert Mustacchi                die corresponding to this fde.  */
1125*f3e7f55eSRobert Mustacchi             if(_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off,
1126*f3e7f55eSRobert Mustacchi                 error) < 0) {
1127*f3e7f55eSRobert Mustacchi                 return -1;
1128*f3e7f55eSRobert Mustacchi             }
1129*f3e7f55eSRobert Mustacchi         }
1130*f3e7f55eSRobert Mustacchi 
1131*f3e7f55eSRobert Mustacchi         /* store relocation for cie pointer */
1132*f3e7f55eSRobert Mustacchi         res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off +
1133*f3e7f55eSRobert Mustacchi                                      BEGIN_LEN_SIZE /* r_offset */,
1134*f3e7f55eSRobert Mustacchi                                  dbg->de_sect_name_idx[DEBUG_FRAME],
1135*f3e7f55eSRobert Mustacchi                                  dwarf_drt_data_reloc, uwordb_size);
1136*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
1137*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
1138*f3e7f55eSRobert Mustacchi         }
1139*f3e7f55eSRobert Mustacchi 
1140*f3e7f55eSRobert Mustacchi         /* store relocation information for initial location */
1141*f3e7f55eSRobert Mustacchi         res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
1142*f3e7f55eSRobert Mustacchi                                  cur_off + BEGIN_LEN_SIZE +
1143*f3e7f55eSRobert Mustacchi                                      upointer_size /* r_offset */,
1144*f3e7f55eSRobert Mustacchi                                  curfde->fde_r_symidx,
1145*f3e7f55eSRobert Mustacchi                                  dwarf_drt_data_reloc, upointer_size);
1146*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
1147*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
1148*f3e7f55eSRobert Mustacchi         }
1149*f3e7f55eSRobert Mustacchi         /* Store the relocation information for the
1150*f3e7f55eSRobert Mustacchi            offset_into_exception_info field, if the offset is valid (0
1151*f3e7f55eSRobert Mustacchi            is a valid offset). */
1152*f3e7f55eSRobert Mustacchi         if (v0_augmentation &&
1153*f3e7f55eSRobert Mustacchi             curfde->fde_offset_into_exception_tables >= 0) {
1154*f3e7f55eSRobert Mustacchi 
1155*f3e7f55eSRobert Mustacchi             res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
1156*f3e7f55eSRobert Mustacchi                                      /* r_offset, where in cie this
1157*f3e7f55eSRobert Mustacchi                                         field starts */
1158*f3e7f55eSRobert Mustacchi                                      cur_off + BEGIN_LEN_SIZE +
1159*f3e7f55eSRobert Mustacchi                                          uwordb_size + 2 * upointer_size +
1160*f3e7f55eSRobert Mustacchi                                          afl_length,
1161*f3e7f55eSRobert Mustacchi                                      curfde->fde_exception_table_symbol,
1162*f3e7f55eSRobert Mustacchi                                      dwarf_drt_segment_rel,
1163*f3e7f55eSRobert Mustacchi                                      sizeof(Dwarf_sfixed));
1164*f3e7f55eSRobert Mustacchi             if (res != DW_DLV_OK) {
1165*f3e7f55eSRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
1166*f3e7f55eSRobert Mustacchi             }
1167*f3e7f55eSRobert Mustacchi         }
1168*f3e7f55eSRobert Mustacchi 
1169*f3e7f55eSRobert Mustacchi         /* adjust for padding */
1170*f3e7f55eSRobert Mustacchi         pad = (int) PADDING(fde_length, upointer_size);
1171*f3e7f55eSRobert Mustacchi         fde_length += pad;
1172*f3e7f55eSRobert Mustacchi 
1173*f3e7f55eSRobert Mustacchi 
1174*f3e7f55eSRobert Mustacchi         /* write out fde */
1175*f3e7f55eSRobert Mustacchi         GET_CHUNK(dbg, elfsectno, data, fde_length + BEGIN_LEN_SIZE,
1176*f3e7f55eSRobert Mustacchi                   error);
1177*f3e7f55eSRobert Mustacchi #if 0
1178*f3e7f55eSRobert Mustacchi         fde_start_point = data;
1179*f3e7f55eSRobert Mustacchi #endif
1180*f3e7f55eSRobert Mustacchi         du = fde_length;
1181*f3e7f55eSRobert Mustacchi         {
1182*f3e7f55eSRobert Mustacchi             if (extension_size) {
1183*f3e7f55eSRobert Mustacchi                 Dwarf_Word x = DISTINGUISHED_VALUE;
1184*f3e7f55eSRobert Mustacchi 
1185*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data,
1186*f3e7f55eSRobert Mustacchi                                 (const void *) &x,
1187*f3e7f55eSRobert Mustacchi                                 sizeof(x), extension_size);
1188*f3e7f55eSRobert Mustacchi                 data += extension_size;
1189*f3e7f55eSRobert Mustacchi             }
1190*f3e7f55eSRobert Mustacchi             /* length */
1191*f3e7f55eSRobert Mustacchi             WRITE_UNALIGNED(dbg, (void *) data,
1192*f3e7f55eSRobert Mustacchi                             (const void *) &du,
1193*f3e7f55eSRobert Mustacchi                             sizeof(du), uwordb_size);
1194*f3e7f55eSRobert Mustacchi             data += uwordb_size;
1195*f3e7f55eSRobert Mustacchi 
1196*f3e7f55eSRobert Mustacchi             /* offset to cie */
1197*f3e7f55eSRobert Mustacchi             du = cie_offs[curfde->fde_cie - 1];
1198*f3e7f55eSRobert Mustacchi             WRITE_UNALIGNED(dbg, (void *) data,
1199*f3e7f55eSRobert Mustacchi                             (const void *) &du,
1200*f3e7f55eSRobert Mustacchi                             sizeof(du), uwordb_size);
1201*f3e7f55eSRobert Mustacchi             data += uwordb_size;
1202*f3e7f55eSRobert Mustacchi 
1203*f3e7f55eSRobert Mustacchi             du = curfde->fde_initloc;
1204*f3e7f55eSRobert Mustacchi             WRITE_UNALIGNED(dbg, (void *) data,
1205*f3e7f55eSRobert Mustacchi                             (const void *) &du,
1206*f3e7f55eSRobert Mustacchi                             sizeof(du), upointer_size);
1207*f3e7f55eSRobert Mustacchi             data += upointer_size;
1208*f3e7f55eSRobert Mustacchi 
1209*f3e7f55eSRobert Mustacchi             if (dbg->de_reloc_pair &&
1210*f3e7f55eSRobert Mustacchi                 curfde->fde_end_symbol != 0 &&
1211*f3e7f55eSRobert Mustacchi                 curfde->fde_addr_range == 0) {
1212*f3e7f55eSRobert Mustacchi                 /* symbolic reloc, need reloc for length What if we
1213*f3e7f55eSRobert Mustacchi                    really know the length? If so, should use the other
1214*f3e7f55eSRobert Mustacchi                    part of 'if'. */
1215*f3e7f55eSRobert Mustacchi                 Dwarf_Unsigned val;
1216*f3e7f55eSRobert Mustacchi 
1217*f3e7f55eSRobert Mustacchi                 res = dbg->de_reloc_pair(dbg,
1218*f3e7f55eSRobert Mustacchi                                          /* DEBUG_ARANGES, */
1219*f3e7f55eSRobert Mustacchi                                          DEBUG_FRAME, cur_off + 2 * uwordb_size + upointer_size,        /* r_offset
1220*f3e7f55eSRobert Mustacchi                                                                                                          */
1221*f3e7f55eSRobert Mustacchi                                          curfde->fde_r_symidx,
1222*f3e7f55eSRobert Mustacchi                                          curfde->fde_end_symbol,
1223*f3e7f55eSRobert Mustacchi                                          dwarf_drt_first_of_length_pair,
1224*f3e7f55eSRobert Mustacchi                                          upointer_size);
1225*f3e7f55eSRobert Mustacchi                 if (res != DW_DLV_OK) {
1226*f3e7f55eSRobert Mustacchi                     {
1227*f3e7f55eSRobert Mustacchi                         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1228*f3e7f55eSRobert Mustacchi                         return (0);
1229*f3e7f55eSRobert Mustacchi                     }
1230*f3e7f55eSRobert Mustacchi                 }
1231*f3e7f55eSRobert Mustacchi 
1232*f3e7f55eSRobert Mustacchi                 /* arrange pre-calc so assem text can do .word end -
1233*f3e7f55eSRobert Mustacchi                    begin + val (gets val from stream) */
1234*f3e7f55eSRobert Mustacchi                 val = curfde->fde_end_symbol_offset -
1235*f3e7f55eSRobert Mustacchi                     curfde->fde_initloc;
1236*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, data,
1237*f3e7f55eSRobert Mustacchi                                 (const void *) &val,
1238*f3e7f55eSRobert Mustacchi                                 sizeof(val), upointer_size);
1239*f3e7f55eSRobert Mustacchi                 data += upointer_size;
1240*f3e7f55eSRobert Mustacchi             } else {
1241*f3e7f55eSRobert Mustacchi 
1242*f3e7f55eSRobert Mustacchi                 du = curfde->fde_addr_range;
1243*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data,
1244*f3e7f55eSRobert Mustacchi                                 (const void *) &du,
1245*f3e7f55eSRobert Mustacchi                                 sizeof(du), upointer_size);
1246*f3e7f55eSRobert Mustacchi                 data += upointer_size;
1247*f3e7f55eSRobert Mustacchi             }
1248*f3e7f55eSRobert Mustacchi         }
1249*f3e7f55eSRobert Mustacchi 
1250*f3e7f55eSRobert Mustacchi         if (v0_augmentation) {
1251*f3e7f55eSRobert Mustacchi             /* write the encoded augmented field length. */
1252*f3e7f55eSRobert Mustacchi             memcpy((void *) data, (const void *) afl_buff, afl_length);
1253*f3e7f55eSRobert Mustacchi             data += afl_length;
1254*f3e7f55eSRobert Mustacchi             /* write the offset_into_exception_tables field. */
1255*f3e7f55eSRobert Mustacchi             dsw =
1256*f3e7f55eSRobert Mustacchi                 (Dwarf_sfixed) curfde->fde_offset_into_exception_tables;
1257*f3e7f55eSRobert Mustacchi             WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw,
1258*f3e7f55eSRobert Mustacchi                             sizeof(dsw), sizeof(Dwarf_sfixed));
1259*f3e7f55eSRobert Mustacchi             data += sizeof(Dwarf_sfixed);
1260*f3e7f55eSRobert Mustacchi         }
1261*f3e7f55eSRobert Mustacchi 
1262*f3e7f55eSRobert Mustacchi         curinst = curfde->fde_inst;
1263*f3e7f55eSRobert Mustacchi         if(curfde->fde_block) {
1264*f3e7f55eSRobert Mustacchi             unsigned long size = curfde->fde_inst_block_size;
1265*f3e7f55eSRobert Mustacchi             memcpy((void *) data, (const void *) curfde->fde_block, size);
1266*f3e7f55eSRobert Mustacchi             data += size;
1267*f3e7f55eSRobert Mustacchi         } else {
1268*f3e7f55eSRobert Mustacchi             while (curinst) {
1269*f3e7f55eSRobert Mustacchi                 db = curinst->dfp_opcode;
1270*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1271*f3e7f55eSRobert Mustacchi                      sizeof(db), sizeof(Dwarf_Ubyte));
1272*f3e7f55eSRobert Mustacchi                 data += sizeof(Dwarf_Ubyte);
1273*f3e7f55eSRobert Mustacchi #if 0
1274*f3e7f55eSRobert Mustacchi                 if (curinst->dfp_sym_index) {
1275*f3e7f55eSRobert Mustacchi                     int res = dbg->de_reloc_name(dbg,
1276*f3e7f55eSRobert Mustacchi                         DEBUG_FRAME,
1277*f3e7f55eSRobert Mustacchi                         /* r_offset = */
1278*f3e7f55eSRobert Mustacchi                         (data - fde_start_point) + cur_off + uwordb_size,
1279*f3e7f55eSRobert Mustacchi                         curinst->dfp_sym_index,
1280*f3e7f55eSRobert Mustacchi                         dwarf_drt_data_reloc,
1281*f3e7f55eSRobert Mustacchi                         upointer_size);
1282*f3e7f55eSRobert Mustacchi                     if (res != DW_DLV_OK) {
1283*f3e7f55eSRobert Mustacchi                         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1284*f3e7f55eSRobert Mustacchi                         return (0);
1285*f3e7f55eSRobert Mustacchi                     }
1286*f3e7f55eSRobert Mustacchi                 }
1287*f3e7f55eSRobert Mustacchi #endif
1288*f3e7f55eSRobert Mustacchi                 memcpy((void *) data,
1289*f3e7f55eSRobert Mustacchi                    (const void *) curinst->dfp_args,
1290*f3e7f55eSRobert Mustacchi                    curinst->dfp_nbytes);
1291*f3e7f55eSRobert Mustacchi                 data += curinst->dfp_nbytes;
1292*f3e7f55eSRobert Mustacchi                 curinst = curinst->dfp_next;
1293*f3e7f55eSRobert Mustacchi             }
1294*f3e7f55eSRobert Mustacchi         }
1295*f3e7f55eSRobert Mustacchi         /* padding */
1296*f3e7f55eSRobert Mustacchi         for (i = 0; i < pad; i++) {
1297*f3e7f55eSRobert Mustacchi             *data = DW_CFA_nop;
1298*f3e7f55eSRobert Mustacchi             data++;
1299*f3e7f55eSRobert Mustacchi         }
1300*f3e7f55eSRobert Mustacchi         cur_off += fde_length + uwordb_size;
1301*f3e7f55eSRobert Mustacchi         curfde = curfde->fde_next;
1302*f3e7f55eSRobert Mustacchi     }
1303*f3e7f55eSRobert Mustacchi 
1304*f3e7f55eSRobert Mustacchi 
1305*f3e7f55eSRobert Mustacchi     return (int) dbg->de_n_debug_sect;
1306*f3e7f55eSRobert Mustacchi }
1307*f3e7f55eSRobert Mustacchi 
1308*f3e7f55eSRobert Mustacchi /*
1309*f3e7f55eSRobert Mustacchi   These functions remember all the markers we see along
1310*f3e7f55eSRobert Mustacchi   with the right offset in the .debug_info section so that
1311*f3e7f55eSRobert Mustacchi   we can dump them all back to the user with the section info.
1312*f3e7f55eSRobert Mustacchi */
1313*f3e7f55eSRobert Mustacchi 
1314*f3e7f55eSRobert Mustacchi static int
marker_init(Dwarf_P_Debug dbg,unsigned count)1315*f3e7f55eSRobert Mustacchi marker_init(Dwarf_P_Debug dbg,
1316*f3e7f55eSRobert Mustacchi             unsigned count)
1317*f3e7f55eSRobert Mustacchi {
1318*f3e7f55eSRobert Mustacchi     dbg->de_marker_n_alloc = count;
1319*f3e7f55eSRobert Mustacchi     dbg->de_markers = NULL;
1320*f3e7f55eSRobert Mustacchi     if (count > 0) {
1321*f3e7f55eSRobert Mustacchi         dbg->de_markers = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Marker_s) *
1322*f3e7f55eSRobert Mustacchi                                              dbg->de_marker_n_alloc);
1323*f3e7f55eSRobert Mustacchi         if (dbg->de_markers == NULL) {
1324*f3e7f55eSRobert Mustacchi             dbg->de_marker_n_alloc = 0;
1325*f3e7f55eSRobert Mustacchi             return -1;
1326*f3e7f55eSRobert Mustacchi         }
1327*f3e7f55eSRobert Mustacchi     }
1328*f3e7f55eSRobert Mustacchi     return 0;
1329*f3e7f55eSRobert Mustacchi }
1330*f3e7f55eSRobert Mustacchi 
1331*f3e7f55eSRobert Mustacchi static int
marker_add(Dwarf_P_Debug dbg,Dwarf_Unsigned offset,Dwarf_Unsigned marker)1332*f3e7f55eSRobert Mustacchi marker_add(Dwarf_P_Debug dbg,
1333*f3e7f55eSRobert Mustacchi            Dwarf_Unsigned offset,
1334*f3e7f55eSRobert Mustacchi            Dwarf_Unsigned marker)
1335*f3e7f55eSRobert Mustacchi {
1336*f3e7f55eSRobert Mustacchi     if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) {
1337*f3e7f55eSRobert Mustacchi         unsigned n = dbg->de_marker_n_used++;
1338*f3e7f55eSRobert Mustacchi         dbg->de_markers[n].ma_offset = offset;
1339*f3e7f55eSRobert Mustacchi         dbg->de_markers[n].ma_marker = marker;
1340*f3e7f55eSRobert Mustacchi         return 0;
1341*f3e7f55eSRobert Mustacchi     }
1342*f3e7f55eSRobert Mustacchi 
1343*f3e7f55eSRobert Mustacchi     return -1;
1344*f3e7f55eSRobert Mustacchi }
1345*f3e7f55eSRobert Mustacchi 
1346*f3e7f55eSRobert Mustacchi Dwarf_Signed
dwarf_get_die_markers(Dwarf_P_Debug dbg,Dwarf_P_Marker * marker_list,Dwarf_Unsigned * marker_count,Dwarf_Error * error)1347*f3e7f55eSRobert Mustacchi dwarf_get_die_markers(Dwarf_P_Debug dbg,
1348*f3e7f55eSRobert Mustacchi                       Dwarf_P_Marker * marker_list, /* pointer to a pointer */
1349*f3e7f55eSRobert Mustacchi                       Dwarf_Unsigned * marker_count,
1350*f3e7f55eSRobert Mustacchi                       Dwarf_Error * error)
1351*f3e7f55eSRobert Mustacchi {
1352*f3e7f55eSRobert Mustacchi     if (marker_list == NULL || marker_count == NULL) {
1353*f3e7f55eSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_BADADDR);
1354*f3e7f55eSRobert Mustacchi     }
1355*f3e7f55eSRobert Mustacchi     if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) {
1356*f3e7f55eSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_BADADDR);
1357*f3e7f55eSRobert Mustacchi     }
1358*f3e7f55eSRobert Mustacchi 
1359*f3e7f55eSRobert Mustacchi     *marker_list = dbg->de_markers;
1360*f3e7f55eSRobert Mustacchi     *marker_count = dbg->de_marker_n_used;
1361*f3e7f55eSRobert Mustacchi     return DW_DLV_OK;
1362*f3e7f55eSRobert Mustacchi }
1363*f3e7f55eSRobert Mustacchi 
1364*f3e7f55eSRobert Mustacchi /* These functions provide the offsets of DW_FORM_string
1365*f3e7f55eSRobert Mustacchi    attributes in the section section_index. These information
1366*f3e7f55eSRobert Mustacchi    will enable a producer app that is generating assembly
1367*f3e7f55eSRobert Mustacchi    text output to easily emit those attributes in ascii form
1368*f3e7f55eSRobert Mustacchi    without having to decode the byte stream.
1369*f3e7f55eSRobert Mustacchi  */
1370*f3e7f55eSRobert Mustacchi static int
string_attr_init(Dwarf_P_Debug dbg,Dwarf_Signed section_index,unsigned count)1371*f3e7f55eSRobert Mustacchi string_attr_init (Dwarf_P_Debug dbg,
1372*f3e7f55eSRobert Mustacchi                   Dwarf_Signed section_index,
1373*f3e7f55eSRobert Mustacchi                   unsigned count)
1374*f3e7f55eSRobert Mustacchi {
1375*f3e7f55eSRobert Mustacchi     Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
1376*f3e7f55eSRobert Mustacchi 
1377*f3e7f55eSRobert Mustacchi     sect_sa->sect_sa_n_alloc = count;
1378*f3e7f55eSRobert Mustacchi     sect_sa->sect_sa_list = NULL;
1379*f3e7f55eSRobert Mustacchi     if (count > 0) {
1380*f3e7f55eSRobert Mustacchi         sect_sa->sect_sa_section_number = section_index;
1381*f3e7f55eSRobert Mustacchi         sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg,
1382*f3e7f55eSRobert Mustacchi                                                    sizeof(struct Dwarf_P_String_Attr_s)
1383*f3e7f55eSRobert Mustacchi                                                    * sect_sa->sect_sa_n_alloc);
1384*f3e7f55eSRobert Mustacchi         if (sect_sa->sect_sa_list == NULL) {
1385*f3e7f55eSRobert Mustacchi             sect_sa->sect_sa_n_alloc = 0;
1386*f3e7f55eSRobert Mustacchi             return -1;
1387*f3e7f55eSRobert Mustacchi         }
1388*f3e7f55eSRobert Mustacchi     }
1389*f3e7f55eSRobert Mustacchi     return 0;
1390*f3e7f55eSRobert Mustacchi }
1391*f3e7f55eSRobert Mustacchi 
1392*f3e7f55eSRobert Mustacchi static int
string_attr_add(Dwarf_P_Debug dbg,Dwarf_Signed section_index,Dwarf_Unsigned offset,Dwarf_P_Attribute attr)1393*f3e7f55eSRobert Mustacchi string_attr_add (Dwarf_P_Debug dbg,
1394*f3e7f55eSRobert Mustacchi                  Dwarf_Signed section_index,
1395*f3e7f55eSRobert Mustacchi                  Dwarf_Unsigned offset,
1396*f3e7f55eSRobert Mustacchi                  Dwarf_P_Attribute attr)
1397*f3e7f55eSRobert Mustacchi {
1398*f3e7f55eSRobert Mustacchi     Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
1399*f3e7f55eSRobert Mustacchi     if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) {
1400*f3e7f55eSRobert Mustacchi         unsigned n = sect_sa->sect_sa_n_used++;
1401*f3e7f55eSRobert Mustacchi         sect_sa->sect_sa_list[n].sa_offset = offset;
1402*f3e7f55eSRobert Mustacchi         sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes;
1403*f3e7f55eSRobert Mustacchi         return 0;
1404*f3e7f55eSRobert Mustacchi     }
1405*f3e7f55eSRobert Mustacchi 
1406*f3e7f55eSRobert Mustacchi     return -1;
1407*f3e7f55eSRobert Mustacchi }
1408*f3e7f55eSRobert Mustacchi 
1409*f3e7f55eSRobert Mustacchi int
dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,Dwarf_Unsigned * count_of_sa_sections,int * drd_buffer_version,Dwarf_Error * error)1410*f3e7f55eSRobert Mustacchi dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,
1411*f3e7f55eSRobert Mustacchi                                   Dwarf_Unsigned *
1412*f3e7f55eSRobert Mustacchi                                   count_of_sa_sections,
1413*f3e7f55eSRobert Mustacchi                                   int *drd_buffer_version,
1414*f3e7f55eSRobert Mustacchi                                   Dwarf_Error *error)
1415*f3e7f55eSRobert Mustacchi {
1416*f3e7f55eSRobert Mustacchi     int i;
1417*f3e7f55eSRobert Mustacchi     unsigned int count = 0;
1418*f3e7f55eSRobert Mustacchi 
1419*f3e7f55eSRobert Mustacchi     for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
1420*f3e7f55eSRobert Mustacchi         if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) {
1421*f3e7f55eSRobert Mustacchi             ++count;
1422*f3e7f55eSRobert Mustacchi         }
1423*f3e7f55eSRobert Mustacchi     }
1424*f3e7f55eSRobert Mustacchi     *count_of_sa_sections = (Dwarf_Unsigned) count;
1425*f3e7f55eSRobert Mustacchi     *drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
1426*f3e7f55eSRobert Mustacchi 
1427*f3e7f55eSRobert Mustacchi     return DW_DLV_OK;
1428*f3e7f55eSRobert Mustacchi }
1429*f3e7f55eSRobert Mustacchi 
1430*f3e7f55eSRobert Mustacchi int
dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,Dwarf_Signed * elf_section_index,Dwarf_Unsigned * sect_sa_buffer_count,Dwarf_P_String_Attr * sect_sa_buffer,Dwarf_Error * error)1431*f3e7f55eSRobert Mustacchi dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,
1432*f3e7f55eSRobert Mustacchi                                  Dwarf_Signed *elf_section_index,
1433*f3e7f55eSRobert Mustacchi                                  Dwarf_Unsigned *sect_sa_buffer_count,
1434*f3e7f55eSRobert Mustacchi                                  Dwarf_P_String_Attr *sect_sa_buffer,
1435*f3e7f55eSRobert Mustacchi                                  Dwarf_Error *error)
1436*f3e7f55eSRobert Mustacchi {
1437*f3e7f55eSRobert Mustacchi     int i;
1438*f3e7f55eSRobert Mustacchi     int next = dbg->de_sect_sa_next_to_return;
1439*f3e7f55eSRobert Mustacchi 
1440*f3e7f55eSRobert Mustacchi     for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
1441*f3e7f55eSRobert Mustacchi         Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i];
1442*f3e7f55eSRobert Mustacchi         if (sect_sa->sect_sa_n_used > 0) {
1443*f3e7f55eSRobert Mustacchi             dbg->de_sect_sa_next_to_return = i + 1;
1444*f3e7f55eSRobert Mustacchi             *elf_section_index = sect_sa->sect_sa_section_number;
1445*f3e7f55eSRobert Mustacchi             *sect_sa_buffer_count = sect_sa->sect_sa_n_used;
1446*f3e7f55eSRobert Mustacchi             *sect_sa_buffer = sect_sa->sect_sa_list;
1447*f3e7f55eSRobert Mustacchi             return DW_DLV_OK;
1448*f3e7f55eSRobert Mustacchi         }
1449*f3e7f55eSRobert Mustacchi     }
1450*f3e7f55eSRobert Mustacchi     return DW_DLV_NO_ENTRY;
1451*f3e7f55eSRobert Mustacchi }
1452*f3e7f55eSRobert Mustacchi 
1453*f3e7f55eSRobert Mustacchi 
1454*f3e7f55eSRobert Mustacchi 
1455*f3e7f55eSRobert Mustacchi /*---------------------------------------------------------------
1456*f3e7f55eSRobert Mustacchi         Generate debug_info and debug_abbrev sections
1457*f3e7f55eSRobert Mustacchi ---------------------------------------------------------------*/
1458*f3e7f55eSRobert Mustacchi static int
_dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,Dwarf_Error * error)1459*f3e7f55eSRobert Mustacchi _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error)
1460*f3e7f55eSRobert Mustacchi {
1461*f3e7f55eSRobert Mustacchi     int elfsectno_of_debug_info = 0;
1462*f3e7f55eSRobert Mustacchi     int abbrevsectno = 0;
1463*f3e7f55eSRobert Mustacchi     unsigned char *data = 0;
1464*f3e7f55eSRobert Mustacchi     int cu_header_size = 0;
1465*f3e7f55eSRobert Mustacchi     Dwarf_P_Abbrev curabbrev = 0;
1466*f3e7f55eSRobert Mustacchi     Dwarf_P_Abbrev abbrev_head = 0;
1467*f3e7f55eSRobert Mustacchi     Dwarf_P_Abbrev abbrev_tail = 0;
1468*f3e7f55eSRobert Mustacchi     Dwarf_P_Die curdie = 0;
1469*f3e7f55eSRobert Mustacchi     Dwarf_P_Die first_child = 0;
1470*f3e7f55eSRobert Mustacchi     Dwarf_Word dw = 0;
1471*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned du = 0;
1472*f3e7f55eSRobert Mustacchi     Dwarf_Half dh = 0;
1473*f3e7f55eSRobert Mustacchi     Dwarf_Ubyte db = 0;
1474*f3e7f55eSRobert Mustacchi     Dwarf_Half version = 0;     /* Need 2 byte quantity. */
1475*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */
1476*f3e7f55eSRobert Mustacchi     int n_abbrevs = 0;
1477*f3e7f55eSRobert Mustacchi     int res = 0;
1478*f3e7f55eSRobert Mustacchi     unsigned marker_count = 0;
1479*f3e7f55eSRobert Mustacchi     unsigned string_attr_count = 0;
1480*f3e7f55eSRobert Mustacchi     unsigned string_attr_offset = 0;
1481*f3e7f55eSRobert Mustacchi 
1482*f3e7f55eSRobert Mustacchi     Dwarf_Small *start_info_sec = 0;
1483*f3e7f55eSRobert Mustacchi 
1484*f3e7f55eSRobert Mustacchi     int uwordb_size = dbg->de_offset_size;
1485*f3e7f55eSRobert Mustacchi     int extension_size = dbg->de_64bit_extension ? 4 : 0;
1486*f3e7f55eSRobert Mustacchi 
1487*f3e7f55eSRobert Mustacchi     abbrev_head = abbrev_tail = NULL;
1488*f3e7f55eSRobert Mustacchi     elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
1489*f3e7f55eSRobert Mustacchi 
1490*f3e7f55eSRobert Mustacchi     /* write cu header */
1491*f3e7f55eSRobert Mustacchi     cu_header_size = BEGIN_LEN_SIZE + sizeof(Dwarf_Half) +      /* version
1492*f3e7f55eSRobert Mustacchi                                                                    stamp
1493*f3e7f55eSRobert Mustacchi                                                                  */
1494*f3e7f55eSRobert Mustacchi         uwordb_size +           /* offset into abbrev table */
1495*f3e7f55eSRobert Mustacchi         sizeof(Dwarf_Ubyte);    /* size of target address */
1496*f3e7f55eSRobert Mustacchi     GET_CHUNK(dbg, elfsectno_of_debug_info, data, cu_header_size,
1497*f3e7f55eSRobert Mustacchi               error);
1498*f3e7f55eSRobert Mustacchi     start_info_sec = data;
1499*f3e7f55eSRobert Mustacchi     if (extension_size) {
1500*f3e7f55eSRobert Mustacchi         du = DISTINGUISHED_VALUE;
1501*f3e7f55eSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) data,
1502*f3e7f55eSRobert Mustacchi                         (const void *) &du, sizeof(du), extension_size);
1503*f3e7f55eSRobert Mustacchi         data += extension_size;
1504*f3e7f55eSRobert Mustacchi     }
1505*f3e7f55eSRobert Mustacchi     du = 0;                     /* length of debug_info, not counting
1506*f3e7f55eSRobert Mustacchi                                    this field itself (unknown at this
1507*f3e7f55eSRobert Mustacchi                                    point). */
1508*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data,
1509*f3e7f55eSRobert Mustacchi                     (const void *) &du, sizeof(du), uwordb_size);
1510*f3e7f55eSRobert Mustacchi     data += uwordb_size;
1511*f3e7f55eSRobert Mustacchi 
1512*f3e7f55eSRobert Mustacchi     version = CURRENT_VERSION_STAMP;    /* assume this length will not
1513*f3e7f55eSRobert Mustacchi                                            change */
1514*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version,
1515*f3e7f55eSRobert Mustacchi                     sizeof(version), sizeof(Dwarf_Half));
1516*f3e7f55eSRobert Mustacchi     data += sizeof(Dwarf_Half);
1517*f3e7f55eSRobert Mustacchi 
1518*f3e7f55eSRobert Mustacchi     du = 0;                     /* offset into abbrev table, not yet
1519*f3e7f55eSRobert Mustacchi                                    known. */
1520*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data,
1521*f3e7f55eSRobert Mustacchi                     (const void *) &du, sizeof(du), uwordb_size);
1522*f3e7f55eSRobert Mustacchi     data += uwordb_size;
1523*f3e7f55eSRobert Mustacchi 
1524*f3e7f55eSRobert Mustacchi 
1525*f3e7f55eSRobert Mustacchi     db = dbg->de_pointer_size;
1526*f3e7f55eSRobert Mustacchi 
1527*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1528*f3e7f55eSRobert Mustacchi                     sizeof(db), 1);
1529*f3e7f55eSRobert Mustacchi 
1530*f3e7f55eSRobert Mustacchi     /* We have filled the chunk we got with GET_CHUNK. At this point we
1531*f3e7f55eSRobert Mustacchi        no longer dare use "data" or "start_info_sec" as a pointer any
1532*f3e7f55eSRobert Mustacchi        longer except to refer to that first small chunk for the cu
1533*f3e7f55eSRobert Mustacchi        header. */
1534*f3e7f55eSRobert Mustacchi 
1535*f3e7f55eSRobert Mustacchi     curdie = dbg->de_dies;
1536*f3e7f55eSRobert Mustacchi 
1537*f3e7f55eSRobert Mustacchi     /* create AT_macro_info if appropriate */
1538*f3e7f55eSRobert Mustacchi     if (dbg->de_first_macinfo != NULL) {
1539*f3e7f55eSRobert Mustacchi         if (_dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error) < 0)
1540*f3e7f55eSRobert Mustacchi             return -1;
1541*f3e7f55eSRobert Mustacchi     }
1542*f3e7f55eSRobert Mustacchi 
1543*f3e7f55eSRobert Mustacchi     /* create AT_stmt_list attribute if necessary */
1544*f3e7f55eSRobert Mustacchi     if (dwarf_need_debug_line_section(dbg) == TRUE)
1545*f3e7f55eSRobert Mustacchi         if (_dwarf_pro_add_AT_stmt_list(dbg, curdie, error) < 0)
1546*f3e7f55eSRobert Mustacchi             return -1;
1547*f3e7f55eSRobert Mustacchi 
1548*f3e7f55eSRobert Mustacchi     die_off = cu_header_size;
1549*f3e7f55eSRobert Mustacchi 
1550*f3e7f55eSRobert Mustacchi     /*
1551*f3e7f55eSRobert Mustacchi        Relocation for abbrev offset in cu header store relocation
1552*f3e7f55eSRobert Mustacchi        record in linked list */
1553*f3e7f55eSRobert Mustacchi     res = dbg->de_reloc_name(dbg, DEBUG_INFO, BEGIN_LEN_SIZE +
1554*f3e7f55eSRobert Mustacchi                              sizeof(Dwarf_Half),
1555*f3e7f55eSRobert Mustacchi                              /* r_offset */
1556*f3e7f55eSRobert Mustacchi                              dbg->de_sect_name_idx[DEBUG_ABBREV],
1557*f3e7f55eSRobert Mustacchi                              dwarf_drt_data_reloc, uwordb_size);
1558*f3e7f55eSRobert Mustacchi     if (res != DW_DLV_OK) {
1559*f3e7f55eSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1560*f3e7f55eSRobert Mustacchi     }
1561*f3e7f55eSRobert Mustacchi 
1562*f3e7f55eSRobert Mustacchi     /* pass 0: only top level dies, add at_sibling attribute to those
1563*f3e7f55eSRobert Mustacchi        dies with children */
1564*f3e7f55eSRobert Mustacchi     first_child = curdie->di_child;
1565*f3e7f55eSRobert Mustacchi     while (first_child && first_child->di_right) {
1566*f3e7f55eSRobert Mustacchi         if (first_child->di_child)
1567*f3e7f55eSRobert Mustacchi             dwarf_add_AT_reference(dbg,
1568*f3e7f55eSRobert Mustacchi                                    first_child,
1569*f3e7f55eSRobert Mustacchi                                    DW_AT_sibling,
1570*f3e7f55eSRobert Mustacchi                                    first_child->di_right, error);
1571*f3e7f55eSRobert Mustacchi         first_child = first_child->di_right;
1572*f3e7f55eSRobert Mustacchi     }
1573*f3e7f55eSRobert Mustacchi 
1574*f3e7f55eSRobert Mustacchi     /* pass 1: create abbrev info, get die offsets, calc relocations */
1575*f3e7f55eSRobert Mustacchi     marker_count = 0;
1576*f3e7f55eSRobert Mustacchi     string_attr_count = 0;
1577*f3e7f55eSRobert Mustacchi     while (curdie != NULL) {
1578*f3e7f55eSRobert Mustacchi         int nbytes = 0;
1579*f3e7f55eSRobert Mustacchi         Dwarf_P_Attribute curattr;
1580*f3e7f55eSRobert Mustacchi         Dwarf_P_Attribute new_first_attr;
1581*f3e7f55eSRobert Mustacchi         Dwarf_P_Attribute new_last_attr;
1582*f3e7f55eSRobert Mustacchi         char *space = 0;
1583*f3e7f55eSRobert Mustacchi         int res = 0;
1584*f3e7f55eSRobert Mustacchi         char buff1[ENCODE_SPACE_NEEDED];
1585*f3e7f55eSRobert Mustacchi         int i = 0;
1586*f3e7f55eSRobert Mustacchi 
1587*f3e7f55eSRobert Mustacchi         curdie->di_offset = die_off;
1588*f3e7f55eSRobert Mustacchi 
1589*f3e7f55eSRobert Mustacchi         if (curdie->di_marker != 0)
1590*f3e7f55eSRobert Mustacchi             marker_count++;
1591*f3e7f55eSRobert Mustacchi 
1592*f3e7f55eSRobert Mustacchi         curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head);
1593*f3e7f55eSRobert Mustacchi         if (curabbrev == NULL) {
1594*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1595*f3e7f55eSRobert Mustacchi         }
1596*f3e7f55eSRobert Mustacchi         if (abbrev_head == NULL) {
1597*f3e7f55eSRobert Mustacchi             n_abbrevs = 1;
1598*f3e7f55eSRobert Mustacchi             curabbrev->abb_idx = n_abbrevs;
1599*f3e7f55eSRobert Mustacchi             abbrev_tail = abbrev_head = curabbrev;
1600*f3e7f55eSRobert Mustacchi         } else {
1601*f3e7f55eSRobert Mustacchi             /* check if its a new abbreviation, if yes, add to tail */
1602*f3e7f55eSRobert Mustacchi             if (curabbrev->abb_idx == 0) {
1603*f3e7f55eSRobert Mustacchi                 n_abbrevs++;
1604*f3e7f55eSRobert Mustacchi                 curabbrev->abb_idx = n_abbrevs;
1605*f3e7f55eSRobert Mustacchi                 abbrev_tail->abb_next = curabbrev;
1606*f3e7f55eSRobert Mustacchi                 abbrev_tail = curabbrev;
1607*f3e7f55eSRobert Mustacchi             }
1608*f3e7f55eSRobert Mustacchi         }
1609*f3e7f55eSRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx,
1610*f3e7f55eSRobert Mustacchi                                           &nbytes,
1611*f3e7f55eSRobert Mustacchi                                           buff1, sizeof(buff1));
1612*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
1613*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1614*f3e7f55eSRobert Mustacchi         }
1615*f3e7f55eSRobert Mustacchi         space = _dwarf_p_get_alloc(dbg, nbytes);
1616*f3e7f55eSRobert Mustacchi         if (space == NULL) {
1617*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1618*f3e7f55eSRobert Mustacchi         }
1619*f3e7f55eSRobert Mustacchi         memcpy(space, buff1, nbytes);
1620*f3e7f55eSRobert Mustacchi         curdie->di_abbrev = space;
1621*f3e7f55eSRobert Mustacchi         curdie->di_abbrev_nbytes = nbytes;
1622*f3e7f55eSRobert Mustacchi         die_off += nbytes;
1623*f3e7f55eSRobert Mustacchi 
1624*f3e7f55eSRobert Mustacchi         /* Resorting the attributes!! */
1625*f3e7f55eSRobert Mustacchi         new_first_attr = new_last_attr = NULL;
1626*f3e7f55eSRobert Mustacchi         curattr = curdie->di_attrs;
1627*f3e7f55eSRobert Mustacchi         for (i = 0; i < (int)curabbrev->abb_n_attr; i++) {
1628*f3e7f55eSRobert Mustacchi             Dwarf_P_Attribute ca;
1629*f3e7f55eSRobert Mustacchi             Dwarf_P_Attribute cl;
1630*f3e7f55eSRobert Mustacchi 
1631*f3e7f55eSRobert Mustacchi             /* The following should always find an attribute! */
1632*f3e7f55eSRobert Mustacchi             for (ca = cl = curattr;
1633*f3e7f55eSRobert Mustacchi                  ca && curabbrev->abb_attrs[i] != ca->ar_attribute;
1634*f3e7f55eSRobert Mustacchi                  cl = ca, ca = ca->ar_next)
1635*f3e7f55eSRobert Mustacchi             {
1636*f3e7f55eSRobert Mustacchi             }
1637*f3e7f55eSRobert Mustacchi 
1638*f3e7f55eSRobert Mustacchi             if (!ca) {
1639*f3e7f55eSRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg,DW_DLE_ABBREV_ALLOC, -1);
1640*f3e7f55eSRobert Mustacchi             }
1641*f3e7f55eSRobert Mustacchi 
1642*f3e7f55eSRobert Mustacchi             /* Remove the attribute from the old list. */
1643*f3e7f55eSRobert Mustacchi             if (ca == curattr) {
1644*f3e7f55eSRobert Mustacchi                 curattr = ca->ar_next;
1645*f3e7f55eSRobert Mustacchi             } else {
1646*f3e7f55eSRobert Mustacchi                 cl->ar_next = ca->ar_next;
1647*f3e7f55eSRobert Mustacchi             }
1648*f3e7f55eSRobert Mustacchi 
1649*f3e7f55eSRobert Mustacchi             ca->ar_next = NULL;
1650*f3e7f55eSRobert Mustacchi 
1651*f3e7f55eSRobert Mustacchi             /* Add the attribute to the new list. */
1652*f3e7f55eSRobert Mustacchi             if (new_first_attr == NULL) {
1653*f3e7f55eSRobert Mustacchi                 new_first_attr = new_last_attr = ca;
1654*f3e7f55eSRobert Mustacchi             } else {
1655*f3e7f55eSRobert Mustacchi                 new_last_attr->ar_next = ca;
1656*f3e7f55eSRobert Mustacchi                 new_last_attr = ca;
1657*f3e7f55eSRobert Mustacchi             }
1658*f3e7f55eSRobert Mustacchi         }
1659*f3e7f55eSRobert Mustacchi 
1660*f3e7f55eSRobert Mustacchi         curdie->di_attrs = new_first_attr;
1661*f3e7f55eSRobert Mustacchi 
1662*f3e7f55eSRobert Mustacchi         curattr = curdie->di_attrs;
1663*f3e7f55eSRobert Mustacchi 
1664*f3e7f55eSRobert Mustacchi         while (curattr) {
1665*f3e7f55eSRobert Mustacchi             if (curattr->ar_rel_type != R_MIPS_NONE) {
1666*f3e7f55eSRobert Mustacchi                 switch (curattr->ar_attribute) {
1667*f3e7f55eSRobert Mustacchi                 case DW_AT_stmt_list:
1668*f3e7f55eSRobert Mustacchi                     curattr->ar_rel_symidx =
1669*f3e7f55eSRobert Mustacchi                         dbg->de_sect_name_idx[DEBUG_LINE];
1670*f3e7f55eSRobert Mustacchi                     break;
1671*f3e7f55eSRobert Mustacchi                 case DW_AT_MIPS_fde:
1672*f3e7f55eSRobert Mustacchi                     curattr->ar_rel_symidx =
1673*f3e7f55eSRobert Mustacchi                         dbg->de_sect_name_idx[DEBUG_FRAME];
1674*f3e7f55eSRobert Mustacchi                     break;
1675*f3e7f55eSRobert Mustacchi                 case DW_AT_macro_info:
1676*f3e7f55eSRobert Mustacchi                     curattr->ar_rel_symidx =
1677*f3e7f55eSRobert Mustacchi                         dbg->de_sect_name_idx[DEBUG_MACINFO];
1678*f3e7f55eSRobert Mustacchi                     break;
1679*f3e7f55eSRobert Mustacchi                 default:
1680*f3e7f55eSRobert Mustacchi                     break;
1681*f3e7f55eSRobert Mustacchi                 }
1682*f3e7f55eSRobert Mustacchi                 res = dbg->de_reloc_name(dbg, DEBUG_INFO, die_off + curattr->ar_rel_offset,     /* r_offset
1683*f3e7f55eSRobert Mustacchi                                                                                                  */
1684*f3e7f55eSRobert Mustacchi                                          curattr->ar_rel_symidx,
1685*f3e7f55eSRobert Mustacchi                                          dwarf_drt_data_reloc,
1686*f3e7f55eSRobert Mustacchi                                          curattr->ar_reloc_len);
1687*f3e7f55eSRobert Mustacchi 
1688*f3e7f55eSRobert Mustacchi                 if (res != DW_DLV_OK) {
1689*f3e7f55eSRobert Mustacchi                     DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1690*f3e7f55eSRobert Mustacchi                 }
1691*f3e7f55eSRobert Mustacchi 
1692*f3e7f55eSRobert Mustacchi             }
1693*f3e7f55eSRobert Mustacchi             if (curattr->ar_attribute_form == DW_FORM_string) {
1694*f3e7f55eSRobert Mustacchi                 string_attr_count++;
1695*f3e7f55eSRobert Mustacchi             }
1696*f3e7f55eSRobert Mustacchi             die_off += curattr->ar_nbytes;
1697*f3e7f55eSRobert Mustacchi             curattr = curattr->ar_next;
1698*f3e7f55eSRobert Mustacchi         }
1699*f3e7f55eSRobert Mustacchi 
1700*f3e7f55eSRobert Mustacchi         /* depth first search */
1701*f3e7f55eSRobert Mustacchi         if (curdie->di_child)
1702*f3e7f55eSRobert Mustacchi             curdie = curdie->di_child;
1703*f3e7f55eSRobert Mustacchi         else {
1704*f3e7f55eSRobert Mustacchi             while (curdie != NULL && curdie->di_right == NULL) {
1705*f3e7f55eSRobert Mustacchi                 curdie = curdie->di_parent;
1706*f3e7f55eSRobert Mustacchi                 die_off++;      /* since we are writing a null die at
1707*f3e7f55eSRobert Mustacchi                                    the end of each sibling chain */
1708*f3e7f55eSRobert Mustacchi             }
1709*f3e7f55eSRobert Mustacchi             if (curdie != NULL)
1710*f3e7f55eSRobert Mustacchi                 curdie = curdie->di_right;
1711*f3e7f55eSRobert Mustacchi         }
1712*f3e7f55eSRobert Mustacchi 
1713*f3e7f55eSRobert Mustacchi     } /* end while (curdie != NULL) */
1714*f3e7f55eSRobert Mustacchi 
1715*f3e7f55eSRobert Mustacchi     res = marker_init(dbg, marker_count);
1716*f3e7f55eSRobert Mustacchi     if (res == -1) {
1717*f3e7f55eSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1718*f3e7f55eSRobert Mustacchi     }
1719*f3e7f55eSRobert Mustacchi     res = string_attr_init(dbg, DEBUG_INFO, string_attr_count);
1720*f3e7f55eSRobert Mustacchi     if (res == -1) {
1721*f3e7f55eSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1722*f3e7f55eSRobert Mustacchi     }
1723*f3e7f55eSRobert Mustacchi 
1724*f3e7f55eSRobert Mustacchi     /* Pass 2: Write out the die information Here 'data' is a
1725*f3e7f55eSRobert Mustacchi        temporary, one block for each GET_CHUNK.  'data' is overused. */
1726*f3e7f55eSRobert Mustacchi     curdie = dbg->de_dies;
1727*f3e7f55eSRobert Mustacchi     while (curdie != NULL) {
1728*f3e7f55eSRobert Mustacchi         Dwarf_P_Attribute curattr;
1729*f3e7f55eSRobert Mustacchi 
1730*f3e7f55eSRobert Mustacchi         if (curdie->di_marker != 0) {
1731*f3e7f55eSRobert Mustacchi             res = marker_add(dbg, curdie->di_offset, curdie->di_marker);
1732*f3e7f55eSRobert Mustacchi             if (res == -1) {
1733*f3e7f55eSRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1734*f3e7f55eSRobert Mustacchi             }
1735*f3e7f55eSRobert Mustacchi         }
1736*f3e7f55eSRobert Mustacchi 
1737*f3e7f55eSRobert Mustacchi         /* index to abbreviation table */
1738*f3e7f55eSRobert Mustacchi         GET_CHUNK(dbg, elfsectno_of_debug_info,
1739*f3e7f55eSRobert Mustacchi                   data, curdie->di_abbrev_nbytes, error);
1740*f3e7f55eSRobert Mustacchi 
1741*f3e7f55eSRobert Mustacchi         memcpy((void *) data,
1742*f3e7f55eSRobert Mustacchi                (const void *) curdie->di_abbrev,
1743*f3e7f55eSRobert Mustacchi                curdie->di_abbrev_nbytes);
1744*f3e7f55eSRobert Mustacchi 
1745*f3e7f55eSRobert Mustacchi         /* Attribute values - need to fill in all form attributes */
1746*f3e7f55eSRobert Mustacchi         curattr = curdie->di_attrs;
1747*f3e7f55eSRobert Mustacchi         string_attr_offset = curdie->di_offset + curdie->di_abbrev_nbytes;
1748*f3e7f55eSRobert Mustacchi 
1749*f3e7f55eSRobert Mustacchi         while (curattr) {
1750*f3e7f55eSRobert Mustacchi             GET_CHUNK(dbg, elfsectno_of_debug_info, data,
1751*f3e7f55eSRobert Mustacchi                       (unsigned long) curattr->ar_nbytes, error);
1752*f3e7f55eSRobert Mustacchi             switch (curattr->ar_attribute_form) {
1753*f3e7f55eSRobert Mustacchi             case DW_FORM_ref1:
1754*f3e7f55eSRobert Mustacchi                 {
1755*f3e7f55eSRobert Mustacchi                     if (curattr->ar_ref_die->di_offset >
1756*f3e7f55eSRobert Mustacchi                         (unsigned) 0xff) {
1757*f3e7f55eSRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
1758*f3e7f55eSRobert Mustacchi                     }
1759*f3e7f55eSRobert Mustacchi                     db = curattr->ar_ref_die->di_offset;
1760*f3e7f55eSRobert Mustacchi                     WRITE_UNALIGNED(dbg, (void *) data,
1761*f3e7f55eSRobert Mustacchi                                     (const void *) &db,
1762*f3e7f55eSRobert Mustacchi                                     sizeof(db), sizeof(Dwarf_Ubyte));
1763*f3e7f55eSRobert Mustacchi                     break;
1764*f3e7f55eSRobert Mustacchi                 }
1765*f3e7f55eSRobert Mustacchi             case DW_FORM_ref2:
1766*f3e7f55eSRobert Mustacchi                 {
1767*f3e7f55eSRobert Mustacchi                     if (curattr->ar_ref_die->di_offset >
1768*f3e7f55eSRobert Mustacchi                         (unsigned) 0xffff) {
1769*f3e7f55eSRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
1770*f3e7f55eSRobert Mustacchi                     }
1771*f3e7f55eSRobert Mustacchi                     dh = curattr->ar_ref_die->di_offset;
1772*f3e7f55eSRobert Mustacchi                     WRITE_UNALIGNED(dbg, (void *) data,
1773*f3e7f55eSRobert Mustacchi                                     (const void *) &dh,
1774*f3e7f55eSRobert Mustacchi                                     sizeof(dh), sizeof(Dwarf_Half));
1775*f3e7f55eSRobert Mustacchi                     break;
1776*f3e7f55eSRobert Mustacchi                 }
1777*f3e7f55eSRobert Mustacchi             case DW_FORM_ref_addr:
1778*f3e7f55eSRobert Mustacchi                 {
1779*f3e7f55eSRobert Mustacchi                     /* curattr->ar_ref_die == NULL!
1780*f3e7f55eSRobert Mustacchi                      *
1781*f3e7f55eSRobert Mustacchi                      * ref_addr doesn't take a CU-offset.
1782*f3e7f55eSRobert Mustacchi                      * This is different than other refs.
1783*f3e7f55eSRobert Mustacchi                      * This value will be set by the user of the
1784*f3e7f55eSRobert Mustacchi                      * producer library using a relocation.
1785*f3e7f55eSRobert Mustacchi                      * No need to set a value here.
1786*f3e7f55eSRobert Mustacchi                      */
1787*f3e7f55eSRobert Mustacchi #if 0
1788*f3e7f55eSRobert Mustacchi                     du = curattr->ar_ref_die->di_offset;
1789*f3e7f55eSRobert Mustacchi                     {
1790*f3e7f55eSRobert Mustacchi                         /* ref to offset of die */
1791*f3e7f55eSRobert Mustacchi                         WRITE_UNALIGNED(dbg, (void *) data,
1792*f3e7f55eSRobert Mustacchi                                         (const void *) &du,
1793*f3e7f55eSRobert Mustacchi                                         sizeof(du), uwordb_size);
1794*f3e7f55eSRobert Mustacchi                     }
1795*f3e7f55eSRobert Mustacchi #endif
1796*f3e7f55eSRobert Mustacchi                     break;
1797*f3e7f55eSRobert Mustacchi 
1798*f3e7f55eSRobert Mustacchi                 }
1799*f3e7f55eSRobert Mustacchi             case DW_FORM_ref4:
1800*f3e7f55eSRobert Mustacchi                 {
1801*f3e7f55eSRobert Mustacchi                     if (curattr->ar_ref_die->di_offset >
1802*f3e7f55eSRobert Mustacchi                         (unsigned) 0xffffffff) {
1803*f3e7f55eSRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
1804*f3e7f55eSRobert Mustacchi                     }
1805*f3e7f55eSRobert Mustacchi                     dw = (Dwarf_Word) curattr->ar_ref_die->di_offset;
1806*f3e7f55eSRobert Mustacchi                     WRITE_UNALIGNED(dbg, (void *) data,
1807*f3e7f55eSRobert Mustacchi                                     (const void *) &dw,
1808*f3e7f55eSRobert Mustacchi                                     sizeof(dw), sizeof(Dwarf_ufixed));
1809*f3e7f55eSRobert Mustacchi                     break;
1810*f3e7f55eSRobert Mustacchi                 }
1811*f3e7f55eSRobert Mustacchi             case DW_FORM_ref8:
1812*f3e7f55eSRobert Mustacchi                 du = curattr->ar_ref_die->di_offset;
1813*f3e7f55eSRobert Mustacchi                 WRITE_UNALIGNED(dbg, (void *) data,
1814*f3e7f55eSRobert Mustacchi                                 (const void *) &du,
1815*f3e7f55eSRobert Mustacchi                                 sizeof(du), sizeof(Dwarf_Unsigned));
1816*f3e7f55eSRobert Mustacchi                 break;
1817*f3e7f55eSRobert Mustacchi             case DW_FORM_ref_udata:
1818*f3e7f55eSRobert Mustacchi                 {               /* unsigned leb128 offset */
1819*f3e7f55eSRobert Mustacchi 
1820*f3e7f55eSRobert Mustacchi                     int nbytes;
1821*f3e7f55eSRobert Mustacchi                     char buff1[ENCODE_SPACE_NEEDED];
1822*f3e7f55eSRobert Mustacchi 
1823*f3e7f55eSRobert Mustacchi                     res =
1824*f3e7f55eSRobert Mustacchi                         _dwarf_pro_encode_leb128_nm(curattr->
1825*f3e7f55eSRobert Mustacchi                                                     ar_ref_die->
1826*f3e7f55eSRobert Mustacchi                                                     di_offset, &nbytes,
1827*f3e7f55eSRobert Mustacchi                                                     buff1,
1828*f3e7f55eSRobert Mustacchi                                                     sizeof(buff1));
1829*f3e7f55eSRobert Mustacchi                     if (res != DW_DLV_OK) {
1830*f3e7f55eSRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1831*f3e7f55eSRobert Mustacchi                     }
1832*f3e7f55eSRobert Mustacchi 
1833*f3e7f55eSRobert Mustacchi                     memcpy(data, buff1, nbytes);
1834*f3e7f55eSRobert Mustacchi                     break;
1835*f3e7f55eSRobert Mustacchi                 }
1836*f3e7f55eSRobert Mustacchi             default:
1837*f3e7f55eSRobert Mustacchi                 memcpy((void *) data,
1838*f3e7f55eSRobert Mustacchi                        (const void *) curattr->ar_data,
1839*f3e7f55eSRobert Mustacchi                        curattr->ar_nbytes);
1840*f3e7f55eSRobert Mustacchi                 break;
1841*f3e7f55eSRobert Mustacchi             }
1842*f3e7f55eSRobert Mustacchi             if (curattr->ar_attribute_form == DW_FORM_string) {
1843*f3e7f55eSRobert Mustacchi                 string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr);
1844*f3e7f55eSRobert Mustacchi             }
1845*f3e7f55eSRobert Mustacchi             string_attr_offset += curattr->ar_nbytes;
1846*f3e7f55eSRobert Mustacchi             curattr = curattr->ar_next;
1847*f3e7f55eSRobert Mustacchi         }
1848*f3e7f55eSRobert Mustacchi 
1849*f3e7f55eSRobert Mustacchi         /* depth first search */
1850*f3e7f55eSRobert Mustacchi         if (curdie->di_child)
1851*f3e7f55eSRobert Mustacchi             curdie = curdie->di_child;
1852*f3e7f55eSRobert Mustacchi         else {
1853*f3e7f55eSRobert Mustacchi             while (curdie != NULL && curdie->di_right == NULL) {
1854*f3e7f55eSRobert Mustacchi                 GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1, error);
1855*f3e7f55eSRobert Mustacchi                 *data = '\0';
1856*f3e7f55eSRobert Mustacchi                 curdie = curdie->di_parent;
1857*f3e7f55eSRobert Mustacchi             }
1858*f3e7f55eSRobert Mustacchi             if (curdie != NULL)
1859*f3e7f55eSRobert Mustacchi                 curdie = curdie->di_right;
1860*f3e7f55eSRobert Mustacchi         }
1861*f3e7f55eSRobert Mustacchi     } /* end while (curdir != NULL) */
1862*f3e7f55eSRobert Mustacchi 
1863*f3e7f55eSRobert Mustacchi     /* Write out debug_info size */
1864*f3e7f55eSRobert Mustacchi     /* Dont include length field or extension bytes */
1865*f3e7f55eSRobert Mustacchi     du = die_off - BEGIN_LEN_SIZE;
1866*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) (start_info_sec + extension_size),
1867*f3e7f55eSRobert Mustacchi                     (const void *) &du, sizeof(du), uwordb_size);
1868*f3e7f55eSRobert Mustacchi 
1869*f3e7f55eSRobert Mustacchi 
1870*f3e7f55eSRobert Mustacchi     data = 0;                   /* Emphasise not usable now */
1871*f3e7f55eSRobert Mustacchi 
1872*f3e7f55eSRobert Mustacchi     /* Write out debug_abbrev section */
1873*f3e7f55eSRobert Mustacchi     abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV];
1874*f3e7f55eSRobert Mustacchi 
1875*f3e7f55eSRobert Mustacchi     curabbrev = abbrev_head;
1876*f3e7f55eSRobert Mustacchi     while (curabbrev) {
1877*f3e7f55eSRobert Mustacchi         char *val;
1878*f3e7f55eSRobert Mustacchi         int nbytes;
1879*f3e7f55eSRobert Mustacchi         int idx;
1880*f3e7f55eSRobert Mustacchi         int res;
1881*f3e7f55eSRobert Mustacchi         char buff1[ENCODE_SPACE_NEEDED];
1882*f3e7f55eSRobert Mustacchi 
1883*f3e7f55eSRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes,
1884*f3e7f55eSRobert Mustacchi                                           buff1, sizeof(buff1));
1885*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
1886*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1887*f3e7f55eSRobert Mustacchi         }
1888*f3e7f55eSRobert Mustacchi 
1889*f3e7f55eSRobert Mustacchi         GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
1890*f3e7f55eSRobert Mustacchi         val = buff1;
1891*f3e7f55eSRobert Mustacchi         memcpy((void *) data, (const void *) val, nbytes);
1892*f3e7f55eSRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_tag, &nbytes,
1893*f3e7f55eSRobert Mustacchi                                           buff1, sizeof(buff1));
1894*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
1895*f3e7f55eSRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1896*f3e7f55eSRobert Mustacchi         }
1897*f3e7f55eSRobert Mustacchi         val = buff1;
1898*f3e7f55eSRobert Mustacchi         GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
1899*f3e7f55eSRobert Mustacchi         memcpy((void *) data, (const void *) val, nbytes);
1900*f3e7f55eSRobert Mustacchi         db = curabbrev->abb_children;
1901*f3e7f55eSRobert Mustacchi         GET_CHUNK(dbg, abbrevsectno, data, sizeof(Dwarf_Ubyte), error);
1902*f3e7f55eSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1903*f3e7f55eSRobert Mustacchi                         sizeof(db), sizeof(Dwarf_Ubyte));
1904*f3e7f55eSRobert Mustacchi 
1905*f3e7f55eSRobert Mustacchi         /* add attributes and forms */
1906*f3e7f55eSRobert Mustacchi         for (idx = 0; idx < curabbrev->abb_n_attr; idx++) {
1907*f3e7f55eSRobert Mustacchi             res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_attrs[idx],
1908*f3e7f55eSRobert Mustacchi                                               &nbytes,
1909*f3e7f55eSRobert Mustacchi                                               buff1, sizeof(buff1));
1910*f3e7f55eSRobert Mustacchi             if (res != DW_DLV_OK) {
1911*f3e7f55eSRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1912*f3e7f55eSRobert Mustacchi             }
1913*f3e7f55eSRobert Mustacchi             val = buff1;
1914*f3e7f55eSRobert Mustacchi             GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
1915*f3e7f55eSRobert Mustacchi             memcpy((void *) data, (const void *) val, nbytes);
1916*f3e7f55eSRobert Mustacchi             res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_forms[idx],
1917*f3e7f55eSRobert Mustacchi                                               &nbytes,
1918*f3e7f55eSRobert Mustacchi                                               buff1, sizeof(buff1));
1919*f3e7f55eSRobert Mustacchi             if (res != DW_DLV_OK) {
1920*f3e7f55eSRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1921*f3e7f55eSRobert Mustacchi             }
1922*f3e7f55eSRobert Mustacchi             val = buff1;
1923*f3e7f55eSRobert Mustacchi             GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
1924*f3e7f55eSRobert Mustacchi             memcpy((void *) data, (const void *) val, nbytes);
1925*f3e7f55eSRobert Mustacchi         }
1926*f3e7f55eSRobert Mustacchi         GET_CHUNK(dbg, abbrevsectno, data, 2, error);   /* two zeros,
1927*f3e7f55eSRobert Mustacchi                                                            for last
1928*f3e7f55eSRobert Mustacchi                                                            entry, see
1929*f3e7f55eSRobert Mustacchi                                                            dwarf2 sec
1930*f3e7f55eSRobert Mustacchi                                                            7.5.3 */
1931*f3e7f55eSRobert Mustacchi         *data = 0;
1932*f3e7f55eSRobert Mustacchi         data++;
1933*f3e7f55eSRobert Mustacchi         *data = 0;
1934*f3e7f55eSRobert Mustacchi 
1935*f3e7f55eSRobert Mustacchi         curabbrev = curabbrev->abb_next;
1936*f3e7f55eSRobert Mustacchi     }
1937*f3e7f55eSRobert Mustacchi 
1938*f3e7f55eSRobert Mustacchi     GET_CHUNK(dbg, abbrevsectno, data, 1, error);       /* one zero,
1939*f3e7f55eSRobert Mustacchi                                                            for end of
1940*f3e7f55eSRobert Mustacchi                                                            cu, see
1941*f3e7f55eSRobert Mustacchi                                                            dwarf2 sec
1942*f3e7f55eSRobert Mustacchi                                                            7.5.3 */
1943*f3e7f55eSRobert Mustacchi     *data = 0;
1944*f3e7f55eSRobert Mustacchi 
1945*f3e7f55eSRobert Mustacchi 
1946*f3e7f55eSRobert Mustacchi     return (int) dbg->de_n_debug_sect;
1947*f3e7f55eSRobert Mustacchi }
1948*f3e7f55eSRobert Mustacchi 
1949*f3e7f55eSRobert Mustacchi 
1950*f3e7f55eSRobert Mustacchi /*---------------------------------------------------------------------
1951*f3e7f55eSRobert Mustacchi         Get a buffer of section data.
1952*f3e7f55eSRobert Mustacchi         section_idx is the elf-section number that this data applies to.
1953*f3e7f55eSRobert Mustacchi         length shows length of returned data
1954*f3e7f55eSRobert Mustacchi ----------------------------------------------------------------------*/
1955*f3e7f55eSRobert Mustacchi  /*ARGSUSED*/                   /* pretend all args used */
1956*f3e7f55eSRobert Mustacchi     Dwarf_Ptr
dwarf_get_section_bytes(Dwarf_P_Debug dbg,Dwarf_Signed dwarf_section,Dwarf_Signed * section_idx,Dwarf_Unsigned * length,Dwarf_Error * error)1957*f3e7f55eSRobert Mustacchi dwarf_get_section_bytes(Dwarf_P_Debug dbg,
1958*f3e7f55eSRobert Mustacchi                         Dwarf_Signed dwarf_section,
1959*f3e7f55eSRobert Mustacchi                         Dwarf_Signed * section_idx,
1960*f3e7f55eSRobert Mustacchi                         Dwarf_Unsigned * length, Dwarf_Error * error)
1961*f3e7f55eSRobert Mustacchi {
1962*f3e7f55eSRobert Mustacchi     Dwarf_Ptr buf;
1963*f3e7f55eSRobert Mustacchi 
1964*f3e7f55eSRobert Mustacchi     if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
1965*f3e7f55eSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL);
1966*f3e7f55eSRobert Mustacchi     }
1967*f3e7f55eSRobert Mustacchi 
1968*f3e7f55eSRobert Mustacchi     if (dbg->de_debug_sects == 0) {
1969*f3e7f55eSRobert Mustacchi         /* no more data !! */
1970*f3e7f55eSRobert Mustacchi         return NULL;
1971*f3e7f55eSRobert Mustacchi     }
1972*f3e7f55eSRobert Mustacchi     if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
1973*f3e7f55eSRobert Mustacchi         /* no data ever entered !! */
1974*f3e7f55eSRobert Mustacchi         return NULL;
1975*f3e7f55eSRobert Mustacchi     }
1976*f3e7f55eSRobert Mustacchi     *section_idx = dbg->de_debug_sects->ds_elf_sect_no;
1977*f3e7f55eSRobert Mustacchi     *length = dbg->de_debug_sects->ds_nbytes;
1978*f3e7f55eSRobert Mustacchi 
1979*f3e7f55eSRobert Mustacchi     buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data;
1980*f3e7f55eSRobert Mustacchi 
1981*f3e7f55eSRobert Mustacchi     dbg->de_debug_sects = dbg->de_debug_sects->ds_next;
1982*f3e7f55eSRobert Mustacchi 
1983*f3e7f55eSRobert Mustacchi     /* We may want to call the section stuff more than once: see
1984*f3e7f55eSRobert Mustacchi        dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */
1985*f3e7f55eSRobert Mustacchi 
1986*f3e7f55eSRobert Mustacchi     return buf;
1987*f3e7f55eSRobert Mustacchi }
1988*f3e7f55eSRobert Mustacchi 
1989*f3e7f55eSRobert Mustacchi /*
1990*f3e7f55eSRobert Mustacchi         No errors possible.
1991*f3e7f55eSRobert Mustacchi */
1992*f3e7f55eSRobert Mustacchi void
dwarf_reset_section_bytes(Dwarf_P_Debug dbg)1993*f3e7f55eSRobert Mustacchi dwarf_reset_section_bytes(Dwarf_P_Debug dbg)
1994*f3e7f55eSRobert Mustacchi {
1995*f3e7f55eSRobert Mustacchi     dbg->de_debug_sects = dbg->de_first_debug_sect;
1996*f3e7f55eSRobert Mustacchi     /* No need to reset; commented out decrement. dbg->de_n_debug_sect
1997*f3e7f55eSRobert Mustacchi        = ???; */
1998*f3e7f55eSRobert Mustacchi     dbg->de_reloc_next_to_return = 0;
1999*f3e7f55eSRobert Mustacchi     dbg->de_sect_sa_next_to_return = 0;
2000*f3e7f55eSRobert Mustacchi }
2001*f3e7f55eSRobert Mustacchi 
2002*f3e7f55eSRobert Mustacchi /*
2003*f3e7f55eSRobert Mustacchi     Storage handler. Gets either a new chunk of memory, or
2004*f3e7f55eSRobert Mustacchi     a pointer in existing memory, from the linked list attached
2005*f3e7f55eSRobert Mustacchi     to dbg at de_debug_sects, depending on size of nbytes
2006*f3e7f55eSRobert Mustacchi 
2007*f3e7f55eSRobert Mustacchi     Assume dbg not null, checked in top level routine
2008*f3e7f55eSRobert Mustacchi 
2009*f3e7f55eSRobert Mustacchi     Returns a pointer to the allocated buffer space for the
2010*f3e7f55eSRobert Mustacchi     lib to fill in,  predincrements next-to-use count so the
2011*f3e7f55eSRobert Mustacchi     space requested is already counted 'used'
2012*f3e7f55eSRobert Mustacchi     when this returns (ie, reserved).
2013*f3e7f55eSRobert Mustacchi 
2014*f3e7f55eSRobert Mustacchi */
2015*f3e7f55eSRobert Mustacchi Dwarf_Small *
_dwarf_pro_buffer(Dwarf_P_Debug dbg,int elfsectno,unsigned long nbytes)2016*f3e7f55eSRobert Mustacchi _dwarf_pro_buffer(Dwarf_P_Debug dbg,
2017*f3e7f55eSRobert Mustacchi                   int elfsectno, unsigned long nbytes)
2018*f3e7f55eSRobert Mustacchi {
2019*f3e7f55eSRobert Mustacchi     Dwarf_P_Section_Data cursect;
2020*f3e7f55eSRobert Mustacchi 
2021*f3e7f55eSRobert Mustacchi 
2022*f3e7f55eSRobert Mustacchi     cursect = dbg->de_current_active_section;
2023*f3e7f55eSRobert Mustacchi     /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must
2024*f3e7f55eSRobert Mustacchi        not match any legit section number. test to have just two
2025*f3e7f55eSRobert Mustacchi        clauses (no NULL pointer test) See dwarf_producer_init(). */
2026*f3e7f55eSRobert Mustacchi     if ((cursect->ds_elf_sect_no != elfsectno) ||
2027*f3e7f55eSRobert Mustacchi         ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc)
2028*f3e7f55eSRobert Mustacchi         ) {
2029*f3e7f55eSRobert Mustacchi 
2030*f3e7f55eSRobert Mustacchi         /* Either the elf section has changed or there is not enough
2031*f3e7f55eSRobert Mustacchi            space in the current section.
2032*f3e7f55eSRobert Mustacchi 
2033*f3e7f55eSRobert Mustacchi            Create a new Dwarf_P_Section_Data_s for the chunk. and have
2034*f3e7f55eSRobert Mustacchi            space 'on the end' for the buffer itself so we just do one
2035*f3e7f55eSRobert Mustacchi            malloc (not two).
2036*f3e7f55eSRobert Mustacchi 
2037*f3e7f55eSRobert Mustacchi          */
2038*f3e7f55eSRobert Mustacchi         unsigned long space = nbytes;
2039*f3e7f55eSRobert Mustacchi 
2040*f3e7f55eSRobert Mustacchi         if (nbytes < CHUNK_SIZE)
2041*f3e7f55eSRobert Mustacchi             space = CHUNK_SIZE;
2042*f3e7f55eSRobert Mustacchi 
2043*f3e7f55eSRobert Mustacchi         cursect = (Dwarf_P_Section_Data)
2044*f3e7f55eSRobert Mustacchi             _dwarf_p_get_alloc(dbg,
2045*f3e7f55eSRobert Mustacchi                                sizeof(struct Dwarf_P_Section_Data_s)
2046*f3e7f55eSRobert Mustacchi                                + space);
2047*f3e7f55eSRobert Mustacchi 
2048*f3e7f55eSRobert Mustacchi 
2049*f3e7f55eSRobert Mustacchi         if (cursect == NULL)
2050*f3e7f55eSRobert Mustacchi             return (NULL);
2051*f3e7f55eSRobert Mustacchi 
2052*f3e7f55eSRobert Mustacchi         /* _dwarf_p_get_alloc zeroes the space... */
2053*f3e7f55eSRobert Mustacchi 
2054*f3e7f55eSRobert Mustacchi         cursect->ds_data = (char *) cursect +
2055*f3e7f55eSRobert Mustacchi             sizeof(struct Dwarf_P_Section_Data_s);
2056*f3e7f55eSRobert Mustacchi         cursect->ds_orig_alloc = space;
2057*f3e7f55eSRobert Mustacchi         cursect->ds_elf_sect_no = elfsectno;
2058*f3e7f55eSRobert Mustacchi         cursect->ds_nbytes = nbytes;    /* reserve this number of bytes
2059*f3e7f55eSRobert Mustacchi                                            of space for caller to fill
2060*f3e7f55eSRobert Mustacchi                                            in */
2061*f3e7f55eSRobert Mustacchi 
2062*f3e7f55eSRobert Mustacchi         /* Now link on the end of the list, and mark this one as the
2063*f3e7f55eSRobert Mustacchi            current one */
2064*f3e7f55eSRobert Mustacchi 
2065*f3e7f55eSRobert Mustacchi         if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
2066*f3e7f55eSRobert Mustacchi             /* the only entry is the special one for 'no entry' so
2067*f3e7f55eSRobert Mustacchi                delete that phony one while adding this initial real
2068*f3e7f55eSRobert Mustacchi                one. */
2069*f3e7f55eSRobert Mustacchi             dbg->de_debug_sects = cursect;
2070*f3e7f55eSRobert Mustacchi             dbg->de_current_active_section = cursect;
2071*f3e7f55eSRobert Mustacchi             dbg->de_first_debug_sect = cursect;
2072*f3e7f55eSRobert Mustacchi         } else {
2073*f3e7f55eSRobert Mustacchi             dbg->de_current_active_section->ds_next = cursect;
2074*f3e7f55eSRobert Mustacchi             dbg->de_current_active_section = cursect;
2075*f3e7f55eSRobert Mustacchi         }
2076*f3e7f55eSRobert Mustacchi         dbg->de_n_debug_sect++;
2077*f3e7f55eSRobert Mustacchi 
2078*f3e7f55eSRobert Mustacchi         return ((Dwarf_Small *) cursect->ds_data);
2079*f3e7f55eSRobert Mustacchi     }
2080*f3e7f55eSRobert Mustacchi 
2081*f3e7f55eSRobert Mustacchi     /* There is enough space in the current buffer */
2082*f3e7f55eSRobert Mustacchi     {
2083*f3e7f55eSRobert Mustacchi         Dwarf_Small *space_for_caller = (Dwarf_Small *)
2084*f3e7f55eSRobert Mustacchi             (cursect->ds_data + cursect->ds_nbytes);
2085*f3e7f55eSRobert Mustacchi 
2086*f3e7f55eSRobert Mustacchi         cursect->ds_nbytes += nbytes;
2087*f3e7f55eSRobert Mustacchi         return space_for_caller;
2088*f3e7f55eSRobert Mustacchi     }
2089*f3e7f55eSRobert Mustacchi }
2090*f3e7f55eSRobert Mustacchi 
2091*f3e7f55eSRobert Mustacchi 
2092*f3e7f55eSRobert Mustacchi /*------------------------------------------------------------
2093*f3e7f55eSRobert Mustacchi         Given address advance and line advance, it gives
2094*f3e7f55eSRobert Mustacchi         either special opcode, or a number < 0
2095*f3e7f55eSRobert Mustacchi ------------------------------------------------------------*/
2096*f3e7f55eSRobert Mustacchi static int
_dwarf_pro_get_opc(Dwarf_Unsigned addr_adv,int line_adv)2097*f3e7f55eSRobert Mustacchi _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv)
2098*f3e7f55eSRobert Mustacchi {
2099*f3e7f55eSRobert Mustacchi     int opc;
2100*f3e7f55eSRobert Mustacchi 
2101*f3e7f55eSRobert Mustacchi     addr_adv = addr_adv / MIN_INST_LENGTH;
2102*f3e7f55eSRobert Mustacchi     if (line_adv == 0 && addr_adv == 0)
2103*f3e7f55eSRobert Mustacchi         return OPC_INCS_ZERO;
2104*f3e7f55eSRobert Mustacchi     if (line_adv >= LINE_BASE && line_adv < LINE_BASE + LINE_RANGE) {
2105*f3e7f55eSRobert Mustacchi         opc =
2106*f3e7f55eSRobert Mustacchi             (line_adv - LINE_BASE) + (addr_adv * LINE_RANGE) +
2107*f3e7f55eSRobert Mustacchi             OPCODE_BASE;
2108*f3e7f55eSRobert Mustacchi         if (opc > 255)
2109*f3e7f55eSRobert Mustacchi             return OPC_OUT_OF_RANGE;
2110*f3e7f55eSRobert Mustacchi         return opc;
2111*f3e7f55eSRobert Mustacchi     } else
2112*f3e7f55eSRobert Mustacchi         return LINE_OUT_OF_RANGE;
2113*f3e7f55eSRobert Mustacchi }
2114*f3e7f55eSRobert Mustacchi 
2115*f3e7f55eSRobert Mustacchi /*-----------------------------------------------------------------------
2116*f3e7f55eSRobert Mustacchi         Handles abbreviations. It takes a die, searches through
2117*f3e7f55eSRobert Mustacchi         current list of abbreviations for matching one. If it
2118*f3e7f55eSRobert Mustacchi         finds one, it returns a pointer to it, and if it doesnt,
2119*f3e7f55eSRobert Mustacchi         it returns a new one. Upto the user of this function to
2120*f3e7f55eSRobert Mustacchi         link it up to the abbreviation head. If its a new one,
2121*f3e7f55eSRobert Mustacchi         abb_idx has 0.
2122*f3e7f55eSRobert Mustacchi -----------------------------------------------------------------------*/
2123*f3e7f55eSRobert Mustacchi static Dwarf_P_Abbrev
_dwarf_pro_getabbrev(Dwarf_P_Die die,Dwarf_P_Abbrev head)2124*f3e7f55eSRobert Mustacchi _dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head)
2125*f3e7f55eSRobert Mustacchi {
2126*f3e7f55eSRobert Mustacchi     Dwarf_P_Abbrev curabbrev;
2127*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute curattr;
2128*f3e7f55eSRobert Mustacchi     int res1;
2129*f3e7f55eSRobert Mustacchi     int nattrs;
2130*f3e7f55eSRobert Mustacchi     int match;
2131*f3e7f55eSRobert Mustacchi     Dwarf_ufixed *forms = 0;
2132*f3e7f55eSRobert Mustacchi     Dwarf_ufixed *attrs = 0;
2133*f3e7f55eSRobert Mustacchi 
2134*f3e7f55eSRobert Mustacchi     curabbrev = head;
2135*f3e7f55eSRobert Mustacchi     while (curabbrev) {
2136*f3e7f55eSRobert Mustacchi         if ((die->di_tag == curabbrev->abb_tag) &&
2137*f3e7f55eSRobert Mustacchi             ((die->di_child != NULL &&
2138*f3e7f55eSRobert Mustacchi               curabbrev->abb_children == DW_CHILDREN_yes) ||
2139*f3e7f55eSRobert Mustacchi              (die->di_child == NULL &&
2140*f3e7f55eSRobert Mustacchi               curabbrev->abb_children == DW_CHILDREN_no)) &&
2141*f3e7f55eSRobert Mustacchi             (die->di_n_attr == curabbrev->abb_n_attr)) {
2142*f3e7f55eSRobert Mustacchi 
2143*f3e7f55eSRobert Mustacchi             /* There is a chance of a match. */
2144*f3e7f55eSRobert Mustacchi             curattr = die->di_attrs;
2145*f3e7f55eSRobert Mustacchi             match = 1;          /* Assume match found. */
2146*f3e7f55eSRobert Mustacchi             while (match && curattr) {
2147*f3e7f55eSRobert Mustacchi                 res1 = _dwarf_pro_match_attr(curattr,
2148*f3e7f55eSRobert Mustacchi                                              curabbrev,
2149*f3e7f55eSRobert Mustacchi                                              (int) curabbrev->
2150*f3e7f55eSRobert Mustacchi                                              abb_n_attr);
2151*f3e7f55eSRobert Mustacchi                 if (res1 == 0)
2152*f3e7f55eSRobert Mustacchi                     match = 0;
2153*f3e7f55eSRobert Mustacchi                 curattr = curattr->ar_next;
2154*f3e7f55eSRobert Mustacchi             }
2155*f3e7f55eSRobert Mustacchi             if (match == 1)
2156*f3e7f55eSRobert Mustacchi                 return curabbrev;
2157*f3e7f55eSRobert Mustacchi         }
2158*f3e7f55eSRobert Mustacchi         curabbrev = curabbrev->abb_next;
2159*f3e7f55eSRobert Mustacchi     }
2160*f3e7f55eSRobert Mustacchi 
2161*f3e7f55eSRobert Mustacchi     /* no match, create new abbreviation */
2162*f3e7f55eSRobert Mustacchi     if (die->di_n_attr != 0) {
2163*f3e7f55eSRobert Mustacchi         forms = (Dwarf_ufixed *)
2164*f3e7f55eSRobert Mustacchi             _dwarf_p_get_alloc(die->di_dbg,
2165*f3e7f55eSRobert Mustacchi                                sizeof(Dwarf_ufixed) * die->di_n_attr);
2166*f3e7f55eSRobert Mustacchi         if (forms == NULL)
2167*f3e7f55eSRobert Mustacchi             return NULL;
2168*f3e7f55eSRobert Mustacchi         attrs = (Dwarf_ufixed *)
2169*f3e7f55eSRobert Mustacchi             _dwarf_p_get_alloc(die->di_dbg,
2170*f3e7f55eSRobert Mustacchi                                sizeof(Dwarf_ufixed) * die->di_n_attr);
2171*f3e7f55eSRobert Mustacchi         if (attrs == NULL)
2172*f3e7f55eSRobert Mustacchi             return NULL;
2173*f3e7f55eSRobert Mustacchi     }
2174*f3e7f55eSRobert Mustacchi     nattrs = 0;
2175*f3e7f55eSRobert Mustacchi     curattr = die->di_attrs;
2176*f3e7f55eSRobert Mustacchi     while (curattr) {
2177*f3e7f55eSRobert Mustacchi         attrs[nattrs] = curattr->ar_attribute;
2178*f3e7f55eSRobert Mustacchi         forms[nattrs] = curattr->ar_attribute_form;
2179*f3e7f55eSRobert Mustacchi         nattrs++;
2180*f3e7f55eSRobert Mustacchi         curattr = curattr->ar_next;
2181*f3e7f55eSRobert Mustacchi     }
2182*f3e7f55eSRobert Mustacchi 
2183*f3e7f55eSRobert Mustacchi     curabbrev = (Dwarf_P_Abbrev)
2184*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s));
2185*f3e7f55eSRobert Mustacchi     if (curabbrev == NULL)
2186*f3e7f55eSRobert Mustacchi         return NULL;
2187*f3e7f55eSRobert Mustacchi 
2188*f3e7f55eSRobert Mustacchi     if (die->di_child == NULL)
2189*f3e7f55eSRobert Mustacchi         curabbrev->abb_children = DW_CHILDREN_no;
2190*f3e7f55eSRobert Mustacchi     else
2191*f3e7f55eSRobert Mustacchi         curabbrev->abb_children = DW_CHILDREN_yes;
2192*f3e7f55eSRobert Mustacchi     curabbrev->abb_tag = die->di_tag;
2193*f3e7f55eSRobert Mustacchi     curabbrev->abb_attrs = attrs;
2194*f3e7f55eSRobert Mustacchi     curabbrev->abb_forms = forms;
2195*f3e7f55eSRobert Mustacchi     curabbrev->abb_n_attr = die->di_n_attr;
2196*f3e7f55eSRobert Mustacchi     curabbrev->abb_idx = 0;
2197*f3e7f55eSRobert Mustacchi     curabbrev->abb_next = NULL;
2198*f3e7f55eSRobert Mustacchi 
2199*f3e7f55eSRobert Mustacchi     return curabbrev;
2200*f3e7f55eSRobert Mustacchi }
2201*f3e7f55eSRobert Mustacchi 
2202*f3e7f55eSRobert Mustacchi /*------------------------------------------------------------------
2203*f3e7f55eSRobert Mustacchi         Tries to see if given attribute and form combination
2204*f3e7f55eSRobert Mustacchi         exists in the given abbreviation
2205*f3e7f55eSRobert Mustacchi -------------------------------------------------------------------*/
2206*f3e7f55eSRobert Mustacchi static int
_dwarf_pro_match_attr(Dwarf_P_Attribute attr,Dwarf_P_Abbrev abbrev,int no_attr)2207*f3e7f55eSRobert Mustacchi _dwarf_pro_match_attr(Dwarf_P_Attribute attr,
2208*f3e7f55eSRobert Mustacchi                       Dwarf_P_Abbrev abbrev, int no_attr)
2209*f3e7f55eSRobert Mustacchi {
2210*f3e7f55eSRobert Mustacchi     int i;
2211*f3e7f55eSRobert Mustacchi     int found = 0;
2212*f3e7f55eSRobert Mustacchi 
2213*f3e7f55eSRobert Mustacchi     for (i = 0; i < no_attr; i++) {
2214*f3e7f55eSRobert Mustacchi         if (attr->ar_attribute == abbrev->abb_attrs[i] &&
2215*f3e7f55eSRobert Mustacchi             attr->ar_attribute_form == abbrev->abb_forms[i]) {
2216*f3e7f55eSRobert Mustacchi             found = 1;
2217*f3e7f55eSRobert Mustacchi             break;
2218*f3e7f55eSRobert Mustacchi         }
2219*f3e7f55eSRobert Mustacchi     }
2220*f3e7f55eSRobert Mustacchi     return found;
2221*f3e7f55eSRobert Mustacchi }
2222