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