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