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
dwarf_need_debug_line_section(Dwarf_P_Debug dbg)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
dwarf_transform_to_disk_form(Dwarf_P_Debug dbg,Dwarf_Error * error)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
_dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,Dwarf_Error * error)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
_dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,Dwarf_Error * error)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
marker_init(Dwarf_P_Debug dbg,unsigned count)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
marker_add(Dwarf_P_Debug dbg,Dwarf_Unsigned offset,Dwarf_Unsigned marker)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
dwarf_get_die_markers(Dwarf_P_Debug dbg,Dwarf_P_Marker * marker_list,Dwarf_Unsigned * marker_count,Dwarf_Error * error)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
string_attr_init(Dwarf_P_Debug dbg,Dwarf_Signed section_index,unsigned count)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
string_attr_add(Dwarf_P_Debug dbg,Dwarf_Signed section_index,Dwarf_Unsigned offset,Dwarf_P_Attribute attr)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
dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,Dwarf_Unsigned * count_of_sa_sections,int * drd_buffer_version,Dwarf_Error * error)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
dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,Dwarf_Signed * elf_section_index,Dwarf_Unsigned * sect_sa_buffer_count,Dwarf_P_String_Attr * sect_sa_buffer,Dwarf_Error * error)1431*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
_dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,Dwarf_Error * error)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
dwarf_get_section_bytes(Dwarf_P_Debug dbg,Dwarf_Signed dwarf_section,Dwarf_Signed * section_idx,Dwarf_Unsigned * length,Dwarf_Error * error)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
dwarf_reset_section_bytes(Dwarf_P_Debug dbg)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 *
_dwarf_pro_buffer(Dwarf_P_Debug dbg,int elfsectno,unsigned long nbytes)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
_dwarf_pro_get_opc(Dwarf_Unsigned addr_adv,int line_adv)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
_dwarf_pro_getabbrev(Dwarf_P_Die die,Dwarf_P_Abbrev head)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
_dwarf_pro_match_attr(Dwarf_P_Attribute attr,Dwarf_P_Abbrev abbrev,int no_attr)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