1bc1f688bSRobert Mustacchi /*
2bc1f688bSRobert Mustacchi Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved.
3*4d9fdb46SRobert Mustacchi Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved.
4bc1f688bSRobert Mustacchi Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
5*4d9fdb46SRobert Mustacchi Portions Copyright 2012 SN Systems Ltd. All rights reserved.
6bc1f688bSRobert Mustacchi
7*4d9fdb46SRobert Mustacchi This program is free software; you can redistribute it
8*4d9fdb46SRobert Mustacchi and/or modify it under the terms of version 2.1 of the
9*4d9fdb46SRobert Mustacchi GNU Lesser General Public License as published by the Free
10*4d9fdb46SRobert Mustacchi Software Foundation.
11bc1f688bSRobert Mustacchi
12*4d9fdb46SRobert Mustacchi This program is distributed in the hope that it would be
13*4d9fdb46SRobert Mustacchi useful, but WITHOUT ANY WARRANTY; without even the implied
14*4d9fdb46SRobert Mustacchi warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15*4d9fdb46SRobert Mustacchi PURPOSE.
16bc1f688bSRobert Mustacchi
17*4d9fdb46SRobert Mustacchi Further, this software is distributed without any warranty
18*4d9fdb46SRobert Mustacchi that it is free of the rightful claim of any third person
19*4d9fdb46SRobert Mustacchi regarding infringement or the like. Any license provided
20*4d9fdb46SRobert Mustacchi herein, whether implied or otherwise, applies only to this
21*4d9fdb46SRobert Mustacchi software file. Patent licenses, if any, provided herein
22*4d9fdb46SRobert Mustacchi do not apply to combinations of this program with other
23*4d9fdb46SRobert Mustacchi software, or any other product whatsoever.
24bc1f688bSRobert Mustacchi
25*4d9fdb46SRobert Mustacchi You should have received a copy of the GNU Lesser General
26*4d9fdb46SRobert Mustacchi Public License along with this program; if not, write the
27*4d9fdb46SRobert Mustacchi Free Software Foundation, Inc., 51 Franklin Street - Fifth
28*4d9fdb46SRobert Mustacchi Floor, Boston MA 02110-1301, USA.
29bc1f688bSRobert Mustacchi
30bc1f688bSRobert Mustacchi */
31bc1f688bSRobert Mustacchi
32bc1f688bSRobert Mustacchi #include "config.h"
33bc1f688bSRobert Mustacchi #include "libdwarfdefs.h"
34bc1f688bSRobert Mustacchi #include <stdio.h>
35*4d9fdb46SRobert Mustacchi #ifdef HAVE_STRING_H
36bc1f688bSRobert Mustacchi #include <string.h>
37*4d9fdb46SRobert Mustacchi #endif /* HAVE_STRING_H */
38bc1f688bSRobert Mustacchi #ifdef HAVE_ELFACCESS_H
39bc1f688bSRobert Mustacchi #include <elfaccess.h>
40bc1f688bSRobert Mustacchi #endif
41*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
42*4d9fdb46SRobert Mustacchi #include <stdlib.h>
43*4d9fdb46SRobert Mustacchi #endif
44*4d9fdb46SRobert Mustacchi #ifdef HAVE_MALLOC_H
45*4d9fdb46SRobert Mustacchi /* Useful include for some Windows compilers. */
46*4d9fdb46SRobert Mustacchi #include <malloc.h>
47*4d9fdb46SRobert Mustacchi #endif /* HAVE_MALLOC_H */
48*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDDEF_H
49*4d9fdb46SRobert Mustacchi #include <stddef.h>
50*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDDEF_H */
51bc1f688bSRobert Mustacchi #include "pro_incl.h"
52*4d9fdb46SRobert Mustacchi #include "dwarf.h"
53*4d9fdb46SRobert Mustacchi #include "libdwarf.h"
54*4d9fdb46SRobert Mustacchi #include "pro_opaque.h"
55*4d9fdb46SRobert Mustacchi #include "pro_error.h"
56*4d9fdb46SRobert Mustacchi #include "pro_util.h"
57*4d9fdb46SRobert Mustacchi #include "pro_encode_nm.h"
58*4d9fdb46SRobert Mustacchi #include "pro_alloc.h"
59bc1f688bSRobert Mustacchi #include "pro_section.h"
60bc1f688bSRobert Mustacchi #include "pro_line.h"
61bc1f688bSRobert Mustacchi #include "pro_frame.h"
62bc1f688bSRobert Mustacchi #include "pro_die.h"
63bc1f688bSRobert Mustacchi #include "pro_macinfo.h"
64bc1f688bSRobert Mustacchi #include "pro_types.h"
65*4d9fdb46SRobert Mustacchi #include "pro_dnames.h"
66*4d9fdb46SRobert Mustacchi
67*4d9fdb46SRobert Mustacchi
68*4d9fdb46SRobert Mustacchi #ifndef SHN_UNDEF
69*4d9fdb46SRobert Mustacchi #define SHN_UNDEF 0
70*4d9fdb46SRobert Mustacchi #endif /* SHN_UNDEF */
71bc1f688bSRobert Mustacchi
72bc1f688bSRobert Mustacchi #ifndef SHF_MIPS_NOSTRIP
73bc1f688bSRobert Mustacchi /* if this is not defined, we probably don't need it: just use 0 */
74bc1f688bSRobert Mustacchi #define SHF_MIPS_NOSTRIP 0
75bc1f688bSRobert Mustacchi #endif
76bc1f688bSRobert Mustacchi #ifndef R_MIPS_NONE
77bc1f688bSRobert Mustacchi #define R_MIPS_NONE 0
78bc1f688bSRobert Mustacchi #endif
79bc1f688bSRobert Mustacchi
80bc1f688bSRobert Mustacchi #ifndef TRUE
81bc1f688bSRobert Mustacchi #define TRUE 1
82bc1f688bSRobert Mustacchi #endif
83bc1f688bSRobert Mustacchi #ifndef FALSE
84bc1f688bSRobert Mustacchi #define FALSE 0
85bc1f688bSRobert Mustacchi #endif
86bc1f688bSRobert Mustacchi
87*4d9fdb46SRobert Mustacchi #ifdef WORDS_BIGENDIAN
88*4d9fdb46SRobert Mustacchi #define ASNOUT(t,s,l) \
89*4d9fdb46SRobert Mustacchi do { \
90*4d9fdb46SRobert Mustacchi unsigned sbyte = 0; \
91*4d9fdb46SRobert Mustacchi const char *p = 0; \
92*4d9fdb46SRobert Mustacchi if (l > sizeof(s)) { \
93*4d9fdb46SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\
94*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; \
95*4d9fdb46SRobert Mustacchi } \
96*4d9fdb46SRobert Mustacchi sbyte = sizeof(s) - l; \
97*4d9fdb46SRobert Mustacchi p = (const char *)(&s); \
98*4d9fdb46SRobert Mustacchi dbg->de_copy_word(t,(const void *)(p+sbyte),l);\
99*4d9fdb46SRobert Mustacchi } while (0)
100*4d9fdb46SRobert Mustacchi #else /* LITTLEENDIAN */
101*4d9fdb46SRobert Mustacchi #define ASNOUT(t,s,l) \
102*4d9fdb46SRobert Mustacchi do { \
103*4d9fdb46SRobert Mustacchi const char *p = 0; \
104*4d9fdb46SRobert Mustacchi if (l > sizeof(s)) { \
105*4d9fdb46SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\
106*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; \
107*4d9fdb46SRobert Mustacchi } \
108*4d9fdb46SRobert Mustacchi p = (const char *)(&s); \
109*4d9fdb46SRobert Mustacchi dbg->de_copy_word(t,(const void *)p,l); \
110*4d9fdb46SRobert Mustacchi } while (0)
111*4d9fdb46SRobert Mustacchi #endif /* ENDIANNESS */
112*4d9fdb46SRobert Mustacchi
113*4d9fdb46SRobert Mustacchi
114*4d9fdb46SRobert Mustacchi #define SIZEOFT32 4
115*4d9fdb46SRobert Mustacchi
116*4d9fdb46SRobert Mustacchi struct Dwarf_Sort_Abbrev_s {
117*4d9fdb46SRobert Mustacchi Dwarf_Unsigned dsa_attr;
118*4d9fdb46SRobert Mustacchi Dwarf_Unsigned dsa_form;
119*4d9fdb46SRobert Mustacchi Dwarf_Signed dsa_implicitvalue;
120*4d9fdb46SRobert Mustacchi Dwarf_P_Attribute dsa_attrp;
121*4d9fdb46SRobert Mustacchi };
122*4d9fdb46SRobert Mustacchi
123*4d9fdb46SRobert Mustacchi
124*4d9fdb46SRobert Mustacchi /* Must match up with pro_section.h defines of DEBUG_INFO etc
125bc1f688bSRobert Mustacchi and sectnames (below). REL_SEC_PREFIX is either ".rel" or ".rela"
126bc1f688bSRobert Mustacchi see pro_incl.h
127bc1f688bSRobert Mustacchi */
128*4d9fdb46SRobert Mustacchi const char *_dwarf_rel_section_names[] = {
129bc1f688bSRobert Mustacchi REL_SEC_PREFIX ".debug_info",
130bc1f688bSRobert Mustacchi REL_SEC_PREFIX ".debug_line",
131*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_abbrev", /* Nothing here refers to anything. */
132bc1f688bSRobert Mustacchi REL_SEC_PREFIX ".debug_frame",
133bc1f688bSRobert Mustacchi REL_SEC_PREFIX ".debug_aranges",
134bc1f688bSRobert Mustacchi REL_SEC_PREFIX ".debug_pubnames",
135bc1f688bSRobert Mustacchi REL_SEC_PREFIX ".debug_funcnames", /* sgi extension */
136bc1f688bSRobert Mustacchi REL_SEC_PREFIX ".debug_typenames", /* sgi extension */
137bc1f688bSRobert Mustacchi REL_SEC_PREFIX ".debug_varnames", /* sgi extension */
138bc1f688bSRobert Mustacchi REL_SEC_PREFIX ".debug_weaknames", /* sgi extension */
139bc1f688bSRobert Mustacchi REL_SEC_PREFIX ".debug_macinfo",
140*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_loc",
141*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_ranges",
142*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_types", /* new in DWARF4 */
143*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_pubtypes", /* new in DWARF3 */
144*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_names", /* DWARF5 aka dnames */
145*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_str", /* Nothing here refers to anything.*/
146*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_rnglists", /* DWARF5. */
147*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_line_str", /* DWARF5. Nothing referselsewhere */
148*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_macro", /* DWARF5. */
149*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_loclists", /* DWARF5. */
150*4d9fdb46SRobert Mustacchi REL_SEC_PREFIX ".debug_rnglists", /* DWARF5. */
151bc1f688bSRobert Mustacchi };
152bc1f688bSRobert Mustacchi
153bc1f688bSRobert Mustacchi /* names of sections. Ensure that it matches the defines
154bc1f688bSRobert Mustacchi in pro_section.h, in the same order
155bc1f688bSRobert Mustacchi Must match also _dwarf_rel_section_names above
156bc1f688bSRobert Mustacchi */
157*4d9fdb46SRobert Mustacchi const char *_dwarf_sectnames[] = {
158bc1f688bSRobert Mustacchi ".debug_info",
159bc1f688bSRobert Mustacchi ".debug_line",
160bc1f688bSRobert Mustacchi ".debug_abbrev",
161bc1f688bSRobert Mustacchi ".debug_frame",
162bc1f688bSRobert Mustacchi ".debug_aranges",
163bc1f688bSRobert Mustacchi ".debug_pubnames",
164bc1f688bSRobert Mustacchi ".debug_funcnames", /* sgi extension */
165bc1f688bSRobert Mustacchi ".debug_typenames", /* sgi extension */
166bc1f688bSRobert Mustacchi ".debug_varnames", /* sgi extension */
167bc1f688bSRobert Mustacchi ".debug_weaknames", /* sgi extension */
168bc1f688bSRobert Mustacchi ".debug_macinfo",
169*4d9fdb46SRobert Mustacchi ".debug_loc",
170*4d9fdb46SRobert Mustacchi ".debug_ranges",
171*4d9fdb46SRobert Mustacchi ".debug_types", /* new in DWARF4 */
172*4d9fdb46SRobert Mustacchi ".debug_pubtypes", /* new in DWARF3 */
173*4d9fdb46SRobert Mustacchi ".debug_names", /* new in DWARF5. aka dnames */
174*4d9fdb46SRobert Mustacchi ".debug_str",
175*4d9fdb46SRobert Mustacchi ".debug_line_str", /* new in DWARF5 */
176*4d9fdb46SRobert Mustacchi ".debug_macro", /* new in DWARF5 */
177*4d9fdb46SRobert Mustacchi ".debug_loclists", /* new in DWARF5 */
178*4d9fdb46SRobert Mustacchi ".debug_rnglists", /* new in DWARF5 */
179bc1f688bSRobert Mustacchi };
180bc1f688bSRobert Mustacchi
181bc1f688bSRobert Mustacchi
182bc1f688bSRobert Mustacchi
183bc1f688bSRobert Mustacchi
184*4d9fdb46SRobert Mustacchi static const Dwarf_Ubyte std_opcode_len[] = { 0, /* DW_LNS_copy */
185bc1f688bSRobert Mustacchi 1, /* DW_LNS_advance_pc */
186bc1f688bSRobert Mustacchi 1, /* DW_LNS_advance_line */
187bc1f688bSRobert Mustacchi 1, /* DW_LNS_set_file */
188bc1f688bSRobert Mustacchi 1, /* DW_LNS_set_column */
189bc1f688bSRobert Mustacchi 0, /* DW_LNS_negate_stmt */
190bc1f688bSRobert Mustacchi 0, /* DW_LNS_set_basic_block */
191bc1f688bSRobert Mustacchi 0, /* DW_LNS_const_add_pc */
192bc1f688bSRobert Mustacchi 1, /* DW_LNS_fixed_advance_pc */
193*4d9fdb46SRobert Mustacchi /* The following for DWARF3 and DWARF4, though GNU
194*4d9fdb46SRobert Mustacchi uses these in DWARF2 as well. */
195*4d9fdb46SRobert Mustacchi 0, /* DW_LNS_set_prologue_end */
196*4d9fdb46SRobert Mustacchi 0, /* DW_LNS_set_epilogue_begin */
197*4d9fdb46SRobert Mustacchi 1, /* DW_LNS_set_isa */
198bc1f688bSRobert Mustacchi };
199bc1f688bSRobert Mustacchi
200bc1f688bSRobert Mustacchi /* struct to hold relocation entries. Its mantained as a linked
201bc1f688bSRobert Mustacchi list of relocation structs, and will then be written at as a
202bc1f688bSRobert Mustacchi whole into the relocation section. Whether its 32 bit or
203bc1f688bSRobert Mustacchi 64 bit will be obtained from Dwarf_Debug pointer.
204bc1f688bSRobert Mustacchi */
205bc1f688bSRobert Mustacchi
206bc1f688bSRobert Mustacchi typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel;
207bc1f688bSRobert Mustacchi struct Dwarf_P_Rel_s {
208bc1f688bSRobert Mustacchi Dwarf_P_Rel dr_next;
209bc1f688bSRobert Mustacchi void *dr_rel_datap;
210bc1f688bSRobert Mustacchi };
211bc1f688bSRobert Mustacchi typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head;
212bc1f688bSRobert Mustacchi struct Dwarf_P_Rel_Head_s {
213bc1f688bSRobert Mustacchi struct Dwarf_P_Rel_s *drh_head;
214bc1f688bSRobert Mustacchi struct Dwarf_P_Rel_s *drh_tail;
215bc1f688bSRobert Mustacchi };
216bc1f688bSRobert Mustacchi
217*4d9fdb46SRobert Mustacchi static int
218*4d9fdb46SRobert Mustacchi _dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg,
219*4d9fdb46SRobert Mustacchi Dwarf_Signed *nbufs, Dwarf_Error * error);
220*4d9fdb46SRobert Mustacchi static int _dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg,
221*4d9fdb46SRobert Mustacchi Dwarf_Signed *nbufs, Dwarf_Error * error);
222*4d9fdb46SRobert Mustacchi static int _dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg,
223*4d9fdb46SRobert Mustacchi Dwarf_Signed *nbufs, Dwarf_Error * error);
224bc1f688bSRobert Mustacchi static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
225*4d9fdb46SRobert Mustacchi Dwarf_Signed *nbufs, Dwarf_Error * error);
226bc1f688bSRobert Mustacchi static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
227*4d9fdb46SRobert Mustacchi Dwarf_Signed *nbufs, Dwarf_Error * error);
228bc1f688bSRobert Mustacchi static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
229*4d9fdb46SRobert Mustacchi Dwarf_Signed *nbufs, Dwarf_Error * error);
230bc1f688bSRobert Mustacchi
231*4d9fdb46SRobert Mustacchi #if 0
232*4d9fdb46SRobert Mustacchi static void
233*4d9fdb46SRobert Mustacchi dump_bytes(char * msg,Dwarf_Small * start, long len)
234*4d9fdb46SRobert Mustacchi {
235*4d9fdb46SRobert Mustacchi Dwarf_Small *end = start + len;
236*4d9fdb46SRobert Mustacchi Dwarf_Small *cur = start;
237*4d9fdb46SRobert Mustacchi
238*4d9fdb46SRobert Mustacchi printf("%s len %ld ",msg,len);
239*4d9fdb46SRobert Mustacchi for (; cur < end; cur++) {
240*4d9fdb46SRobert Mustacchi printf("%02x ", *cur);
241*4d9fdb46SRobert Mustacchi }
242*4d9fdb46SRobert Mustacchi printf("\n");
243*4d9fdb46SRobert Mustacchi }
244*4d9fdb46SRobert Mustacchi #endif
245*4d9fdb46SRobert Mustacchi
246*4d9fdb46SRobert Mustacchi #if 0
247*4d9fdb46SRobert Mustacchi static void
248*4d9fdb46SRobert Mustacchi print_single_abbrev(Dwarf_P_Abbrev c, unsigned idx)
249*4d9fdb46SRobert Mustacchi {
250*4d9fdb46SRobert Mustacchi unsigned j = 0;
251*4d9fdb46SRobert Mustacchi
252*4d9fdb46SRobert Mustacchi printf(" %2u idx %2u tag 0x%x attrct %2u\n",idx,
253*4d9fdb46SRobert Mustacchi (unsigned)c->abb_idx,
254*4d9fdb46SRobert Mustacchi (unsigned)c->abb_tag,
255*4d9fdb46SRobert Mustacchi (unsigned)c->abb_n_attr);
256*4d9fdb46SRobert Mustacchi
257*4d9fdb46SRobert Mustacchi for ( ; j < (unsigned)c->abb_n_attr; ++j) {
258*4d9fdb46SRobert Mustacchi printf(" %2u attr 0x%2x form 0x%2x impl val %" DW_PR_DSd "\n",
259*4d9fdb46SRobert Mustacchi j,
260*4d9fdb46SRobert Mustacchi (unsigned)c->abb_attrs[j],
261*4d9fdb46SRobert Mustacchi (unsigned)c->abb_forms[j]);
262*4d9fdb46SRobert Mustacchi (unsigned)c->abb_implicits[j]);
263*4d9fdb46SRobert Mustacchi }
264*4d9fdb46SRobert Mustacchi }
265*4d9fdb46SRobert Mustacchi static void
266*4d9fdb46SRobert Mustacchi print_curabbrev(const char *where,
267*4d9fdb46SRobert Mustacchi Dwarf_P_Abbrev curabbrev)
268*4d9fdb46SRobert Mustacchi {
269*4d9fdb46SRobert Mustacchi Dwarf_P_Abbrev ca = 0;
270*4d9fdb46SRobert Mustacchi unsigned i = 0;
271*4d9fdb46SRobert Mustacchi for(ca = curabbrev; ca ; ca = ca->abb_next,++i) {
272*4d9fdb46SRobert Mustacchi printf("ABBREV %u from %s\n",i,where);
273*4d9fdb46SRobert Mustacchi print_single_abbrev(ca,i);
274*4d9fdb46SRobert Mustacchi }
275*4d9fdb46SRobert Mustacchi }
276*4d9fdb46SRobert Mustacchi #endif
277*4d9fdb46SRobert Mustacchi
278*4d9fdb46SRobert Mustacchi
279*4d9fdb46SRobert Mustacchi /* These macros used as return value for _dwarf_pro_get_opc. */
280bc1f688bSRobert Mustacchi #define OPC_INCS_ZERO -1
281bc1f688bSRobert Mustacchi #define OPC_OUT_OF_RANGE -2
282bc1f688bSRobert Mustacchi #define LINE_OUT_OF_RANGE -3
283*4d9fdb46SRobert Mustacchi /* Given address advance and line advance, it gives
284*4d9fdb46SRobert Mustacchi either special opcode, or a number < 0
285*4d9fdb46SRobert Mustacchi
286*4d9fdb46SRobert Mustacchi FIXME: Check all three negative values.
287*4d9fdb46SRobert Mustacchi Are any negatives really hard errors?
288*4d9fdb46SRobert Mustacchi */
289*4d9fdb46SRobert Mustacchi static int
_dwarf_pro_get_opc(struct Dwarf_P_Line_Inits_s * inits,Dwarf_Unsigned addr_adv,int line_adv)290*4d9fdb46SRobert Mustacchi _dwarf_pro_get_opc(
291*4d9fdb46SRobert Mustacchi struct Dwarf_P_Line_Inits_s *inits,
292*4d9fdb46SRobert Mustacchi Dwarf_Unsigned addr_adv,
293*4d9fdb46SRobert Mustacchi int line_adv)
294*4d9fdb46SRobert Mustacchi {
295*4d9fdb46SRobert Mustacchi int line_base = inits->pi_line_base;
296*4d9fdb46SRobert Mustacchi int line_range =inits->pi_line_range;
297*4d9fdb46SRobert Mustacchi Dwarf_Unsigned factored_adv = 0;
298*4d9fdb46SRobert Mustacchi
299*4d9fdb46SRobert Mustacchi factored_adv = addr_adv / inits->pi_minimum_instruction_length;
300*4d9fdb46SRobert Mustacchi if (line_adv == 0 && factored_adv == 0) {
301*4d9fdb46SRobert Mustacchi return OPC_INCS_ZERO;
302*4d9fdb46SRobert Mustacchi }
303*4d9fdb46SRobert Mustacchi if (line_adv >= line_base && line_adv < line_base + line_range) {
304*4d9fdb46SRobert Mustacchi int opc = 0;
305*4d9fdb46SRobert Mustacchi
306*4d9fdb46SRobert Mustacchi opc = (line_adv - line_base) +
307*4d9fdb46SRobert Mustacchi (factored_adv * line_range) +
308*4d9fdb46SRobert Mustacchi inits->pi_opcode_base;
309*4d9fdb46SRobert Mustacchi if (opc > 255) {
310*4d9fdb46SRobert Mustacchi return OPC_OUT_OF_RANGE;
311*4d9fdb46SRobert Mustacchi }
312*4d9fdb46SRobert Mustacchi return opc;
313*4d9fdb46SRobert Mustacchi }
314*4d9fdb46SRobert Mustacchi return LINE_OUT_OF_RANGE;
315*4d9fdb46SRobert Mustacchi }
316bc1f688bSRobert Mustacchi
317bc1f688bSRobert Mustacchi
318*4d9fdb46SRobert Mustacchi
319*4d9fdb46SRobert Mustacchi /* OFFSET_PLUS_EXTENSION_SIZE is the size of the 'length' field in total.
320bc1f688bSRobert Mustacchi Which may be 4,8, or 12 bytes!
321bc1f688bSRobert Mustacchi 4 is standard DWARF2.
322bc1f688bSRobert Mustacchi 8 is non-standard MIPS-IRIX 64-bit.
323bc1f688bSRobert Mustacchi 12 is standard DWARF3 for 64 bit offsets.
324bc1f688bSRobert Mustacchi Used in various routines: local variable names
325bc1f688bSRobert Mustacchi must match the names here.
326bc1f688bSRobert Mustacchi */
327*4d9fdb46SRobert Mustacchi #define OFFSET_PLUS_EXTENSION_SIZE (offset_size + extension_size)
328bc1f688bSRobert Mustacchi
329*4d9fdb46SRobert Mustacchi /* Return TRUE if we need the section, FALSE otherwise
330bc1f688bSRobert Mustacchi
331bc1f688bSRobert Mustacchi If any of the 'line-data-related' calls were made
332bc1f688bSRobert Mustacchi including file or directory entries,
333bc1f688bSRobert Mustacchi produce .debug_line .
334bc1f688bSRobert Mustacchi
335bc1f688bSRobert Mustacchi */
336bc1f688bSRobert Mustacchi static int
dwarf_need_debug_line_section(Dwarf_P_Debug dbg)337bc1f688bSRobert Mustacchi dwarf_need_debug_line_section(Dwarf_P_Debug dbg)
338bc1f688bSRobert Mustacchi {
339*4d9fdb46SRobert Mustacchi if (dbg->de_output_version > 4) {
340*4d9fdb46SRobert Mustacchi return FALSE;
341*4d9fdb46SRobert Mustacchi }
342bc1f688bSRobert Mustacchi if (dbg->de_lines == NULL && dbg->de_file_entries == NULL
343bc1f688bSRobert Mustacchi && dbg->de_inc_dirs == NULL) {
344bc1f688bSRobert Mustacchi return FALSE;
345bc1f688bSRobert Mustacchi }
346bc1f688bSRobert Mustacchi return TRUE;
347bc1f688bSRobert Mustacchi }
348bc1f688bSRobert Mustacchi
349*4d9fdb46SRobert Mustacchi /* DWARF5 only. */
350*4d9fdb46SRobert Mustacchi static int
dwarf_need_debug_names_section(Dwarf_P_Debug dbg)351*4d9fdb46SRobert Mustacchi dwarf_need_debug_names_section(Dwarf_P_Debug dbg)
352*4d9fdb46SRobert Mustacchi {
353*4d9fdb46SRobert Mustacchi if (dbg->de_output_version < 5) {
354*4d9fdb46SRobert Mustacchi return FALSE;
355*4d9fdb46SRobert Mustacchi }
356*4d9fdb46SRobert Mustacchi if (!dbg->de_dnames) {
357*4d9fdb46SRobert Mustacchi return FALSE;
358*4d9fdb46SRobert Mustacchi }
359*4d9fdb46SRobert Mustacchi if (!dbg->de_dnames->dn_create_section) {
360*4d9fdb46SRobert Mustacchi return FALSE;
361*4d9fdb46SRobert Mustacchi }
362*4d9fdb46SRobert Mustacchi return TRUE;
363*4d9fdb46SRobert Mustacchi }
364*4d9fdb46SRobert Mustacchi
365*4d9fdb46SRobert Mustacchi /* Convert debug information to a format such that
366bc1f688bSRobert Mustacchi it can be written on disk.
367bc1f688bSRobert Mustacchi Called exactly once per execution.
368*4d9fdb46SRobert Mustacchi This is the traditional interface. Bad interface design.
369bc1f688bSRobert Mustacchi */
370bc1f688bSRobert Mustacchi Dwarf_Signed
dwarf_transform_to_disk_form(Dwarf_P_Debug dbg,Dwarf_Error * error)371bc1f688bSRobert Mustacchi dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error)
372bc1f688bSRobert Mustacchi {
373*4d9fdb46SRobert Mustacchi Dwarf_Signed count = 0;
374*4d9fdb46SRobert Mustacchi int res = 0;
375*4d9fdb46SRobert Mustacchi
376*4d9fdb46SRobert Mustacchi res = dwarf_transform_to_disk_form_a(dbg, &count,error);
377*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
378*4d9fdb46SRobert Mustacchi return DW_DLV_NOCOUNT;
379*4d9fdb46SRobert Mustacchi }
380*4d9fdb46SRobert Mustacchi return count;
381*4d9fdb46SRobert Mustacchi }
382*4d9fdb46SRobert Mustacchi /* Convert debug information to a format such that
383*4d9fdb46SRobert Mustacchi it can be written on disk.
384*4d9fdb46SRobert Mustacchi Called exactly once per execution.
385*4d9fdb46SRobert Mustacchi This is the interface design used with the consumer
386*4d9fdb46SRobert Mustacchi interface, so easier for callers to work with.
387*4d9fdb46SRobert Mustacchi */
388*4d9fdb46SRobert Mustacchi int
dwarf_transform_to_disk_form_a(Dwarf_P_Debug dbg,Dwarf_Signed * count,Dwarf_Error * error)389*4d9fdb46SRobert Mustacchi dwarf_transform_to_disk_form_a(Dwarf_P_Debug dbg, Dwarf_Signed *count,
390*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
391*4d9fdb46SRobert Mustacchi {
392*4d9fdb46SRobert Mustacchi /* Section data in written out in a number of buffers. Each
393bc1f688bSRobert Mustacchi _generate_*() function returns a cumulative count of buffers for
394*4d9fdb46SRobert Mustacchi all the sections.
395*4d9fdb46SRobert Mustacchi dwarf_get_section_bytes() returns pointers to these
396bc1f688bSRobert Mustacchi buffers one at a time. */
397*4d9fdb46SRobert Mustacchi Dwarf_Signed nbufs = 0;
398bc1f688bSRobert Mustacchi int sect = 0;
399bc1f688bSRobert Mustacchi int err = 0;
400bc1f688bSRobert Mustacchi Dwarf_Unsigned du = 0;
401bc1f688bSRobert Mustacchi
402bc1f688bSRobert Mustacchi if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
403*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR);
404bc1f688bSRobert Mustacchi }
405bc1f688bSRobert Mustacchi
406bc1f688bSRobert Mustacchi /* Create dwarf section headers */
407bc1f688bSRobert Mustacchi for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) {
408bc1f688bSRobert Mustacchi long flags = 0;
409bc1f688bSRobert Mustacchi
410bc1f688bSRobert Mustacchi switch (sect) {
411bc1f688bSRobert Mustacchi
412bc1f688bSRobert Mustacchi case DEBUG_INFO:
413*4d9fdb46SRobert Mustacchi if (dbg->de_dies == NULL) {
414bc1f688bSRobert Mustacchi continue;
415*4d9fdb46SRobert Mustacchi }
416bc1f688bSRobert Mustacchi break;
417bc1f688bSRobert Mustacchi
418bc1f688bSRobert Mustacchi case DEBUG_LINE:
419bc1f688bSRobert Mustacchi if (dwarf_need_debug_line_section(dbg) == FALSE) {
420bc1f688bSRobert Mustacchi continue;
421bc1f688bSRobert Mustacchi }
422bc1f688bSRobert Mustacchi break;
423bc1f688bSRobert Mustacchi
424bc1f688bSRobert Mustacchi case DEBUG_ABBREV:
425*4d9fdb46SRobert Mustacchi if (dbg->de_dies == NULL) {
426bc1f688bSRobert Mustacchi continue;
427*4d9fdb46SRobert Mustacchi }
428bc1f688bSRobert Mustacchi break;
429bc1f688bSRobert Mustacchi
430bc1f688bSRobert Mustacchi case DEBUG_FRAME:
431*4d9fdb46SRobert Mustacchi if (dbg->de_frame_cies == NULL) {
432bc1f688bSRobert Mustacchi continue;
433*4d9fdb46SRobert Mustacchi }
434bc1f688bSRobert Mustacchi flags = SHF_MIPS_NOSTRIP;
435bc1f688bSRobert Mustacchi break;
436bc1f688bSRobert Mustacchi
437bc1f688bSRobert Mustacchi case DEBUG_ARANGES:
438*4d9fdb46SRobert Mustacchi if (dbg->de_arange == NULL) {
439bc1f688bSRobert Mustacchi continue;
440*4d9fdb46SRobert Mustacchi }
441bc1f688bSRobert Mustacchi break;
442bc1f688bSRobert Mustacchi
443bc1f688bSRobert Mustacchi case DEBUG_PUBNAMES:
444bc1f688bSRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_pubname].
445*4d9fdb46SRobert Mustacchi sn_head == NULL) {
446bc1f688bSRobert Mustacchi continue;
447*4d9fdb46SRobert Mustacchi }
448*4d9fdb46SRobert Mustacchi break;
449*4d9fdb46SRobert Mustacchi case DEBUG_PUBTYPES:
450*4d9fdb46SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_pubtype].
451*4d9fdb46SRobert Mustacchi sn_head == NULL) {
452*4d9fdb46SRobert Mustacchi continue;
453*4d9fdb46SRobert Mustacchi }
454bc1f688bSRobert Mustacchi break;
455bc1f688bSRobert Mustacchi
456bc1f688bSRobert Mustacchi case DEBUG_STR:
457*4d9fdb46SRobert Mustacchi if (dbg->de_debug_str->ds_data == NULL) {
458bc1f688bSRobert Mustacchi continue;
459*4d9fdb46SRobert Mustacchi }
460bc1f688bSRobert Mustacchi break;
461bc1f688bSRobert Mustacchi
462bc1f688bSRobert Mustacchi case DEBUG_FUNCNAMES:
463bc1f688bSRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_funcname].
464*4d9fdb46SRobert Mustacchi sn_head == NULL) {
465bc1f688bSRobert Mustacchi continue;
466*4d9fdb46SRobert Mustacchi }
467bc1f688bSRobert Mustacchi break;
468bc1f688bSRobert Mustacchi
469bc1f688bSRobert Mustacchi case DEBUG_TYPENAMES:
470bc1f688bSRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_typename].
471*4d9fdb46SRobert Mustacchi sn_head == NULL) {
472bc1f688bSRobert Mustacchi continue;
473*4d9fdb46SRobert Mustacchi }
474bc1f688bSRobert Mustacchi break;
475bc1f688bSRobert Mustacchi
476bc1f688bSRobert Mustacchi case DEBUG_VARNAMES:
477bc1f688bSRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_varname].
478*4d9fdb46SRobert Mustacchi sn_head == NULL) {
479bc1f688bSRobert Mustacchi continue;
480*4d9fdb46SRobert Mustacchi }
481bc1f688bSRobert Mustacchi break;
482bc1f688bSRobert Mustacchi
483bc1f688bSRobert Mustacchi case DEBUG_WEAKNAMES:
484bc1f688bSRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_weakname].
485*4d9fdb46SRobert Mustacchi sn_head == NULL) {
486bc1f688bSRobert Mustacchi continue;
487*4d9fdb46SRobert Mustacchi }
488bc1f688bSRobert Mustacchi break;
489bc1f688bSRobert Mustacchi
490bc1f688bSRobert Mustacchi case DEBUG_MACINFO:
491*4d9fdb46SRobert Mustacchi if (dbg->de_first_macinfo == NULL) {
492bc1f688bSRobert Mustacchi continue;
493*4d9fdb46SRobert Mustacchi }
494*4d9fdb46SRobert Mustacchi break;
495*4d9fdb46SRobert Mustacchi case DEBUG_NAMES: /* DWARF5 */
496*4d9fdb46SRobert Mustacchi if (dwarf_need_debug_names_section(dbg) == FALSE) {
497*4d9fdb46SRobert Mustacchi continue;
498*4d9fdb46SRobert Mustacchi }
499bc1f688bSRobert Mustacchi break;
500bc1f688bSRobert Mustacchi case DEBUG_LOC:
501*4d9fdb46SRobert Mustacchi /* Not handled yet. */
502*4d9fdb46SRobert Mustacchi continue;
503*4d9fdb46SRobert Mustacchi case DEBUG_RANGES:
504*4d9fdb46SRobert Mustacchi /* Not handled yet. */
505*4d9fdb46SRobert Mustacchi continue;
506*4d9fdb46SRobert Mustacchi case DEBUG_TYPES:
507*4d9fdb46SRobert Mustacchi /* Not handled yet. */
508*4d9fdb46SRobert Mustacchi continue;
509*4d9fdb46SRobert Mustacchi case DEBUG_MACRO:
510*4d9fdb46SRobert Mustacchi /* Not handled yet. */
511*4d9fdb46SRobert Mustacchi continue;
512*4d9fdb46SRobert Mustacchi case DEBUG_LOCLISTS:
513*4d9fdb46SRobert Mustacchi /* Not handled yet. */
514*4d9fdb46SRobert Mustacchi continue;
515*4d9fdb46SRobert Mustacchi case DEBUG_RNGLISTS:
516*4d9fdb46SRobert Mustacchi /* Not handled yet. */
517*4d9fdb46SRobert Mustacchi continue;
518*4d9fdb46SRobert Mustacchi case DEBUG_LINE_STR:
519*4d9fdb46SRobert Mustacchi if (dwarf_need_debug_line_section(dbg) == FALSE) {
520*4d9fdb46SRobert Mustacchi continue;
521*4d9fdb46SRobert Mustacchi }
522*4d9fdb46SRobert Mustacchi /* Not handled yet. */
523bc1f688bSRobert Mustacchi continue;
524bc1f688bSRobert Mustacchi default:
525bc1f688bSRobert Mustacchi /* logic error: missing a case */
526*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR);
527bc1f688bSRobert Mustacchi }
528bc1f688bSRobert Mustacchi {
529*4d9fdb46SRobert Mustacchi int new_base_elf_sect = 0;
530bc1f688bSRobert Mustacchi
531*4d9fdb46SRobert Mustacchi if (dbg->de_callback_func) {
532bc1f688bSRobert Mustacchi new_base_elf_sect =
533*4d9fdb46SRobert Mustacchi dbg->de_callback_func(_dwarf_sectnames[sect],
534bc1f688bSRobert Mustacchi /* rec size */ 1,
535bc1f688bSRobert Mustacchi SECTION_TYPE,
536*4d9fdb46SRobert Mustacchi flags, SHN_UNDEF, 0, &du,
537*4d9fdb46SRobert Mustacchi dbg->de_user_data, &err);
538bc1f688bSRobert Mustacchi }
539bc1f688bSRobert Mustacchi if (new_base_elf_sect == -1) {
540bc1f688bSRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR,
541*4d9fdb46SRobert Mustacchi DW_DLV_ERROR);
542bc1f688bSRobert Mustacchi }
543bc1f688bSRobert Mustacchi dbg->de_elf_sects[sect] = new_base_elf_sect;
544bc1f688bSRobert Mustacchi dbg->de_sect_name_idx[sect] = du;
545bc1f688bSRobert Mustacchi }
546bc1f688bSRobert Mustacchi }
547bc1f688bSRobert Mustacchi
548bc1f688bSRobert Mustacchi nbufs = 0;
549bc1f688bSRobert Mustacchi
550*4d9fdb46SRobert Mustacchi /* Changing the order in which the sections are generated may cause
551bc1f688bSRobert Mustacchi problems because of relocations. */
552bc1f688bSRobert Mustacchi
553bc1f688bSRobert Mustacchi if (dwarf_need_debug_line_section(dbg) == TRUE) {
554*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_generate_debugline(dbg,&nbufs, error);
555*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
556*4d9fdb46SRobert Mustacchi return res;
557bc1f688bSRobert Mustacchi }
558bc1f688bSRobert Mustacchi }
559bc1f688bSRobert Mustacchi
560bc1f688bSRobert Mustacchi if (dbg->de_frame_cies) {
561*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_generate_debugframe(dbg,&nbufs,error);
562*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
563*4d9fdb46SRobert Mustacchi return res;
564bc1f688bSRobert Mustacchi }
565bc1f688bSRobert Mustacchi }
566bc1f688bSRobert Mustacchi if (dbg->de_first_macinfo) {
567*4d9fdb46SRobert Mustacchi /* For DWARF 2,3,4 only */
568*4d9fdb46SRobert Mustacchi /* Need new code for DWARF5 macro info. FIXME*/
569*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_transform_macro_info_to_disk(dbg,
570*4d9fdb46SRobert Mustacchi &nbufs,error);
571*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
572*4d9fdb46SRobert Mustacchi return res;
573bc1f688bSRobert Mustacchi }
574bc1f688bSRobert Mustacchi }
575bc1f688bSRobert Mustacchi
576bc1f688bSRobert Mustacchi if (dbg->de_dies) {
577*4d9fdb46SRobert Mustacchi int res= _dwarf_pro_generate_debuginfo(dbg, &nbufs, error);
578*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
579*4d9fdb46SRobert Mustacchi return res;
580bc1f688bSRobert Mustacchi }
581bc1f688bSRobert Mustacchi }
582bc1f688bSRobert Mustacchi
583*4d9fdb46SRobert Mustacchi if (dbg->de_debug_str->ds_data) {
584*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_generate_debug_str(dbg,&nbufs, error);
585*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
586*4d9fdb46SRobert Mustacchi return res;
587*4d9fdb46SRobert Mustacchi }
588*4d9fdb46SRobert Mustacchi }
589*4d9fdb46SRobert Mustacchi if (dbg->de_debug_line_str->ds_data) {
590*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_generate_debug_line_str(dbg,&nbufs, error);
591*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
592*4d9fdb46SRobert Mustacchi return res;
593*4d9fdb46SRobert Mustacchi }
594*4d9fdb46SRobert Mustacchi }
595*4d9fdb46SRobert Mustacchi
596*4d9fdb46SRobert Mustacchi
597*4d9fdb46SRobert Mustacchi
598bc1f688bSRobert Mustacchi if (dbg->de_arange) {
599*4d9fdb46SRobert Mustacchi int res = _dwarf_transform_arange_to_disk(dbg,&nbufs, error);
600*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
601*4d9fdb46SRobert Mustacchi return res;
602bc1f688bSRobert Mustacchi }
603bc1f688bSRobert Mustacchi }
604*4d9fdb46SRobert Mustacchi if (dbg->de_output_version < 5) {
605bc1f688bSRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) {
606*4d9fdb46SRobert Mustacchi int res = _dwarf_transform_simplename_to_disk(dbg,
607bc1f688bSRobert Mustacchi dwarf_snk_pubname,
608bc1f688bSRobert Mustacchi DEBUG_PUBNAMES,
609*4d9fdb46SRobert Mustacchi &nbufs,
610bc1f688bSRobert Mustacchi error);
611*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
612*4d9fdb46SRobert Mustacchi return res;
613*4d9fdb46SRobert Mustacchi }
614*4d9fdb46SRobert Mustacchi }
615*4d9fdb46SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_pubtype].sn_head) {
616*4d9fdb46SRobert Mustacchi int res = _dwarf_transform_simplename_to_disk(dbg,
617*4d9fdb46SRobert Mustacchi dwarf_snk_pubtype,
618*4d9fdb46SRobert Mustacchi DEBUG_PUBTYPES,
619*4d9fdb46SRobert Mustacchi &nbufs,
620*4d9fdb46SRobert Mustacchi error);
621*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
622*4d9fdb46SRobert Mustacchi return res;
623bc1f688bSRobert Mustacchi }
624bc1f688bSRobert Mustacchi }
625bc1f688bSRobert Mustacchi
626bc1f688bSRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) {
627*4d9fdb46SRobert Mustacchi int res = _dwarf_transform_simplename_to_disk(dbg,
628bc1f688bSRobert Mustacchi dwarf_snk_funcname,
629bc1f688bSRobert Mustacchi DEBUG_FUNCNAMES,
630*4d9fdb46SRobert Mustacchi &nbufs,
631bc1f688bSRobert Mustacchi error);
632*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
633*4d9fdb46SRobert Mustacchi return res;
634bc1f688bSRobert Mustacchi }
635bc1f688bSRobert Mustacchi }
636bc1f688bSRobert Mustacchi
637bc1f688bSRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) {
638*4d9fdb46SRobert Mustacchi int res = _dwarf_transform_simplename_to_disk(dbg,
639bc1f688bSRobert Mustacchi dwarf_snk_typename,
640bc1f688bSRobert Mustacchi DEBUG_TYPENAMES,
641*4d9fdb46SRobert Mustacchi &nbufs,
642bc1f688bSRobert Mustacchi error);
643*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
644*4d9fdb46SRobert Mustacchi return res;
645bc1f688bSRobert Mustacchi }
646bc1f688bSRobert Mustacchi }
647bc1f688bSRobert Mustacchi
648bc1f688bSRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) {
649*4d9fdb46SRobert Mustacchi int res = _dwarf_transform_simplename_to_disk(dbg,
650bc1f688bSRobert Mustacchi dwarf_snk_varname,
651bc1f688bSRobert Mustacchi DEBUG_VARNAMES,
652*4d9fdb46SRobert Mustacchi &nbufs,
653bc1f688bSRobert Mustacchi error);
654*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
655*4d9fdb46SRobert Mustacchi return res;
656bc1f688bSRobert Mustacchi }
657bc1f688bSRobert Mustacchi }
658bc1f688bSRobert Mustacchi
659bc1f688bSRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) {
660*4d9fdb46SRobert Mustacchi int res = _dwarf_transform_simplename_to_disk(dbg,
661*4d9fdb46SRobert Mustacchi dwarf_snk_weakname, DEBUG_WEAKNAMES,
662*4d9fdb46SRobert Mustacchi &nbufs,
663*4d9fdb46SRobert Mustacchi error);
664*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
665*4d9fdb46SRobert Mustacchi return res;
666bc1f688bSRobert Mustacchi }
667bc1f688bSRobert Mustacchi }
668*4d9fdb46SRobert Mustacchi }
669*4d9fdb46SRobert Mustacchi if (dwarf_need_debug_names_section(dbg) == TRUE) {
670*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_generate_debug_names(dbg,&nbufs, error);
671*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
672*4d9fdb46SRobert Mustacchi return res;
673*4d9fdb46SRobert Mustacchi }
674*4d9fdb46SRobert Mustacchi }
675*4d9fdb46SRobert Mustacchi #if 0 /* FIXME: TODO new sections */
676*4d9fdb46SRobert Mustacchi if (dwarf_need_debug_macro_section(dbg) == TRUE) {
677*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_generate_debug_macro(dbg,&nbufs, error);
678*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
679*4d9fdb46SRobert Mustacchi return res;
680*4d9fdb46SRobert Mustacchi }
681*4d9fdb46SRobert Mustacchi }
682*4d9fdb46SRobert Mustacchi if (dwarf_need_debug_loclists_section(dbg) == TRUE) {
683*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_generate_debug_loclists(dbg,&nbufs, error);
684*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
685*4d9fdb46SRobert Mustacchi return res;
686*4d9fdb46SRobert Mustacchi }
687*4d9fdb46SRobert Mustacchi }
688*4d9fdb46SRobert Mustacchi if (dwarf_need_debug_rnglists_section(dbg) == TRUE) {
689*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_generate_debug_rnglists(dbg,&nbufs, error);
690*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
691*4d9fdb46SRobert Mustacchi return res;
692*4d9fdb46SRobert Mustacchi }
693*4d9fdb46SRobert Mustacchi }
694*4d9fdb46SRobert Mustacchi #endif
695bc1f688bSRobert Mustacchi
696bc1f688bSRobert Mustacchi {
697*4d9fdb46SRobert Mustacchi Dwarf_Signed new_chunks = 0;
698bc1f688bSRobert Mustacchi int res = 0;
699bc1f688bSRobert Mustacchi
700*4d9fdb46SRobert Mustacchi res = dbg->de_transform_relocs_to_disk(dbg, &new_chunks);
701bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
702*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_RELOCS_ERROR,
703*4d9fdb46SRobert Mustacchi DW_DLV_ERROR);
704bc1f688bSRobert Mustacchi }
705*4d9fdb46SRobert Mustacchi nbufs += new_chunks;
706bc1f688bSRobert Mustacchi }
707*4d9fdb46SRobert Mustacchi *count = nbufs;
708*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
709bc1f688bSRobert Mustacchi }
710bc1f688bSRobert Mustacchi
711bc1f688bSRobert Mustacchi static int
write_fixed_size(Dwarf_Unsigned val,Dwarf_P_Debug dbg,int elfsectno,Dwarf_Unsigned size,unsigned * size_out,Dwarf_Error * error)712*4d9fdb46SRobert Mustacchi write_fixed_size(Dwarf_Unsigned val,
713*4d9fdb46SRobert Mustacchi Dwarf_P_Debug dbg,
714*4d9fdb46SRobert Mustacchi int elfsectno,
715*4d9fdb46SRobert Mustacchi Dwarf_Unsigned size,
716*4d9fdb46SRobert Mustacchi unsigned * size_out,
717*4d9fdb46SRobert Mustacchi Dwarf_Error* error)
718bc1f688bSRobert Mustacchi {
719*4d9fdb46SRobert Mustacchi unsigned char *data = 0;
720*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, elfsectno, data, size, error);
721*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &val,
722*4d9fdb46SRobert Mustacchi sizeof(val), size);
723*4d9fdb46SRobert Mustacchi *size_out = size;
724*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
725*4d9fdb46SRobert Mustacchi }
726bc1f688bSRobert Mustacchi
727*4d9fdb46SRobert Mustacchi static int
write_ubyte(unsigned val,Dwarf_P_Debug dbg,int elfsectno,unsigned * len_out,Dwarf_Error * error)728*4d9fdb46SRobert Mustacchi write_ubyte(unsigned val,
729*4d9fdb46SRobert Mustacchi Dwarf_P_Debug dbg,
730*4d9fdb46SRobert Mustacchi int elfsectno,
731*4d9fdb46SRobert Mustacchi unsigned *len_out,
732*4d9fdb46SRobert Mustacchi Dwarf_Error* error)
733*4d9fdb46SRobert Mustacchi {
734*4d9fdb46SRobert Mustacchi Dwarf_Ubyte db = val;
735*4d9fdb46SRobert Mustacchi unsigned char *data = 0;
736*4d9fdb46SRobert Mustacchi unsigned len = sizeof(Dwarf_Ubyte);
737*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, elfsectno, data,
738*4d9fdb46SRobert Mustacchi len, error);
739*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
740*4d9fdb46SRobert Mustacchi sizeof(db), len);
741*4d9fdb46SRobert Mustacchi *len_out = 1;
742*4d9fdb46SRobert Mustacchi return DW_DLV_OK;;
743*4d9fdb46SRobert Mustacchi }
744*4d9fdb46SRobert Mustacchi static int
pretend_write_uval(Dwarf_Unsigned val,Dwarf_P_Debug dbg,unsigned * uval_len_out,Dwarf_Error * error)745*4d9fdb46SRobert Mustacchi pretend_write_uval(Dwarf_Unsigned val,
746*4d9fdb46SRobert Mustacchi Dwarf_P_Debug dbg,
747*4d9fdb46SRobert Mustacchi unsigned *uval_len_out,
748*4d9fdb46SRobert Mustacchi Dwarf_Error* error)
749*4d9fdb46SRobert Mustacchi {
750bc1f688bSRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED];
751*4d9fdb46SRobert Mustacchi int nbytes = 0;
752*4d9fdb46SRobert Mustacchi int res = 0;
753*4d9fdb46SRobert Mustacchi
754*4d9fdb46SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val,
755*4d9fdb46SRobert Mustacchi &nbytes, buff1,
756*4d9fdb46SRobert Mustacchi sizeof(buff1));
757*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
758*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg,DW_DLE_LEB_OUT_ERROR , DW_DLV_ERROR);
759*4d9fdb46SRobert Mustacchi }
760*4d9fdb46SRobert Mustacchi *uval_len_out = nbytes;
761*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
762*4d9fdb46SRobert Mustacchi }
763*4d9fdb46SRobert Mustacchi
764*4d9fdb46SRobert Mustacchi static int
write_sval(Dwarf_Signed val,Dwarf_P_Debug dbg,int elfsectno,unsigned * sval_len_out,Dwarf_Error * error)765*4d9fdb46SRobert Mustacchi write_sval(Dwarf_Signed val,
766*4d9fdb46SRobert Mustacchi Dwarf_P_Debug dbg,
767*4d9fdb46SRobert Mustacchi int elfsectno,
768*4d9fdb46SRobert Mustacchi unsigned *sval_len_out,
769*4d9fdb46SRobert Mustacchi Dwarf_Error* error)
770*4d9fdb46SRobert Mustacchi {
771*4d9fdb46SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED];
772*4d9fdb46SRobert Mustacchi unsigned char *data = 0;
773*4d9fdb46SRobert Mustacchi int nbytes = 0;
774*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_encode_signed_leb128_nm(val,
775*4d9fdb46SRobert Mustacchi &nbytes, buff1,
776*4d9fdb46SRobert Mustacchi sizeof(buff1));
777*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
778*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR);
779*4d9fdb46SRobert Mustacchi }
780*4d9fdb46SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, nbytes, error);
781*4d9fdb46SRobert Mustacchi memcpy((void *) data, (const void *) buff1, nbytes);
782*4d9fdb46SRobert Mustacchi *sval_len_out = nbytes;
783*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
784*4d9fdb46SRobert Mustacchi }
785*4d9fdb46SRobert Mustacchi
786*4d9fdb46SRobert Mustacchi /* This one does not allocate a chunk, uses
787*4d9fdb46SRobert Mustacchi an already existing chunk.
788*4d9fdb46SRobert Mustacchi data points into that existing chunk. */
789*4d9fdb46SRobert Mustacchi static int
append_uval(Dwarf_Unsigned val,Dwarf_P_Debug dbg,unsigned char * data,unsigned * uval_len_out,Dwarf_Error * error)790*4d9fdb46SRobert Mustacchi append_uval(Dwarf_Unsigned val,
791*4d9fdb46SRobert Mustacchi Dwarf_P_Debug dbg,
792*4d9fdb46SRobert Mustacchi unsigned char *data,
793*4d9fdb46SRobert Mustacchi unsigned * uval_len_out,
794*4d9fdb46SRobert Mustacchi Dwarf_Error* error)
795*4d9fdb46SRobert Mustacchi {
796*4d9fdb46SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED];
797*4d9fdb46SRobert Mustacchi int nbytes = 0;
798*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_encode_leb128_nm(val,
799*4d9fdb46SRobert Mustacchi &nbytes, buff1,
800*4d9fdb46SRobert Mustacchi sizeof(buff1));
801*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
802*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR);
803*4d9fdb46SRobert Mustacchi }
804*4d9fdb46SRobert Mustacchi memcpy((void *) data, (const void *) buff1, nbytes);
805*4d9fdb46SRobert Mustacchi *uval_len_out = nbytes;
806*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
807*4d9fdb46SRobert Mustacchi }
808bc1f688bSRobert Mustacchi
809bc1f688bSRobert Mustacchi
810*4d9fdb46SRobert Mustacchi static int
write_uval(Dwarf_Unsigned val,Dwarf_P_Debug dbg,int elfsectno,unsigned * uval_len_out,Dwarf_Error * error)811*4d9fdb46SRobert Mustacchi write_uval(Dwarf_Unsigned val,
812*4d9fdb46SRobert Mustacchi Dwarf_P_Debug dbg,
813*4d9fdb46SRobert Mustacchi int elfsectno,
814*4d9fdb46SRobert Mustacchi unsigned * uval_len_out,
815*4d9fdb46SRobert Mustacchi Dwarf_Error* error)
816*4d9fdb46SRobert Mustacchi {
817*4d9fdb46SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED];
818*4d9fdb46SRobert Mustacchi unsigned char *data = 0;
819*4d9fdb46SRobert Mustacchi int nbytes = 0;
820*4d9fdb46SRobert Mustacchi int res = _dwarf_pro_encode_leb128_nm(val,
821*4d9fdb46SRobert Mustacchi &nbytes, buff1,
822*4d9fdb46SRobert Mustacchi sizeof(buff1));
823*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
824*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR);
825*4d9fdb46SRobert Mustacchi }
826*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, elfsectno, data, nbytes, error);
827*4d9fdb46SRobert Mustacchi memcpy((void *) data, (const void *) buff1, nbytes);
828*4d9fdb46SRobert Mustacchi *uval_len_out = nbytes;
829*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
830*4d9fdb46SRobert Mustacchi }
831bc1f688bSRobert Mustacchi
832bc1f688bSRobert Mustacchi
833*4d9fdb46SRobert Mustacchi static unsigned
write_opcode_uval(int opcode,Dwarf_P_Debug dbg,int elfsectno,Dwarf_Unsigned val,unsigned * len_out,Dwarf_Error * error)834*4d9fdb46SRobert Mustacchi write_opcode_uval(int opcode,
835*4d9fdb46SRobert Mustacchi Dwarf_P_Debug dbg,
836*4d9fdb46SRobert Mustacchi int elfsectno,
837*4d9fdb46SRobert Mustacchi Dwarf_Unsigned val,
838*4d9fdb46SRobert Mustacchi unsigned *len_out,
839*4d9fdb46SRobert Mustacchi Dwarf_Error* error)
840*4d9fdb46SRobert Mustacchi {
841*4d9fdb46SRobert Mustacchi unsigned ublen = 0;
842*4d9fdb46SRobert Mustacchi int res = 0;
843*4d9fdb46SRobert Mustacchi unsigned uvlen = 0;
844*4d9fdb46SRobert Mustacchi res = write_ubyte(opcode,dbg,elfsectno,&ublen,error);
845*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
846*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR);
847*4d9fdb46SRobert Mustacchi }
848*4d9fdb46SRobert Mustacchi res = write_uval(val,dbg,elfsectno,&uvlen,error);
849*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
850*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR);
851*4d9fdb46SRobert Mustacchi }
852*4d9fdb46SRobert Mustacchi *len_out = ublen +uvlen;
853*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
854*4d9fdb46SRobert Mustacchi }
855*4d9fdb46SRobert Mustacchi
856*4d9fdb46SRobert Mustacchi static int
determine_form_size(Dwarf_P_Debug dbg,unsigned format_count,struct Dwarf_P_Line_format_s * format,unsigned * size_out,Dwarf_Bool write_out,unsigned char * data,Dwarf_Error * error)857*4d9fdb46SRobert Mustacchi determine_form_size(Dwarf_P_Debug dbg,
858*4d9fdb46SRobert Mustacchi unsigned format_count,
859*4d9fdb46SRobert Mustacchi struct Dwarf_P_Line_format_s *format,
860*4d9fdb46SRobert Mustacchi unsigned *size_out,
861*4d9fdb46SRobert Mustacchi Dwarf_Bool write_out,
862*4d9fdb46SRobert Mustacchi unsigned char *data,
863*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
864*4d9fdb46SRobert Mustacchi {
865*4d9fdb46SRobert Mustacchi unsigned calculated_size = 0;
866*4d9fdb46SRobert Mustacchi unsigned n = 0;
867*4d9fdb46SRobert Mustacchi int res = 0;
868*4d9fdb46SRobert Mustacchi
869*4d9fdb46SRobert Mustacchi /* entry format itself */
870*4d9fdb46SRobert Mustacchi calculated_size += sizeof_ubyte(dbg);
871*4d9fdb46SRobert Mustacchi
872*4d9fdb46SRobert Mustacchi /* Space for the format details. */
873*4d9fdb46SRobert Mustacchi for(n = 0; n < format_count; ++n) {
874*4d9fdb46SRobert Mustacchi struct Dwarf_P_Line_format_s *lf = format+n;
875*4d9fdb46SRobert Mustacchi unsigned val_len = 0;
876*4d9fdb46SRobert Mustacchi unsigned val_len2 = 0;
877*4d9fdb46SRobert Mustacchi
878*4d9fdb46SRobert Mustacchi if (write_out) {
879*4d9fdb46SRobert Mustacchi res = append_uval(lf->def_content_type, dbg,
880*4d9fdb46SRobert Mustacchi data,
881*4d9fdb46SRobert Mustacchi &val_len,error);
882*4d9fdb46SRobert Mustacchi } else {
883*4d9fdb46SRobert Mustacchi res = pretend_write_uval(lf->def_content_type, dbg,
884*4d9fdb46SRobert Mustacchi &val_len,error);
885*4d9fdb46SRobert Mustacchi }
886*4d9fdb46SRobert Mustacchi data += val_len;
887*4d9fdb46SRobert Mustacchi if(res != DW_DLV_OK) {
888*4d9fdb46SRobert Mustacchi return res;
889*4d9fdb46SRobert Mustacchi }
890*4d9fdb46SRobert Mustacchi if (write_out) {
891*4d9fdb46SRobert Mustacchi res = append_uval(lf->def_form_code, dbg,
892*4d9fdb46SRobert Mustacchi data,
893*4d9fdb46SRobert Mustacchi &val_len2,error);
894*4d9fdb46SRobert Mustacchi } else {
895*4d9fdb46SRobert Mustacchi res = pretend_write_uval(lf->def_form_code, dbg,
896*4d9fdb46SRobert Mustacchi &val_len2,error);
897*4d9fdb46SRobert Mustacchi }
898*4d9fdb46SRobert Mustacchi if(res != DW_DLV_OK) {
899*4d9fdb46SRobert Mustacchi return res;
900*4d9fdb46SRobert Mustacchi }
901*4d9fdb46SRobert Mustacchi data += val_len2;
902*4d9fdb46SRobert Mustacchi calculated_size += val_len + val_len2;
903*4d9fdb46SRobert Mustacchi }
904*4d9fdb46SRobert Mustacchi *size_out = calculated_size;
905*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
906*4d9fdb46SRobert Mustacchi }
907*4d9fdb46SRobert Mustacchi
908*4d9fdb46SRobert Mustacchi static int
determine_file_content_size(Dwarf_P_Debug dbg,Dwarf_P_F_Entry entry_list,Dwarf_Unsigned format_count,struct Dwarf_P_Line_format_s * format,unsigned * size_out,Dwarf_Bool write_out,unsigned char * data,Dwarf_Error * error)909*4d9fdb46SRobert Mustacchi determine_file_content_size(Dwarf_P_Debug dbg,
910*4d9fdb46SRobert Mustacchi Dwarf_P_F_Entry entry_list,
911*4d9fdb46SRobert Mustacchi Dwarf_Unsigned format_count,
912*4d9fdb46SRobert Mustacchi struct Dwarf_P_Line_format_s *format,
913*4d9fdb46SRobert Mustacchi unsigned *size_out,
914*4d9fdb46SRobert Mustacchi Dwarf_Bool write_out,
915*4d9fdb46SRobert Mustacchi unsigned char *data,
916*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
917*4d9fdb46SRobert Mustacchi {
918*4d9fdb46SRobert Mustacchi unsigned calculated_size = 0;
919*4d9fdb46SRobert Mustacchi unsigned count_len = 0;
920*4d9fdb46SRobert Mustacchi Dwarf_P_F_Entry cur = 0;
921*4d9fdb46SRobert Mustacchi Dwarf_P_F_Entry nxt = 0;
922*4d9fdb46SRobert Mustacchi unsigned n = 0;
923*4d9fdb46SRobert Mustacchi int res = 0;
924*4d9fdb46SRobert Mustacchi Dwarf_Unsigned offset_size = 0;
925*4d9fdb46SRobert Mustacchi
926*4d9fdb46SRobert Mustacchi offset_size = dbg->de_dwarf_offset_size;
927*4d9fdb46SRobert Mustacchi res = pretend_write_uval(format_count,dbg,
928*4d9fdb46SRobert Mustacchi &count_len,error);
929*4d9fdb46SRobert Mustacchi if(res != DW_DLV_OK) {
930*4d9fdb46SRobert Mustacchi return res;
931*4d9fdb46SRobert Mustacchi }
932*4d9fdb46SRobert Mustacchi calculated_size += count_len;
933*4d9fdb46SRobert Mustacchi
934*4d9fdb46SRobert Mustacchi cur = entry_list;
935*4d9fdb46SRobert Mustacchi for(n = 0; cur; n++,cur = nxt) {
936*4d9fdb46SRobert Mustacchi unsigned f = 0;
937*4d9fdb46SRobert Mustacchi nxt = cur->dfe_next;
938*4d9fdb46SRobert Mustacchi
939*4d9fdb46SRobert Mustacchi for( ; f < format_count; f++) {
940*4d9fdb46SRobert Mustacchi struct Dwarf_P_Line_format_s *lf = format+f;
941*4d9fdb46SRobert Mustacchi unsigned ctype = lf->def_content_type;
942*4d9fdb46SRobert Mustacchi unsigned cform = lf->def_form_code;
943*4d9fdb46SRobert Mustacchi
944*4d9fdb46SRobert Mustacchi switch (ctype) {
945*4d9fdb46SRobert Mustacchi case DW_LNCT_path: {
946*4d9fdb46SRobert Mustacchi switch(cform) {
947*4d9fdb46SRobert Mustacchi case DW_FORM_string: {
948*4d9fdb46SRobert Mustacchi unsigned slen = strlen(cur->dfe_name) +1;
949*4d9fdb46SRobert Mustacchi calculated_size += slen;
950*4d9fdb46SRobert Mustacchi if (write_out) {
951*4d9fdb46SRobert Mustacchi strcpy((char *)data, cur->dfe_name);
952*4d9fdb46SRobert Mustacchi data += slen;
953*4d9fdb46SRobert Mustacchi }
954*4d9fdb46SRobert Mustacchi }
955*4d9fdb46SRobert Mustacchi break;
956*4d9fdb46SRobert Mustacchi case DW_FORM_strp: {
957*4d9fdb46SRobert Mustacchi unsigned slen = strlen(cur->dfe_name) +1;
958*4d9fdb46SRobert Mustacchi if (write_out) {
959*4d9fdb46SRobert Mustacchi Dwarf_Unsigned stroffset = 0;
960*4d9fdb46SRobert Mustacchi res = _dwarf_insert_or_find_in_debug_str(
961*4d9fdb46SRobert Mustacchi dbg,
962*4d9fdb46SRobert Mustacchi cur->dfe_name,
963*4d9fdb46SRobert Mustacchi _dwarf_hash_debug_str,
964*4d9fdb46SRobert Mustacchi slen,
965*4d9fdb46SRobert Mustacchi &stroffset,error);
966*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
967*4d9fdb46SRobert Mustacchi return res;
968*4d9fdb46SRobert Mustacchi }
969*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
970*4d9fdb46SRobert Mustacchi (const void *) &stroffset,
971*4d9fdb46SRobert Mustacchi sizeof(stroffset), offset_size);
972*4d9fdb46SRobert Mustacchi data += offset_size;
973*4d9fdb46SRobert Mustacchi }
974*4d9fdb46SRobert Mustacchi calculated_size += offset_size;
975*4d9fdb46SRobert Mustacchi }
976*4d9fdb46SRobert Mustacchi break;
977*4d9fdb46SRobert Mustacchi case DW_FORM_line_strp: {
978*4d9fdb46SRobert Mustacchi unsigned slen = strlen(cur->dfe_name) +1;
979*4d9fdb46SRobert Mustacchi if (write_out) {
980*4d9fdb46SRobert Mustacchi Dwarf_Unsigned stroffset = 0;
981*4d9fdb46SRobert Mustacchi res = _dwarf_insert_or_find_in_debug_str(
982*4d9fdb46SRobert Mustacchi dbg,
983*4d9fdb46SRobert Mustacchi cur->dfe_name,
984*4d9fdb46SRobert Mustacchi _dwarf_hash_debug_line_str,
985*4d9fdb46SRobert Mustacchi slen,
986*4d9fdb46SRobert Mustacchi &stroffset,error);
987*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
988*4d9fdb46SRobert Mustacchi return res;
989*4d9fdb46SRobert Mustacchi }
990*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
991*4d9fdb46SRobert Mustacchi (const void *) &stroffset,
992*4d9fdb46SRobert Mustacchi sizeof(stroffset), offset_size);
993*4d9fdb46SRobert Mustacchi data += offset_size;
994*4d9fdb46SRobert Mustacchi }
995*4d9fdb46SRobert Mustacchi calculated_size += offset_size;
996*4d9fdb46SRobert Mustacchi }
997*4d9fdb46SRobert Mustacchi break;
998*4d9fdb46SRobert Mustacchi case DW_FORM_strp_sup:
999*4d9fdb46SRobert Mustacchi /* Following in dwo only. */
1000*4d9fdb46SRobert Mustacchi case DW_FORM_strx:
1001*4d9fdb46SRobert Mustacchi case DW_FORM_strx1:
1002*4d9fdb46SRobert Mustacchi case DW_FORM_strx2:
1003*4d9fdb46SRobert Mustacchi case DW_FORM_strx3:
1004*4d9fdb46SRobert Mustacchi case DW_FORM_strx4:
1005*4d9fdb46SRobert Mustacchi default:
1006*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg,
1007*4d9fdb46SRobert Mustacchi DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR);
1008*4d9fdb46SRobert Mustacchi break;
1009*4d9fdb46SRobert Mustacchi }
1010*4d9fdb46SRobert Mustacchi }
1011*4d9fdb46SRobert Mustacchi break;
1012*4d9fdb46SRobert Mustacchi case DW_LNCT_directory_index: {
1013*4d9fdb46SRobert Mustacchi switch(cform) {
1014*4d9fdb46SRobert Mustacchi case DW_FORM_data1:
1015*4d9fdb46SRobert Mustacchi calculated_size += 1;
1016*4d9fdb46SRobert Mustacchi if (write_out) {
1017*4d9fdb46SRobert Mustacchi unsigned char ub = cur->dfe_index;
1018*4d9fdb46SRobert Mustacchi *data = ub;
1019*4d9fdb46SRobert Mustacchi data += 1;
1020*4d9fdb46SRobert Mustacchi }
1021*4d9fdb46SRobert Mustacchi break;
1022*4d9fdb46SRobert Mustacchi case DW_FORM_data2:
1023*4d9fdb46SRobert Mustacchi calculated_size += DWARF_HALF_SIZE;
1024*4d9fdb46SRobert Mustacchi if (write_out) {
1025*4d9fdb46SRobert Mustacchi Dwarf_Half uh = cur->dfe_index;
1026*4d9fdb46SRobert Mustacchi memcpy(data,&uh,DWARF_HALF_SIZE);
1027*4d9fdb46SRobert Mustacchi data += DWARF_HALF_SIZE;
1028*4d9fdb46SRobert Mustacchi }
1029*4d9fdb46SRobert Mustacchi break;
1030*4d9fdb46SRobert Mustacchi case DW_FORM_udata: {
1031*4d9fdb46SRobert Mustacchi unsigned val_len = 0;
1032*4d9fdb46SRobert Mustacchi if (write_out) {
1033*4d9fdb46SRobert Mustacchi res = append_uval(cur->dfe_index,
1034*4d9fdb46SRobert Mustacchi dbg,
1035*4d9fdb46SRobert Mustacchi data,
1036*4d9fdb46SRobert Mustacchi &val_len,error);
1037*4d9fdb46SRobert Mustacchi data += val_len;
1038*4d9fdb46SRobert Mustacchi } else {
1039*4d9fdb46SRobert Mustacchi res = pretend_write_uval(cur->dfe_index,
1040*4d9fdb46SRobert Mustacchi dbg, &val_len,error);
1041*4d9fdb46SRobert Mustacchi }
1042*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1043*4d9fdb46SRobert Mustacchi return res;
1044*4d9fdb46SRobert Mustacchi }
1045*4d9fdb46SRobert Mustacchi calculated_size += val_len;
1046*4d9fdb46SRobert Mustacchi }
1047*4d9fdb46SRobert Mustacchi break;
1048*4d9fdb46SRobert Mustacchi default:
1049*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg,
1050*4d9fdb46SRobert Mustacchi DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR);
1051*4d9fdb46SRobert Mustacchi }
1052*4d9fdb46SRobert Mustacchi }
1053*4d9fdb46SRobert Mustacchi break;
1054*4d9fdb46SRobert Mustacchi case DW_LNCT_timestamp: {
1055*4d9fdb46SRobert Mustacchi switch(cform) {
1056*4d9fdb46SRobert Mustacchi case DW_FORM_udata: {
1057*4d9fdb46SRobert Mustacchi unsigned val_len = 0;
1058*4d9fdb46SRobert Mustacchi if (write_out) {
1059*4d9fdb46SRobert Mustacchi res = append_uval(cur->dfe_timestamp,
1060*4d9fdb46SRobert Mustacchi dbg,
1061*4d9fdb46SRobert Mustacchi data,
1062*4d9fdb46SRobert Mustacchi &val_len,error);
1063*4d9fdb46SRobert Mustacchi data += val_len;
1064*4d9fdb46SRobert Mustacchi } else {
1065*4d9fdb46SRobert Mustacchi res = pretend_write_uval(cur->dfe_timestamp,
1066*4d9fdb46SRobert Mustacchi dbg, &val_len,error);
1067*4d9fdb46SRobert Mustacchi }
1068*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1069*4d9fdb46SRobert Mustacchi return res;
1070*4d9fdb46SRobert Mustacchi }
1071*4d9fdb46SRobert Mustacchi calculated_size += val_len;
1072*4d9fdb46SRobert Mustacchi }
1073*4d9fdb46SRobert Mustacchi break;
1074*4d9fdb46SRobert Mustacchi case DW_FORM_data4: {
1075*4d9fdb46SRobert Mustacchi calculated_size += DWARF_32BIT_SIZE;
1076*4d9fdb46SRobert Mustacchi if (write_out) {
1077*4d9fdb46SRobert Mustacchi ASNOUT(data,cur->dfe_timestamp,
1078*4d9fdb46SRobert Mustacchi DWARF_32BIT_SIZE);
1079*4d9fdb46SRobert Mustacchi data += DWARF_32BIT_SIZE;
1080*4d9fdb46SRobert Mustacchi }
1081*4d9fdb46SRobert Mustacchi }
1082*4d9fdb46SRobert Mustacchi break;
1083*4d9fdb46SRobert Mustacchi case DW_FORM_data8:
1084*4d9fdb46SRobert Mustacchi /* As of 2017 there is no 8 byte timestamp
1085*4d9fdb46SRobert Mustacchi defined, though it does have to happen.
1086*4d9fdb46SRobert Mustacchi before 2038. */
1087*4d9fdb46SRobert Mustacchi calculated_size += DWARF_64BIT_SIZE;
1088*4d9fdb46SRobert Mustacchi if (write_out) {
1089*4d9fdb46SRobert Mustacchi Dwarf_Unsigned u8 = cur->dfe_index;
1090*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
1091*4d9fdb46SRobert Mustacchi (const void *) &u8,
1092*4d9fdb46SRobert Mustacchi sizeof(u8), DWARF_64BIT_SIZE);
1093*4d9fdb46SRobert Mustacchi data += DWARF_64BIT_SIZE;
1094*4d9fdb46SRobert Mustacchi }
1095*4d9fdb46SRobert Mustacchi break;
1096*4d9fdb46SRobert Mustacchi case DW_FORM_block:
1097*4d9fdb46SRobert Mustacchi default:
1098*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg,
1099*4d9fdb46SRobert Mustacchi DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR);
1100*4d9fdb46SRobert Mustacchi }
1101*4d9fdb46SRobert Mustacchi }
1102*4d9fdb46SRobert Mustacchi break;
1103*4d9fdb46SRobert Mustacchi case DW_LNCT_size: {
1104*4d9fdb46SRobert Mustacchi switch(cform) {
1105*4d9fdb46SRobert Mustacchi case DW_FORM_data1:
1106*4d9fdb46SRobert Mustacchi calculated_size += 1;
1107*4d9fdb46SRobert Mustacchi if (write_out) {
1108*4d9fdb46SRobert Mustacchi unsigned char ub = cur->dfe_index;
1109*4d9fdb46SRobert Mustacchi *data = ub;
1110*4d9fdb46SRobert Mustacchi data += 1;
1111*4d9fdb46SRobert Mustacchi }
1112*4d9fdb46SRobert Mustacchi break;
1113*4d9fdb46SRobert Mustacchi case DW_FORM_data2:
1114*4d9fdb46SRobert Mustacchi calculated_size += DWARF_HALF_SIZE;
1115*4d9fdb46SRobert Mustacchi if (write_out) {
1116*4d9fdb46SRobert Mustacchi Dwarf_Half uh = cur->dfe_index;
1117*4d9fdb46SRobert Mustacchi memcpy(data,&uh,DWARF_HALF_SIZE);
1118*4d9fdb46SRobert Mustacchi
1119*4d9fdb46SRobert Mustacchi }
1120*4d9fdb46SRobert Mustacchi break;
1121*4d9fdb46SRobert Mustacchi case DW_FORM_data4:
1122*4d9fdb46SRobert Mustacchi calculated_size += DWARF_32BIT_SIZE;
1123*4d9fdb46SRobert Mustacchi if (write_out) {
1124*4d9fdb46SRobert Mustacchi ASNOUT(data,cur->dfe_index,
1125*4d9fdb46SRobert Mustacchi DWARF_32BIT_SIZE);
1126*4d9fdb46SRobert Mustacchi data += DWARF_32BIT_SIZE;
1127*4d9fdb46SRobert Mustacchi }
1128*4d9fdb46SRobert Mustacchi break;
1129*4d9fdb46SRobert Mustacchi case DW_FORM_data8:
1130*4d9fdb46SRobert Mustacchi calculated_size += DWARF_64BIT_SIZE;
1131*4d9fdb46SRobert Mustacchi if (write_out) {
1132*4d9fdb46SRobert Mustacchi Dwarf_Unsigned u8 = cur->dfe_index;
1133*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
1134*4d9fdb46SRobert Mustacchi (const void *) &u8,
1135*4d9fdb46SRobert Mustacchi sizeof(u8), DWARF_64BIT_SIZE);
1136*4d9fdb46SRobert Mustacchi data += DWARF_64BIT_SIZE;
1137*4d9fdb46SRobert Mustacchi }
1138*4d9fdb46SRobert Mustacchi break;
1139*4d9fdb46SRobert Mustacchi case DW_FORM_udata: {
1140*4d9fdb46SRobert Mustacchi unsigned val_len = 0;
1141*4d9fdb46SRobert Mustacchi if (write_out) {
1142*4d9fdb46SRobert Mustacchi res = append_uval(cur->dfe_size,
1143*4d9fdb46SRobert Mustacchi dbg,
1144*4d9fdb46SRobert Mustacchi data,
1145*4d9fdb46SRobert Mustacchi &val_len,error);
1146*4d9fdb46SRobert Mustacchi data += val_len;
1147*4d9fdb46SRobert Mustacchi } else {
1148*4d9fdb46SRobert Mustacchi res = pretend_write_uval(cur->dfe_size,
1149*4d9fdb46SRobert Mustacchi dbg, &val_len,error);
1150*4d9fdb46SRobert Mustacchi }
1151*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1152*4d9fdb46SRobert Mustacchi return res;
1153*4d9fdb46SRobert Mustacchi }
1154*4d9fdb46SRobert Mustacchi calculated_size += val_len;
1155*4d9fdb46SRobert Mustacchi }
1156*4d9fdb46SRobert Mustacchi break;
1157*4d9fdb46SRobert Mustacchi default:
1158*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg,
1159*4d9fdb46SRobert Mustacchi DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR);
1160*4d9fdb46SRobert Mustacchi }
1161*4d9fdb46SRobert Mustacchi }
1162*4d9fdb46SRobert Mustacchi break;
1163*4d9fdb46SRobert Mustacchi case DW_LNCT_MD5: {
1164*4d9fdb46SRobert Mustacchi switch(cform) {
1165*4d9fdb46SRobert Mustacchi case DW_FORM_data16:
1166*4d9fdb46SRobert Mustacchi if (write_out) {
1167*4d9fdb46SRobert Mustacchi memcpy(data,cur->dfe_md5,sizeof(cur->dfe_md5));
1168*4d9fdb46SRobert Mustacchi data += 16;
1169*4d9fdb46SRobert Mustacchi }
1170*4d9fdb46SRobert Mustacchi calculated_size += 16;
1171*4d9fdb46SRobert Mustacchi break;
1172*4d9fdb46SRobert Mustacchi default:
1173*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg,
1174*4d9fdb46SRobert Mustacchi DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR);
1175*4d9fdb46SRobert Mustacchi }
1176*4d9fdb46SRobert Mustacchi }
1177*4d9fdb46SRobert Mustacchi break;
1178*4d9fdb46SRobert Mustacchi default:
1179*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_CODE_UNKNOWN, DW_DLV_ERROR);
1180*4d9fdb46SRobert Mustacchi }
1181*4d9fdb46SRobert Mustacchi }
1182*4d9fdb46SRobert Mustacchi }
1183*4d9fdb46SRobert Mustacchi *size_out = calculated_size;
1184*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
1185*4d9fdb46SRobert Mustacchi }
1186*4d9fdb46SRobert Mustacchi
1187*4d9fdb46SRobert Mustacchi static int
calculate_size_of_line_header5(Dwarf_P_Debug dbg,struct Dwarf_P_Line_Inits_s * inits,unsigned * prolog_size_out,Dwarf_Error * error)1188*4d9fdb46SRobert Mustacchi calculate_size_of_line_header5(Dwarf_P_Debug dbg,
1189*4d9fdb46SRobert Mustacchi struct Dwarf_P_Line_Inits_s *inits,
1190*4d9fdb46SRobert Mustacchi unsigned *prolog_size_out,
1191*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
1192*4d9fdb46SRobert Mustacchi {
1193*4d9fdb46SRobert Mustacchi unsigned prolog_size = 0;
1194*4d9fdb46SRobert Mustacchi int offset_size = dbg->de_dwarf_offset_size;
1195*4d9fdb46SRobert Mustacchi int extension_size = dbg->de_64bit_extension ? 4 : 0;
1196*4d9fdb46SRobert Mustacchi int res = 0;
1197*4d9fdb46SRobert Mustacchi
1198*4d9fdb46SRobert Mustacchi prolog_size += OFFSET_PLUS_EXTENSION_SIZE +
1199*4d9fdb46SRobert Mustacchi sizeof_uhalf(dbg) + /* version # */
1200*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* address_size */
1201*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* segment_selector_size */
1202*4d9fdb46SRobert Mustacchi offset_size + /* header length */
1203*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* min_instr length */
1204*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* maximum_operations_per_instruction */
1205*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* default is_stmt */
1206*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* linebase */
1207*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* linerange */
1208*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg); /* opcode base */
1209*4d9fdb46SRobert Mustacchi /* For maximum_operations_per_instruction. */
1210*4d9fdb46SRobert Mustacchi prolog_size += sizeof_ubyte(dbg);
1211*4d9fdb46SRobert Mustacchi
1212*4d9fdb46SRobert Mustacchi /* standard_opcode_lengths table len */
1213*4d9fdb46SRobert Mustacchi prolog_size += inits->pi_opcode_base-1;
1214*4d9fdb46SRobert Mustacchi
1215*4d9fdb46SRobert Mustacchi {
1216*4d9fdb46SRobert Mustacchi unsigned fsize = 0;
1217*4d9fdb46SRobert Mustacchi res = determine_form_size(dbg,
1218*4d9fdb46SRobert Mustacchi inits->pi_directory_entry_format_count,
1219*4d9fdb46SRobert Mustacchi inits->pi_incformats,
1220*4d9fdb46SRobert Mustacchi &fsize,FALSE,0,error);
1221*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1222*4d9fdb46SRobert Mustacchi return res;
1223*4d9fdb46SRobert Mustacchi }
1224*4d9fdb46SRobert Mustacchi prolog_size += fsize;
1225*4d9fdb46SRobert Mustacchi }
1226*4d9fdb46SRobert Mustacchi {
1227*4d9fdb46SRobert Mustacchi unsigned dir_count_len = 0;
1228*4d9fdb46SRobert Mustacchi res = determine_file_content_size(dbg,
1229*4d9fdb46SRobert Mustacchi dbg->de_inc_dirs,
1230*4d9fdb46SRobert Mustacchi dbg->de_line_inits.pi_directory_entry_format_count,
1231*4d9fdb46SRobert Mustacchi dbg->de_line_inits.pi_incformats,
1232*4d9fdb46SRobert Mustacchi &dir_count_len,
1233*4d9fdb46SRobert Mustacchi FALSE,0,
1234*4d9fdb46SRobert Mustacchi error);
1235*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1236*4d9fdb46SRobert Mustacchi return res;
1237*4d9fdb46SRobert Mustacchi }
1238*4d9fdb46SRobert Mustacchi prolog_size += dir_count_len;
1239*4d9fdb46SRobert Mustacchi }
1240*4d9fdb46SRobert Mustacchi {
1241*4d9fdb46SRobert Mustacchi unsigned fsize = 0;
1242*4d9fdb46SRobert Mustacchi res = determine_form_size(dbg,
1243*4d9fdb46SRobert Mustacchi inits->pi_file_entry_format_count,
1244*4d9fdb46SRobert Mustacchi inits->pi_fileformats,
1245*4d9fdb46SRobert Mustacchi &fsize,
1246*4d9fdb46SRobert Mustacchi FALSE,0,
1247*4d9fdb46SRobert Mustacchi error);
1248*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1249*4d9fdb46SRobert Mustacchi return res;
1250*4d9fdb46SRobert Mustacchi }
1251*4d9fdb46SRobert Mustacchi prolog_size += fsize;
1252*4d9fdb46SRobert Mustacchi }
1253*4d9fdb46SRobert Mustacchi {
1254*4d9fdb46SRobert Mustacchi unsigned file_count_len = 0;
1255*4d9fdb46SRobert Mustacchi res = determine_file_content_size(dbg,
1256*4d9fdb46SRobert Mustacchi dbg->de_file_entries,
1257*4d9fdb46SRobert Mustacchi dbg->de_line_inits.pi_file_entry_format_count,
1258*4d9fdb46SRobert Mustacchi dbg->de_line_inits.pi_fileformats,
1259*4d9fdb46SRobert Mustacchi &file_count_len,
1260*4d9fdb46SRobert Mustacchi FALSE,0,
1261*4d9fdb46SRobert Mustacchi error);
1262*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1263*4d9fdb46SRobert Mustacchi return res;
1264*4d9fdb46SRobert Mustacchi }
1265*4d9fdb46SRobert Mustacchi prolog_size += file_count_len;
1266*4d9fdb46SRobert Mustacchi }
1267*4d9fdb46SRobert Mustacchi *prolog_size_out = prolog_size;
1268*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
1269*4d9fdb46SRobert Mustacchi }
1270*4d9fdb46SRobert Mustacchi
1271*4d9fdb46SRobert Mustacchi /* For DWARF 2,3,4 */
1272*4d9fdb46SRobert Mustacchi static int
calculate_size_of_line_header4(Dwarf_P_Debug dbg,struct Dwarf_P_Line_Inits_s * inits,unsigned * prolog_size_out,UNUSEDARG Dwarf_Error * error)1273*4d9fdb46SRobert Mustacchi calculate_size_of_line_header4(Dwarf_P_Debug dbg,
1274*4d9fdb46SRobert Mustacchi struct Dwarf_P_Line_Inits_s *inits,
1275*4d9fdb46SRobert Mustacchi unsigned *prolog_size_out,
1276*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Error *error)
1277*4d9fdb46SRobert Mustacchi {
1278*4d9fdb46SRobert Mustacchi Dwarf_P_F_Entry curdir = 0;
1279*4d9fdb46SRobert Mustacchi Dwarf_P_F_Entry curentry = 0;
1280*4d9fdb46SRobert Mustacchi unsigned prolog_size = 0;
1281*4d9fdb46SRobert Mustacchi int offset_size = dbg->de_dwarf_offset_size;
1282*4d9fdb46SRobert Mustacchi int extension_size = dbg->de_64bit_extension ? 4 : 0;
1283*4d9fdb46SRobert Mustacchi
1284*4d9fdb46SRobert Mustacchi prolog_size += OFFSET_PLUS_EXTENSION_SIZE +
1285*4d9fdb46SRobert Mustacchi sizeof_uhalf(dbg) + /* version # */
1286*4d9fdb46SRobert Mustacchi offset_size + /* header length */
1287*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* min_instr length */
1288*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* default is_stmt */
1289*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* linebase */
1290*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg) + /* linerange */
1291*4d9fdb46SRobert Mustacchi sizeof_ubyte(dbg); /* opcode base */
1292*4d9fdb46SRobert Mustacchi if (inits->pi_linetable_version == DW_LINE_VERSION4) {
1293*4d9fdb46SRobert Mustacchi /* For maximum_operations_per_instruction. */
1294*4d9fdb46SRobert Mustacchi prolog_size += sizeof_ubyte(dbg);
1295*4d9fdb46SRobert Mustacchi }
1296*4d9fdb46SRobert Mustacchi /* standard_opcode_lengths table len */
1297*4d9fdb46SRobert Mustacchi prolog_size += inits->pi_opcode_base-1;
1298bc1f688bSRobert Mustacchi
1299bc1f688bSRobert Mustacchi /* include directories */
1300bc1f688bSRobert Mustacchi curdir = dbg->de_inc_dirs;
1301bc1f688bSRobert Mustacchi while (curdir) {
1302*4d9fdb46SRobert Mustacchi prolog_size += strlen(curdir->dfe_name) + 1;
1303*4d9fdb46SRobert Mustacchi curdir = curdir->dfe_next;
1304bc1f688bSRobert Mustacchi }
1305bc1f688bSRobert Mustacchi prolog_size++; /* last null following last directory
1306bc1f688bSRobert Mustacchi entry. */
1307bc1f688bSRobert Mustacchi
1308bc1f688bSRobert Mustacchi /* file entries */
1309bc1f688bSRobert Mustacchi curentry = dbg->de_file_entries;
1310bc1f688bSRobert Mustacchi while (curentry) {
1311bc1f688bSRobert Mustacchi prolog_size +=
1312bc1f688bSRobert Mustacchi strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes;
1313bc1f688bSRobert Mustacchi curentry = curentry->dfe_next;
1314bc1f688bSRobert Mustacchi }
1315bc1f688bSRobert Mustacchi prolog_size++; /* last null byte */
1316*4d9fdb46SRobert Mustacchi *prolog_size_out = prolog_size;
1317*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
1318*4d9fdb46SRobert Mustacchi }
1319bc1f688bSRobert Mustacchi
1320bc1f688bSRobert Mustacchi
1321*4d9fdb46SRobert Mustacchi /* Generate debug_line section
1322*4d9fdb46SRobert Mustacchi Dwarf2, dwarf3 headers are the same (DW3 acknowledges 64bit).
1323*4d9fdb46SRobert Mustacchi DWARF4 adds the maximum_operations_per_instruction field.
1324*4d9fdb46SRobert Mustacchi DWARF5 adds address size and address selector size
1325*4d9fdb46SRobert Mustacchi and replaces the entire directories/files list with
1326*4d9fdb46SRobert Mustacchi very different stuff.
1327*4d9fdb46SRobert Mustacchi */
1328*4d9fdb46SRobert Mustacchi static int
_dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)1329*4d9fdb46SRobert Mustacchi _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
1330*4d9fdb46SRobert Mustacchi Dwarf_Signed * nbufs,
1331*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
1332*4d9fdb46SRobert Mustacchi {
1333*4d9fdb46SRobert Mustacchi Dwarf_P_F_Entry curdir = 0;
1334*4d9fdb46SRobert Mustacchi Dwarf_P_F_Entry curentry = 0;
1335*4d9fdb46SRobert Mustacchi Dwarf_P_Line curline = 0;
1336*4d9fdb46SRobert Mustacchi Dwarf_P_Line prevline = 0;
1337*4d9fdb46SRobert Mustacchi struct Dwarf_P_Line_Inits_s *inits = 0;
1338bc1f688bSRobert Mustacchi
1339*4d9fdb46SRobert Mustacchi /* all data named cur* are used to loop thru linked lists */
1340bc1f688bSRobert Mustacchi
1341*4d9fdb46SRobert Mustacchi int sum_bytes = 0;
1342*4d9fdb46SRobert Mustacchi unsigned prolog_size = 0;
1343*4d9fdb46SRobert Mustacchi unsigned char *data = 0; /* holds disk form data */
1344*4d9fdb46SRobert Mustacchi int elfsectno = 0;
1345*4d9fdb46SRobert Mustacchi unsigned char *start_line_sec = 0; /* pointer to the buffer at
1346*4d9fdb46SRobert Mustacchi section start */
1347*4d9fdb46SRobert Mustacchi /* temps for memcpy */
1348*4d9fdb46SRobert Mustacchi Dwarf_Unsigned du = 0;
1349*4d9fdb46SRobert Mustacchi Dwarf_Ubyte db = 0;
1350*4d9fdb46SRobert Mustacchi Dwarf_Half dh = 0;
1351*4d9fdb46SRobert Mustacchi int res = 0;
1352*4d9fdb46SRobert Mustacchi Dwarf_Half version = dbg->de_output_version;
1353*4d9fdb46SRobert Mustacchi int offset_size = dbg->de_dwarf_offset_size;
1354*4d9fdb46SRobert Mustacchi Dwarf_Ubyte extension_size = dbg->de_64bit_extension ? 4 : 0;
1355*4d9fdb46SRobert Mustacchi Dwarf_Ubyte address_size = dbg->de_pointer_size;
1356*4d9fdb46SRobert Mustacchi
1357*4d9fdb46SRobert Mustacchi sum_bytes = 0;
1358*4d9fdb46SRobert Mustacchi
1359*4d9fdb46SRobert Mustacchi elfsectno = dbg->de_elf_sects[DEBUG_LINE];
1360*4d9fdb46SRobert Mustacchi
1361*4d9fdb46SRobert Mustacchi inits = &dbg->de_line_inits;
1362*4d9fdb46SRobert Mustacchi if (version < 5) {
1363*4d9fdb46SRobert Mustacchi res = calculate_size_of_line_header4(dbg,inits,&prolog_size,
1364*4d9fdb46SRobert Mustacchi error);
1365*4d9fdb46SRobert Mustacchi } else if (version == 5) {
1366*4d9fdb46SRobert Mustacchi res = calculate_size_of_line_header5(dbg,inits,&prolog_size,
1367*4d9fdb46SRobert Mustacchi error);
1368*4d9fdb46SRobert Mustacchi } else {
1369*4d9fdb46SRobert Mustacchi _dwarf_p_error(dbg, error,DW_DLE_VERSION_STAMP_ERROR );
1370*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
1371*4d9fdb46SRobert Mustacchi }
1372*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1373*4d9fdb46SRobert Mustacchi return res;
1374*4d9fdb46SRobert Mustacchi }
1375*4d9fdb46SRobert Mustacchi /* Allocate a chunk, put address in 'data' */
1376*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, elfsectno, data, prolog_size, error);
1377*4d9fdb46SRobert Mustacchi
1378bc1f688bSRobert Mustacchi start_line_sec = data;
1379bc1f688bSRobert Mustacchi
1380*4d9fdb46SRobert Mustacchi /* Copy the prologue data into 'data' */
1381bc1f688bSRobert Mustacchi /* total_length */
1382bc1f688bSRobert Mustacchi du = 0;
1383bc1f688bSRobert Mustacchi if (extension_size) {
1384*4d9fdb46SRobert Mustacchi DISTINGUISHED_VALUE_ARRAY(v4);
1385bc1f688bSRobert Mustacchi
1386*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0],
1387*4d9fdb46SRobert Mustacchi SIZEOFT32, extension_size);
1388bc1f688bSRobert Mustacchi data += extension_size;
1389bc1f688bSRobert Mustacchi }
1390bc1f688bSRobert Mustacchi
1391*4d9fdb46SRobert Mustacchi /* We will adjust this later, we do not know the full length
1392*4d9fdb46SRobert Mustacchi of the line_section content for this cu yet. */
1393bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
1394*4d9fdb46SRobert Mustacchi sizeof(du), offset_size);
1395*4d9fdb46SRobert Mustacchi data += offset_size;
1396bc1f688bSRobert Mustacchi
1397*4d9fdb46SRobert Mustacchi dh = inits->pi_linetable_version;
1398bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh,
1399*4d9fdb46SRobert Mustacchi sizeof(dh), DWARF_HALF_SIZE);
1400*4d9fdb46SRobert Mustacchi data += DWARF_HALF_SIZE;
1401*4d9fdb46SRobert Mustacchi if (version == 5 ) {
1402*4d9fdb46SRobert Mustacchi /* address size, seg sel size now */
1403*4d9fdb46SRobert Mustacchi db = inits->pi_address_size;
1404*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1405*4d9fdb46SRobert Mustacchi sizeof(db), sizeof(db));
1406*4d9fdb46SRobert Mustacchi data += sizeof(db);
1407*4d9fdb46SRobert Mustacchi db = inits->pi_segment_size; /* segment selector size */
1408*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1409*4d9fdb46SRobert Mustacchi sizeof(db), sizeof(db));
1410*4d9fdb46SRobert Mustacchi data += sizeof(db);
1411bc1f688bSRobert Mustacchi }
1412*4d9fdb46SRobert Mustacchi
1413*4d9fdb46SRobert Mustacchi {
1414*4d9fdb46SRobert Mustacchi /* header length (called prolog length in DWARF2)
1415*4d9fdb46SRobert Mustacchi This we do know, we calculated the prolog length
1416*4d9fdb46SRobert Mustacchi already and it is prolog_size so just
1417*4d9fdb46SRobert Mustacchi */
1418*4d9fdb46SRobert Mustacchi Dwarf_Unsigned sofar = data - start_line_sec;
1419*4d9fdb46SRobert Mustacchi
1420*4d9fdb46SRobert Mustacchi du = prolog_size - sofar - offset_size;
1421*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
1422*4d9fdb46SRobert Mustacchi sizeof(du), offset_size);
1423*4d9fdb46SRobert Mustacchi data += offset_size;
1424*4d9fdb46SRobert Mustacchi }
1425*4d9fdb46SRobert Mustacchi db = inits->pi_minimum_instruction_length;
1426bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1427bc1f688bSRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
1428bc1f688bSRobert Mustacchi data += sizeof(Dwarf_Ubyte);
1429*4d9fdb46SRobert Mustacchi
1430*4d9fdb46SRobert Mustacchi if (inits->pi_linetable_version == 4 ||
1431*4d9fdb46SRobert Mustacchi inits->pi_linetable_version == 5) {
1432*4d9fdb46SRobert Mustacchi db = inits->pi_maximum_operations_per_instruction;
1433bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1434bc1f688bSRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
1435bc1f688bSRobert Mustacchi data += sizeof(Dwarf_Ubyte);
1436*4d9fdb46SRobert Mustacchi }
1437*4d9fdb46SRobert Mustacchi
1438*4d9fdb46SRobert Mustacchi db = inits->pi_default_is_stmt;
1439bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1440bc1f688bSRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
1441bc1f688bSRobert Mustacchi data += sizeof(Dwarf_Ubyte);
1442*4d9fdb46SRobert Mustacchi db = inits->pi_line_base;
1443bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1444bc1f688bSRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
1445bc1f688bSRobert Mustacchi data += sizeof(Dwarf_Ubyte);
1446*4d9fdb46SRobert Mustacchi db = inits->pi_line_range;
1447*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1448*4d9fdb46SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
1449*4d9fdb46SRobert Mustacchi data += sizeof(Dwarf_Ubyte);
1450*4d9fdb46SRobert Mustacchi db = inits->pi_opcode_base;
1451bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1452bc1f688bSRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
1453bc1f688bSRobert Mustacchi data += sizeof(Dwarf_Ubyte);
1454bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len,
1455*4d9fdb46SRobert Mustacchi inits->pi_opcode_base-1,
1456*4d9fdb46SRobert Mustacchi inits->pi_opcode_base-1);
1457*4d9fdb46SRobert Mustacchi data += inits->pi_opcode_base-1;
1458bc1f688bSRobert Mustacchi
1459*4d9fdb46SRobert Mustacchi if (version < 5) {
1460bc1f688bSRobert Mustacchi /* copy over include directories */
1461bc1f688bSRobert Mustacchi curdir = dbg->de_inc_dirs;
1462bc1f688bSRobert Mustacchi while (curdir) {
1463*4d9fdb46SRobert Mustacchi strcpy((char *) data, curdir->dfe_name);
1464*4d9fdb46SRobert Mustacchi data += strlen(curdir->dfe_name) + 1;
1465*4d9fdb46SRobert Mustacchi curdir = curdir->dfe_next;
1466bc1f688bSRobert Mustacchi }
1467bc1f688bSRobert Mustacchi *data = '\0'; /* last null */
1468bc1f688bSRobert Mustacchi data++;
1469bc1f688bSRobert Mustacchi
1470bc1f688bSRobert Mustacchi /* copy file entries */
1471bc1f688bSRobert Mustacchi curentry = dbg->de_file_entries;
1472bc1f688bSRobert Mustacchi while (curentry) {
1473bc1f688bSRobert Mustacchi strcpy((char *) data, curentry->dfe_name);
1474bc1f688bSRobert Mustacchi data += strlen(curentry->dfe_name) + 1;
1475bc1f688bSRobert Mustacchi /* copies of leb numbers, no endian issues */
1476bc1f688bSRobert Mustacchi memcpy((void *) data,
1477bc1f688bSRobert Mustacchi (const void *) curentry->dfe_args, curentry->dfe_nbytes);
1478bc1f688bSRobert Mustacchi data += curentry->dfe_nbytes;
1479bc1f688bSRobert Mustacchi curentry = curentry->dfe_next;
1480bc1f688bSRobert Mustacchi }
1481bc1f688bSRobert Mustacchi *data = '\0';
1482bc1f688bSRobert Mustacchi data++;
1483*4d9fdb46SRobert Mustacchi } else if (version == 5) {
1484*4d9fdb46SRobert Mustacchi {
1485*4d9fdb46SRobert Mustacchi unsigned fsize = 0;
1486*4d9fdb46SRobert Mustacchi res = determine_form_size(dbg,
1487*4d9fdb46SRobert Mustacchi inits->pi_directory_entry_format_count,
1488*4d9fdb46SRobert Mustacchi inits->pi_incformats,
1489*4d9fdb46SRobert Mustacchi &fsize,
1490*4d9fdb46SRobert Mustacchi TRUE,data,
1491*4d9fdb46SRobert Mustacchi error);
1492*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1493*4d9fdb46SRobert Mustacchi return res;
1494*4d9fdb46SRobert Mustacchi }
1495*4d9fdb46SRobert Mustacchi data += fsize;
1496*4d9fdb46SRobert Mustacchi }
1497*4d9fdb46SRobert Mustacchi {
1498*4d9fdb46SRobert Mustacchi unsigned dir_count_len = 0;
1499*4d9fdb46SRobert Mustacchi res = determine_file_content_size(dbg,
1500*4d9fdb46SRobert Mustacchi dbg->de_inc_dirs,
1501*4d9fdb46SRobert Mustacchi inits->pi_directory_entry_format_count,
1502*4d9fdb46SRobert Mustacchi inits->pi_incformats,
1503*4d9fdb46SRobert Mustacchi &dir_count_len,
1504*4d9fdb46SRobert Mustacchi TRUE,data,
1505*4d9fdb46SRobert Mustacchi error);
1506*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1507*4d9fdb46SRobert Mustacchi return res;
1508*4d9fdb46SRobert Mustacchi }
1509*4d9fdb46SRobert Mustacchi data += dir_count_len;
1510*4d9fdb46SRobert Mustacchi }
1511*4d9fdb46SRobert Mustacchi {
1512*4d9fdb46SRobert Mustacchi unsigned fsize = 0;
1513*4d9fdb46SRobert Mustacchi res = determine_form_size(dbg,
1514*4d9fdb46SRobert Mustacchi inits->pi_file_entry_format_count,
1515*4d9fdb46SRobert Mustacchi inits->pi_fileformats,
1516*4d9fdb46SRobert Mustacchi &fsize,
1517*4d9fdb46SRobert Mustacchi TRUE,data,
1518*4d9fdb46SRobert Mustacchi error);
1519*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1520*4d9fdb46SRobert Mustacchi return res;
1521*4d9fdb46SRobert Mustacchi }
1522*4d9fdb46SRobert Mustacchi data += fsize;
1523*4d9fdb46SRobert Mustacchi }
1524*4d9fdb46SRobert Mustacchi {
1525*4d9fdb46SRobert Mustacchi unsigned file_count_len = 0;
1526*4d9fdb46SRobert Mustacchi res = determine_file_content_size(dbg,
1527*4d9fdb46SRobert Mustacchi dbg->de_file_entries,
1528*4d9fdb46SRobert Mustacchi dbg->de_line_inits.pi_file_entry_format_count,
1529*4d9fdb46SRobert Mustacchi dbg->de_line_inits.pi_fileformats,
1530*4d9fdb46SRobert Mustacchi &file_count_len,
1531*4d9fdb46SRobert Mustacchi TRUE,data,
1532*4d9fdb46SRobert Mustacchi error);
1533*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1534*4d9fdb46SRobert Mustacchi return res;
1535*4d9fdb46SRobert Mustacchi }
1536*4d9fdb46SRobert Mustacchi data += file_count_len;
1537*4d9fdb46SRobert Mustacchi }
1538*4d9fdb46SRobert Mustacchi }
1539bc1f688bSRobert Mustacchi
1540*4d9fdb46SRobert Mustacchi {
1541*4d9fdb46SRobert Mustacchi Dwarf_Unsigned sofar = data - start_line_sec;
1542*4d9fdb46SRobert Mustacchi if (sofar != prolog_size) {
1543*4d9fdb46SRobert Mustacchi /* We miscalculated something. */
1544*4d9fdb46SRobert Mustacchi _dwarf_p_error(dbg, error,
1545*4d9fdb46SRobert Mustacchi DW_DLE_LINE_HEADER_LENGTH_BOTCH);
1546*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
1547*4d9fdb46SRobert Mustacchi }
1548bc1f688bSRobert Mustacchi sum_bytes += prolog_size;
1549*4d9fdb46SRobert Mustacchi }
1550bc1f688bSRobert Mustacchi
1551bc1f688bSRobert Mustacchi curline = dbg->de_lines;
1552bc1f688bSRobert Mustacchi prevline = (Dwarf_P_Line)
1553bc1f688bSRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
1554bc1f688bSRobert Mustacchi if (prevline == NULL) {
1555*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR);
1556bc1f688bSRobert Mustacchi }
1557*4d9fdb46SRobert Mustacchi _dwarf_pro_reg_init(dbg,prevline);
1558bc1f688bSRobert Mustacchi /* generate opcodes for line numbers */
1559bc1f688bSRobert Mustacchi while (curline) {
1560*4d9fdb46SRobert Mustacchi int opc = 0;
1561*4d9fdb46SRobert Mustacchi int no_lns_copy = 0; /* if lns copy opcode does not need to be
1562bc1f688bSRobert Mustacchi generated, if special opcode or end
1563bc1f688bSRobert Mustacchi sequence */
1564*4d9fdb46SRobert Mustacchi Dwarf_Unsigned addr_adv = 0;
1565*4d9fdb46SRobert Mustacchi int line_adv = 0; /* supposed to be a reasonably small
1566bc1f688bSRobert Mustacchi number, so the size should not be a
1567bc1f688bSRobert Mustacchi problem. ? */
1568bc1f688bSRobert Mustacchi
1569bc1f688bSRobert Mustacchi no_lns_copy = 0;
1570bc1f688bSRobert Mustacchi if (curline->dpl_opc != 0) {
1571*4d9fdb46SRobert Mustacchi int inst_bytes = 0; /* no of bytes in extended opcode */
1572*4d9fdb46SRobert Mustacchi unsigned writelen = 0;
1573bc1f688bSRobert Mustacchi
1574bc1f688bSRobert Mustacchi switch (curline->dpl_opc) {
1575bc1f688bSRobert Mustacchi case DW_LNE_end_sequence:
1576bc1f688bSRobert Mustacchi /* Advance pc to end of text section. */
1577bc1f688bSRobert Mustacchi addr_adv = curline->dpl_address - prevline->dpl_address;
1578bc1f688bSRobert Mustacchi if (addr_adv > 0) {
1579*4d9fdb46SRobert Mustacchi res = write_opcode_uval(DW_LNS_advance_pc,dbg,
1580*4d9fdb46SRobert Mustacchi elfsectno,
1581*4d9fdb46SRobert Mustacchi addr_adv/inits->pi_minimum_instruction_length,
1582*4d9fdb46SRobert Mustacchi &writelen,
1583*4d9fdb46SRobert Mustacchi error);
1584bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
1585*4d9fdb46SRobert Mustacchi return res;
1586bc1f688bSRobert Mustacchi }
1587*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1588bc1f688bSRobert Mustacchi prevline->dpl_address = curline->dpl_address;
1589bc1f688bSRobert Mustacchi }
1590bc1f688bSRobert Mustacchi
1591bc1f688bSRobert Mustacchi /* first null byte */
1592bc1f688bSRobert Mustacchi db = 0;
1593*4d9fdb46SRobert Mustacchi res = write_ubyte(db,dbg,elfsectno,
1594*4d9fdb46SRobert Mustacchi &writelen,error);
1595*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1596*4d9fdb46SRobert Mustacchi return res;
1597*4d9fdb46SRobert Mustacchi }
1598*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1599bc1f688bSRobert Mustacchi
1600bc1f688bSRobert Mustacchi /* write length of extended opcode */
1601bc1f688bSRobert Mustacchi inst_bytes = sizeof(Dwarf_Ubyte);
1602*4d9fdb46SRobert Mustacchi res = write_uval(inst_bytes,dbg,elfsectno,
1603*4d9fdb46SRobert Mustacchi &writelen,error);
1604bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
1605*4d9fdb46SRobert Mustacchi return res;
1606bc1f688bSRobert Mustacchi }
1607*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1608bc1f688bSRobert Mustacchi
1609bc1f688bSRobert Mustacchi /* write extended opcode */
1610*4d9fdb46SRobert Mustacchi res = write_ubyte(DW_LNE_end_sequence,dbg,elfsectno,
1611*4d9fdb46SRobert Mustacchi &writelen,error);
1612*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1613*4d9fdb46SRobert Mustacchi return res;
1614*4d9fdb46SRobert Mustacchi }
1615*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1616*4d9fdb46SRobert Mustacchi
1617bc1f688bSRobert Mustacchi /* reset value to original values */
1618*4d9fdb46SRobert Mustacchi _dwarf_pro_reg_init(dbg,prevline);
1619bc1f688bSRobert Mustacchi no_lns_copy = 1;
1620bc1f688bSRobert Mustacchi /* this is set only for end_sequence, so that a
1621bc1f688bSRobert Mustacchi dw_lns_copy is not generated */
1622bc1f688bSRobert Mustacchi break;
1623bc1f688bSRobert Mustacchi
1624bc1f688bSRobert Mustacchi case DW_LNE_set_address:
1625bc1f688bSRobert Mustacchi
1626bc1f688bSRobert Mustacchi /* first null byte */
1627bc1f688bSRobert Mustacchi db = 0;
1628*4d9fdb46SRobert Mustacchi res = write_ubyte(db,dbg,elfsectno,
1629*4d9fdb46SRobert Mustacchi &writelen,error);
1630*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1631*4d9fdb46SRobert Mustacchi return res;
1632*4d9fdb46SRobert Mustacchi }
1633*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1634bc1f688bSRobert Mustacchi
1635bc1f688bSRobert Mustacchi /* write length of extended opcode */
1636*4d9fdb46SRobert Mustacchi inst_bytes = sizeof(Dwarf_Ubyte) + address_size;
1637*4d9fdb46SRobert Mustacchi res = write_uval(inst_bytes,dbg,elfsectno,
1638*4d9fdb46SRobert Mustacchi &writelen,error);
1639bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
1640*4d9fdb46SRobert Mustacchi return res;
1641bc1f688bSRobert Mustacchi }
1642*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1643bc1f688bSRobert Mustacchi
1644bc1f688bSRobert Mustacchi /* write extended opcode */
1645*4d9fdb46SRobert Mustacchi res = write_ubyte(DW_LNE_set_address,dbg,elfsectno,
1646*4d9fdb46SRobert Mustacchi &writelen,error);
1647*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1648*4d9fdb46SRobert Mustacchi return res;
1649*4d9fdb46SRobert Mustacchi }
1650*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1651bc1f688bSRobert Mustacchi
1652bc1f688bSRobert Mustacchi /* reloc for address */
1653*4d9fdb46SRobert Mustacchi res = dbg->de_relocate_by_name_symbol(dbg,
1654*4d9fdb46SRobert Mustacchi DEBUG_LINE,
1655bc1f688bSRobert Mustacchi sum_bytes, /* r_offset */
1656bc1f688bSRobert Mustacchi curline->dpl_r_symidx,
1657bc1f688bSRobert Mustacchi dwarf_drt_data_reloc,
1658*4d9fdb46SRobert Mustacchi offset_size);
1659bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
1660*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, DW_DLV_ERROR);
1661bc1f688bSRobert Mustacchi }
1662bc1f688bSRobert Mustacchi
1663bc1f688bSRobert Mustacchi /* write offset (address) */
1664bc1f688bSRobert Mustacchi du = curline->dpl_address;
1665*4d9fdb46SRobert Mustacchi res = write_fixed_size(du,dbg,elfsectno,
1666*4d9fdb46SRobert Mustacchi address_size,&writelen,error);
1667*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1668*4d9fdb46SRobert Mustacchi return res;
1669*4d9fdb46SRobert Mustacchi }
1670*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1671bc1f688bSRobert Mustacchi prevline->dpl_address = curline->dpl_address;
1672bc1f688bSRobert Mustacchi no_lns_copy = 1;
1673bc1f688bSRobert Mustacchi break;
1674*4d9fdb46SRobert Mustacchi case DW_LNE_define_file:
1675*4d9fdb46SRobert Mustacchi /* Not supported, all add-file entries
1676*4d9fdb46SRobert Mustacchi are added via dbg -> de_file_entries,
1677*4d9fdb46SRobert Mustacchi which adds to the line table header. */
1678*4d9fdb46SRobert Mustacchi no_lns_copy = 1;
1679*4d9fdb46SRobert Mustacchi break;
1680*4d9fdb46SRobert Mustacchi case DW_LNE_set_discriminator: {/* DWARF4 */
1681*4d9fdb46SRobert Mustacchi unsigned val_len = 0;
1682*4d9fdb46SRobert Mustacchi /* first null byte */
1683*4d9fdb46SRobert Mustacchi db = 0;
1684*4d9fdb46SRobert Mustacchi res = write_ubyte(db,dbg,elfsectno,&writelen,error);
1685*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1686*4d9fdb46SRobert Mustacchi return res;
1687*4d9fdb46SRobert Mustacchi }
1688*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1689*4d9fdb46SRobert Mustacchi
1690*4d9fdb46SRobert Mustacchi /* Write len of opcode + value here. */
1691*4d9fdb46SRobert Mustacchi res = pretend_write_uval(curline->dpl_discriminator,
1692*4d9fdb46SRobert Mustacchi dbg, &val_len,error);
1693*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1694*4d9fdb46SRobert Mustacchi return res;
1695*4d9fdb46SRobert Mustacchi }
1696*4d9fdb46SRobert Mustacchi val_len++;
1697*4d9fdb46SRobert Mustacchi
1698*4d9fdb46SRobert Mustacchi res = write_uval(val_len +1,dbg,elfsectno,
1699*4d9fdb46SRobert Mustacchi &writelen,error);
1700*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1701*4d9fdb46SRobert Mustacchi return res;
1702*4d9fdb46SRobert Mustacchi }
1703*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1704*4d9fdb46SRobert Mustacchi
1705*4d9fdb46SRobert Mustacchi /* Write opcode */
1706*4d9fdb46SRobert Mustacchi res = write_ubyte(DW_LNE_set_discriminator,
1707*4d9fdb46SRobert Mustacchi dbg,elfsectno,
1708*4d9fdb46SRobert Mustacchi &writelen,error);
1709*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1710*4d9fdb46SRobert Mustacchi return res;
1711*4d9fdb46SRobert Mustacchi }
1712*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1713*4d9fdb46SRobert Mustacchi
1714*4d9fdb46SRobert Mustacchi /* Write the value itself. */
1715*4d9fdb46SRobert Mustacchi res = write_uval(curline->dpl_discriminator,
1716*4d9fdb46SRobert Mustacchi dbg,elfsectno,&writelen,error);
1717*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1718*4d9fdb46SRobert Mustacchi return res;
1719*4d9fdb46SRobert Mustacchi }
1720*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1721*4d9fdb46SRobert Mustacchi no_lns_copy = 1;
1722*4d9fdb46SRobert Mustacchi }
1723*4d9fdb46SRobert Mustacchi break;
1724bc1f688bSRobert Mustacchi }
1725bc1f688bSRobert Mustacchi } else {
1726*4d9fdb46SRobert Mustacchi unsigned writelen = 0;
1727*4d9fdb46SRobert Mustacchi if (inits->pi_opcode_base >12) {
1728*4d9fdb46SRobert Mustacchi /* We have the newer standard opcodes
1729*4d9fdb46SRobert Mustacchi DW_LNS_set_prologue_end, DW_LNS_set_epilogue_end,
1730*4d9fdb46SRobert Mustacchi DW_LNS_set_isa, we do not write them if not
1731*4d9fdb46SRobert Mustacchi in the table. DWARF3 and DWARF4 */
1732*4d9fdb46SRobert Mustacchi /* Should we check if a change? These reset automatically
1733*4d9fdb46SRobert Mustacchi in the line processing/reading engine,
1734*4d9fdb46SRobert Mustacchi so I think no check of prevline is wanted. */
1735*4d9fdb46SRobert Mustacchi if (curline->dpl_epilogue_begin) {
1736*4d9fdb46SRobert Mustacchi res = write_ubyte(DW_LNS_set_epilogue_begin,dbg,
1737*4d9fdb46SRobert Mustacchi elfsectno,&writelen, error);
1738*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1739*4d9fdb46SRobert Mustacchi return res;
1740*4d9fdb46SRobert Mustacchi }
1741*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1742*4d9fdb46SRobert Mustacchi }
1743*4d9fdb46SRobert Mustacchi if (curline->dpl_prologue_end) {
1744*4d9fdb46SRobert Mustacchi res = write_ubyte(DW_LNS_set_prologue_end,dbg,
1745*4d9fdb46SRobert Mustacchi elfsectno, &writelen,error);
1746*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1747*4d9fdb46SRobert Mustacchi return res;
1748*4d9fdb46SRobert Mustacchi }
1749*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1750*4d9fdb46SRobert Mustacchi }
1751*4d9fdb46SRobert Mustacchi if (curline->dpl_isa != prevline->dpl_isa) {
1752*4d9fdb46SRobert Mustacchi res = write_opcode_uval(DW_LNS_set_isa,dbg,
1753*4d9fdb46SRobert Mustacchi elfsectno, curline->dpl_isa,
1754*4d9fdb46SRobert Mustacchi &writelen ,error);
1755*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1756*4d9fdb46SRobert Mustacchi return res;
1757*4d9fdb46SRobert Mustacchi }
1758*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1759*4d9fdb46SRobert Mustacchi }
1760*4d9fdb46SRobert Mustacchi }
1761bc1f688bSRobert Mustacchi if (curline->dpl_file != prevline->dpl_file) {
1762bc1f688bSRobert Mustacchi db = DW_LNS_set_file;
1763*4d9fdb46SRobert Mustacchi res = write_opcode_uval(db,dbg,
1764*4d9fdb46SRobert Mustacchi elfsectno,
1765*4d9fdb46SRobert Mustacchi curline->dpl_file,&writelen ,error);
1766bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
1767*4d9fdb46SRobert Mustacchi return res;
1768bc1f688bSRobert Mustacchi }
1769*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1770*4d9fdb46SRobert Mustacchi
1771bc1f688bSRobert Mustacchi prevline->dpl_file = curline->dpl_file;
1772bc1f688bSRobert Mustacchi }
1773bc1f688bSRobert Mustacchi if (curline->dpl_column != prevline->dpl_column) {
1774bc1f688bSRobert Mustacchi db = DW_LNS_set_column;
1775*4d9fdb46SRobert Mustacchi res = write_opcode_uval(db,dbg,
1776*4d9fdb46SRobert Mustacchi elfsectno, curline->dpl_column , &writelen,error);
1777bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
1778*4d9fdb46SRobert Mustacchi return res;
1779bc1f688bSRobert Mustacchi }
1780*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1781bc1f688bSRobert Mustacchi prevline->dpl_column = curline->dpl_column;
1782bc1f688bSRobert Mustacchi }
1783bc1f688bSRobert Mustacchi if (curline->dpl_is_stmt != prevline->dpl_is_stmt) {
1784*4d9fdb46SRobert Mustacchi res = write_ubyte(DW_LNS_negate_stmt,dbg,elfsectno,
1785*4d9fdb46SRobert Mustacchi &writelen,error);
1786*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1787*4d9fdb46SRobert Mustacchi return res;
1788*4d9fdb46SRobert Mustacchi }
1789*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1790bc1f688bSRobert Mustacchi prevline->dpl_is_stmt = curline->dpl_is_stmt;
1791bc1f688bSRobert Mustacchi }
1792bc1f688bSRobert Mustacchi if (curline->dpl_basic_block == true &&
1793bc1f688bSRobert Mustacchi prevline->dpl_basic_block == false) {
1794*4d9fdb46SRobert Mustacchi res = write_ubyte(DW_LNS_set_basic_block,dbg,
1795*4d9fdb46SRobert Mustacchi elfsectno,&writelen,error);
1796*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1797*4d9fdb46SRobert Mustacchi return res;
1798*4d9fdb46SRobert Mustacchi }
1799*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1800bc1f688bSRobert Mustacchi prevline->dpl_basic_block = curline->dpl_basic_block;
1801bc1f688bSRobert Mustacchi }
1802*4d9fdb46SRobert Mustacchi if (curline->dpl_discriminator) {
1803*4d9fdb46SRobert Mustacchi /* This is dwarf4, but because it is an extended op
1804*4d9fdb46SRobert Mustacchi not a standard op,
1805*4d9fdb46SRobert Mustacchi we allow it without testing version.
1806*4d9fdb46SRobert Mustacchi GNU seems to set this from time to time. */
1807*4d9fdb46SRobert Mustacchi unsigned val_len = 0;
1808*4d9fdb46SRobert Mustacchi /* first null byte */
1809*4d9fdb46SRobert Mustacchi db = 0;
1810*4d9fdb46SRobert Mustacchi res = write_ubyte(db,dbg,elfsectno,&writelen,error);
1811*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1812*4d9fdb46SRobert Mustacchi return res;
1813*4d9fdb46SRobert Mustacchi }
1814*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1815*4d9fdb46SRobert Mustacchi
1816*4d9fdb46SRobert Mustacchi /* Write len of opcode + value here. */
1817*4d9fdb46SRobert Mustacchi res = pretend_write_uval(curline->dpl_discriminator,
1818*4d9fdb46SRobert Mustacchi dbg, &val_len,error);
1819*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1820*4d9fdb46SRobert Mustacchi return res;
1821*4d9fdb46SRobert Mustacchi }
1822*4d9fdb46SRobert Mustacchi val_len ++;
1823*4d9fdb46SRobert Mustacchi res = write_uval(val_len +1,dbg,elfsectno,
1824*4d9fdb46SRobert Mustacchi &writelen,error);
1825*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1826*4d9fdb46SRobert Mustacchi return res;
1827*4d9fdb46SRobert Mustacchi }
1828*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1829*4d9fdb46SRobert Mustacchi
1830*4d9fdb46SRobert Mustacchi /* Write opcode */
1831*4d9fdb46SRobert Mustacchi res = write_ubyte(DW_LNE_set_discriminator,
1832*4d9fdb46SRobert Mustacchi dbg,elfsectno,&writelen,error);
1833*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1834*4d9fdb46SRobert Mustacchi return res;
1835*4d9fdb46SRobert Mustacchi }
1836*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1837*4d9fdb46SRobert Mustacchi
1838*4d9fdb46SRobert Mustacchi /* Write the value itself. */
1839*4d9fdb46SRobert Mustacchi res = write_uval(curline->dpl_discriminator,
1840*4d9fdb46SRobert Mustacchi dbg,elfsectno,&writelen,error);
1841*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1842*4d9fdb46SRobert Mustacchi return res;
1843*4d9fdb46SRobert Mustacchi }
1844*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1845*4d9fdb46SRobert Mustacchi }
1846*4d9fdb46SRobert Mustacchi
1847bc1f688bSRobert Mustacchi addr_adv = curline->dpl_address - prevline->dpl_address;
1848bc1f688bSRobert Mustacchi
1849bc1f688bSRobert Mustacchi line_adv = (int) (curline->dpl_line - prevline->dpl_line);
1850bc1f688bSRobert Mustacchi if ((addr_adv % MIN_INST_LENGTH) != 0) {
1851*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, DW_DLV_ERROR);
1852bc1f688bSRobert Mustacchi }
1853*4d9fdb46SRobert Mustacchi opc = _dwarf_pro_get_opc(inits,addr_adv, line_adv);
1854*4d9fdb46SRobert Mustacchi if (opc > 0) {
1855*4d9fdb46SRobert Mustacchi /* Use special opcode. */
1856bc1f688bSRobert Mustacchi no_lns_copy = 1;
1857*4d9fdb46SRobert Mustacchi res = write_ubyte(opc,dbg,elfsectno,&writelen,error);
1858*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1859*4d9fdb46SRobert Mustacchi return res;
1860*4d9fdb46SRobert Mustacchi }
1861*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1862bc1f688bSRobert Mustacchi prevline->dpl_basic_block = false;
1863bc1f688bSRobert Mustacchi prevline->dpl_address = curline->dpl_address;
1864bc1f688bSRobert Mustacchi prevline->dpl_line = curline->dpl_line;
1865bc1f688bSRobert Mustacchi } else {
1866*4d9fdb46SRobert Mustacchi /* opc says use standard opcodes. */
1867bc1f688bSRobert Mustacchi if (addr_adv > 0) {
1868bc1f688bSRobert Mustacchi db = DW_LNS_advance_pc;
1869*4d9fdb46SRobert Mustacchi res = write_opcode_uval(db,dbg,
1870*4d9fdb46SRobert Mustacchi elfsectno,
1871*4d9fdb46SRobert Mustacchi addr_adv/inits->pi_minimum_instruction_length,
1872*4d9fdb46SRobert Mustacchi &writelen,
1873*4d9fdb46SRobert Mustacchi error);
1874bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
1875*4d9fdb46SRobert Mustacchi return res;
1876bc1f688bSRobert Mustacchi }
1877*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1878bc1f688bSRobert Mustacchi prevline->dpl_basic_block = false;
1879bc1f688bSRobert Mustacchi prevline->dpl_address = curline->dpl_address;
1880bc1f688bSRobert Mustacchi }
1881bc1f688bSRobert Mustacchi if (line_adv != 0) {
1882bc1f688bSRobert Mustacchi db = DW_LNS_advance_line;
1883*4d9fdb46SRobert Mustacchi res = write_ubyte(db,dbg,
1884*4d9fdb46SRobert Mustacchi elfsectno,
1885*4d9fdb46SRobert Mustacchi &writelen,
1886*4d9fdb46SRobert Mustacchi error);
1887bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
1888*4d9fdb46SRobert Mustacchi return res;
1889bc1f688bSRobert Mustacchi }
1890*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1891*4d9fdb46SRobert Mustacchi res = write_sval(line_adv,dbg,
1892*4d9fdb46SRobert Mustacchi elfsectno,
1893*4d9fdb46SRobert Mustacchi &writelen,
1894*4d9fdb46SRobert Mustacchi error);
1895*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1896*4d9fdb46SRobert Mustacchi return res;
1897*4d9fdb46SRobert Mustacchi }
1898*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1899bc1f688bSRobert Mustacchi prevline->dpl_basic_block = false;
1900bc1f688bSRobert Mustacchi prevline->dpl_line = curline->dpl_line;
1901bc1f688bSRobert Mustacchi }
1902bc1f688bSRobert Mustacchi }
1903*4d9fdb46SRobert Mustacchi } /* ends else for opc <= 0 */
1904bc1f688bSRobert Mustacchi if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq
1905bc1f688bSRobert Mustacchi generate a matrix line */
1906*4d9fdb46SRobert Mustacchi unsigned writelen = 0;
1907*4d9fdb46SRobert Mustacchi res = write_ubyte(DW_LNS_copy,dbg,elfsectno,&writelen,error);
1908*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
1909*4d9fdb46SRobert Mustacchi return res;
1910*4d9fdb46SRobert Mustacchi }
1911*4d9fdb46SRobert Mustacchi sum_bytes += writelen;
1912bc1f688bSRobert Mustacchi prevline->dpl_basic_block = false;
1913bc1f688bSRobert Mustacchi }
1914bc1f688bSRobert Mustacchi curline = curline->dpl_next;
1915bc1f688bSRobert Mustacchi }
1916bc1f688bSRobert Mustacchi
1917bc1f688bSRobert Mustacchi /* write total length field */
1918*4d9fdb46SRobert Mustacchi du = sum_bytes - OFFSET_PLUS_EXTENSION_SIZE;
1919bc1f688bSRobert Mustacchi {
1920bc1f688bSRobert Mustacchi start_line_sec += extension_size;
1921bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) start_line_sec,
1922*4d9fdb46SRobert Mustacchi (const void *) &du, sizeof(du), offset_size);
1923bc1f688bSRobert Mustacchi }
1924bc1f688bSRobert Mustacchi
1925*4d9fdb46SRobert Mustacchi *nbufs = dbg->de_n_debug_sect;
1926*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
1927bc1f688bSRobert Mustacchi }
1928bc1f688bSRobert Mustacchi
1929*4d9fdb46SRobert Mustacchi /*
1930*4d9fdb46SRobert Mustacchi Generate debug_frame section */
1931bc1f688bSRobert Mustacchi static int
_dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)1932*4d9fdb46SRobert Mustacchi _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
1933*4d9fdb46SRobert Mustacchi Dwarf_Signed *nbufs,
1934*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
1935bc1f688bSRobert Mustacchi {
1936bc1f688bSRobert Mustacchi int elfsectno = 0;
1937bc1f688bSRobert Mustacchi int i = 0;
1938bc1f688bSRobert Mustacchi int firsttime = 1;
1939bc1f688bSRobert Mustacchi Dwarf_P_Cie curcie = 0;
1940bc1f688bSRobert Mustacchi Dwarf_P_Fde curfde = 0;
1941bc1f688bSRobert Mustacchi unsigned char *data = 0;
1942bc1f688bSRobert Mustacchi Dwarf_Unsigned du = 0;
1943bc1f688bSRobert Mustacchi Dwarf_Ubyte db = 0;
1944bc1f688bSRobert Mustacchi long *cie_offs = 0; /* Holds byte offsets for links to fde's */
1945bc1f688bSRobert Mustacchi unsigned long cie_length = 0;
1946bc1f688bSRobert Mustacchi int cie_no = 0;
1947*4d9fdb46SRobert Mustacchi Dwarf_Ubyte offset_size = dbg->de_dwarf_offset_size;
1948*4d9fdb46SRobert Mustacchi Dwarf_Ubyte extension_size = dbg->de_64bit_extension ? 4 : 0;
1949*4d9fdb46SRobert Mustacchi Dwarf_Ubyte address_size = dbg->de_pointer_size;
1950bc1f688bSRobert Mustacchi Dwarf_Unsigned cur_off = 0; /* current offset of written data, held
1951bc1f688bSRobert Mustacchi for relocation info */
1952bc1f688bSRobert Mustacchi
1953bc1f688bSRobert Mustacchi elfsectno = dbg->de_elf_sects[DEBUG_FRAME];
1954bc1f688bSRobert Mustacchi
1955bc1f688bSRobert Mustacchi curcie = dbg->de_frame_cies;
1956bc1f688bSRobert Mustacchi cie_length = 0;
1957bc1f688bSRobert Mustacchi cie_offs = (long *)
1958bc1f688bSRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie);
1959bc1f688bSRobert Mustacchi if (cie_offs == NULL) {
1960*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR);
1961bc1f688bSRobert Mustacchi }
1962bc1f688bSRobert Mustacchi /* Generate cie number as we go along. This writes
1963bc1f688bSRobert Mustacchi all CIEs first before any FDEs, which is rather
1964bc1f688bSRobert Mustacchi different from the order a compiler might like (which
1965bc1f688bSRobert Mustacchi might be each CIE followed by its FDEs then the next CIE, and
1966bc1f688bSRobert Mustacchi so on). */
1967bc1f688bSRobert Mustacchi cie_no = 1;
1968bc1f688bSRobert Mustacchi while (curcie) {
1969bc1f688bSRobert Mustacchi char *code_al = 0;
1970*4d9fdb46SRobert Mustacchi int codeal_bytes = 0;
1971bc1f688bSRobert Mustacchi char *data_al = 0;
1972*4d9fdb46SRobert Mustacchi int data_align_bytes = 0;
1973*4d9fdb46SRobert Mustacchi int pad = 0; /* Pad for padding to align cies and fdes */
1974bc1f688bSRobert Mustacchi int res = 0;
1975bc1f688bSRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED];
1976bc1f688bSRobert Mustacchi char buff2[ENCODE_SPACE_NEEDED];
1977bc1f688bSRobert Mustacchi char buff3[ENCODE_SPACE_NEEDED];
1978bc1f688bSRobert Mustacchi char *augmentation = 0;
1979bc1f688bSRobert Mustacchi char *augmented_al = 0;
1980bc1f688bSRobert Mustacchi long augmented_fields_length = 0;
1981*4d9fdb46SRobert Mustacchi int irix_auglen_v0 = 0;
1982*4d9fdb46SRobert Mustacchi Dwarf_Half version = curcie->cie_version;
1983bc1f688bSRobert Mustacchi
1984bc1f688bSRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align,
1985*4d9fdb46SRobert Mustacchi &codeal_bytes,
1986bc1f688bSRobert Mustacchi buff1, sizeof(buff1));
1987bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
1988*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR);
1989bc1f688bSRobert Mustacchi }
1990bc1f688bSRobert Mustacchi /* Before April 1999, the following was using an unsigned
1991bc1f688bSRobert Mustacchi encode. That worked ok even though the decoder used the
1992bc1f688bSRobert Mustacchi correct signed leb read, but doing the encode correctly
1993bc1f688bSRobert Mustacchi (according to the dwarf spec) saves space in the output file
1994bc1f688bSRobert Mustacchi and is completely compatible.
1995bc1f688bSRobert Mustacchi
1996bc1f688bSRobert Mustacchi Note the actual stored amount on MIPS was 10 bytes (!) to
1997bc1f688bSRobert Mustacchi store the value -4. (hex)fc ffffffff ffffffff 01 The
1998bc1f688bSRobert Mustacchi libdwarf consumer consumed all 10 bytes too!
1999bc1f688bSRobert Mustacchi
2000bc1f688bSRobert Mustacchi old version res =
2001bc1f688bSRobert Mustacchi _dwarf_pro_encode_leb128_nm(curcie->cie_data_align,
2002bc1f688bSRobert Mustacchi
2003bc1f688bSRobert Mustacchi below is corrected signed version. */
2004bc1f688bSRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align,
2005*4d9fdb46SRobert Mustacchi &data_align_bytes,
2006bc1f688bSRobert Mustacchi buff2, sizeof(buff2));
2007bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
2008*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR);
2009bc1f688bSRobert Mustacchi }
2010bc1f688bSRobert Mustacchi code_al = buff1;
2011bc1f688bSRobert Mustacchi data_al = buff2;
2012bc1f688bSRobert Mustacchi
2013bc1f688bSRobert Mustacchi /* get the correct offset */
2014bc1f688bSRobert Mustacchi if (firsttime) {
2015bc1f688bSRobert Mustacchi cie_offs[cie_no - 1] = 0;
2016bc1f688bSRobert Mustacchi firsttime = 0;
2017bc1f688bSRobert Mustacchi } else {
2018bc1f688bSRobert Mustacchi cie_offs[cie_no - 1] = cie_offs[cie_no - 2] +
2019*4d9fdb46SRobert Mustacchi (long) cie_length + OFFSET_PLUS_EXTENSION_SIZE;
2020bc1f688bSRobert Mustacchi }
2021bc1f688bSRobert Mustacchi cie_no++;
2022bc1f688bSRobert Mustacchi augmentation = curcie->cie_aug;
2023*4d9fdb46SRobert Mustacchi cie_length = offset_size + /* cie_id */
2024*4d9fdb46SRobert Mustacchi sizeof(Dwarf_Ubyte) + /* cie version */
2025*4d9fdb46SRobert Mustacchi strlen(curcie->cie_aug) + 1 + /* augmentation */
2026*4d9fdb46SRobert Mustacchi codeal_bytes + /* code alignment factor */
2027*4d9fdb46SRobert Mustacchi data_align_bytes + /* data alignment factor */
2028*4d9fdb46SRobert Mustacchi sizeof(Dwarf_Ubyte) + /* return reg address */
2029*4d9fdb46SRobert Mustacchi curcie->cie_inst_bytes;
2030*4d9fdb46SRobert Mustacchi if (dbg->de_irix_exc_augmentation &&
2031*4d9fdb46SRobert Mustacchi (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0)) {
2032*4d9fdb46SRobert Mustacchi
2033*4d9fdb46SRobert Mustacchi /* IRIX specific. */
2034bc1f688bSRobert Mustacchi augmented_fields_length = 0;
2035bc1f688bSRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(augmented_fields_length,
2036*4d9fdb46SRobert Mustacchi &irix_auglen_v0, buff3,
2037bc1f688bSRobert Mustacchi sizeof(buff3));
2038bc1f688bSRobert Mustacchi augmented_al = buff3;
2039bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
2040*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC,
2041*4d9fdb46SRobert Mustacchi DW_DLV_ERROR);
2042bc1f688bSRobert Mustacchi }
2043*4d9fdb46SRobert Mustacchi cie_length += irix_auglen_v0 ; /* augmentation length */
2044bc1f688bSRobert Mustacchi }
2045*4d9fdb46SRobert Mustacchi if (version >= 4) {
2046*4d9fdb46SRobert Mustacchi /* address size, segment selector size */
2047*4d9fdb46SRobert Mustacchi cie_length += 1 +1;
2048*4d9fdb46SRobert Mustacchi }
2049*4d9fdb46SRobert Mustacchi
2050*4d9fdb46SRobert Mustacchi pad = (int) PADDING(cie_length, address_size);
2051bc1f688bSRobert Mustacchi cie_length += pad;
2052*4d9fdb46SRobert Mustacchi
2053*4d9fdb46SRobert Mustacchi /* Now we have the cie length with padding,
2054*4d9fdb46SRobert Mustacchi allocate a buffer for that plus the header
2055*4d9fdb46SRobert Mustacchi length. */
2056*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, elfsectno, data, cie_length +
2057*4d9fdb46SRobert Mustacchi OFFSET_PLUS_EXTENSION_SIZE,
2058*4d9fdb46SRobert Mustacchi error);
2059bc1f688bSRobert Mustacchi if (extension_size) {
2060*4d9fdb46SRobert Mustacchi DISTINGUISHED_VALUE_ARRAY(v4);
2061bc1f688bSRobert Mustacchi
2062bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2063*4d9fdb46SRobert Mustacchi (const void *) &v4[0],
2064*4d9fdb46SRobert Mustacchi SIZEOFT32, extension_size);
2065bc1f688bSRobert Mustacchi data += extension_size;
2066bc1f688bSRobert Mustacchi
2067bc1f688bSRobert Mustacchi }
2068bc1f688bSRobert Mustacchi du = cie_length;
2069bc1f688bSRobert Mustacchi /* total length of cie */
2070bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2071*4d9fdb46SRobert Mustacchi (const void *) &du, sizeof(du), offset_size);
2072*4d9fdb46SRobert Mustacchi data += offset_size;
2073bc1f688bSRobert Mustacchi
2074bc1f688bSRobert Mustacchi /* cie-id is a special value. */
2075bc1f688bSRobert Mustacchi du = DW_CIE_ID;
2076bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
2077*4d9fdb46SRobert Mustacchi sizeof(du), offset_size);
2078*4d9fdb46SRobert Mustacchi data += offset_size;
2079bc1f688bSRobert Mustacchi
2080bc1f688bSRobert Mustacchi db = curcie->cie_version;
2081bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2082bc1f688bSRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
2083bc1f688bSRobert Mustacchi data += sizeof(Dwarf_Ubyte);
2084*4d9fdb46SRobert Mustacchi
2085bc1f688bSRobert Mustacchi strcpy((char *) data, curcie->cie_aug);
2086bc1f688bSRobert Mustacchi data += strlen(curcie->cie_aug) + 1;
2087*4d9fdb46SRobert Mustacchi
2088*4d9fdb46SRobert Mustacchi if (curcie->cie_version >= 4) {
2089*4d9fdb46SRobert Mustacchi /* emit address-size, segment selector size */
2090*4d9fdb46SRobert Mustacchi db = dbg->de_pointer_size;
2091*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2092*4d9fdb46SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
2093*4d9fdb46SRobert Mustacchi data += sizeof(Dwarf_Ubyte);
2094*4d9fdb46SRobert Mustacchi
2095*4d9fdb46SRobert Mustacchi db = dbg->de_segment_selector_size;
2096*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2097*4d9fdb46SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
2098*4d9fdb46SRobert Mustacchi data += sizeof(Dwarf_Ubyte);
2099*4d9fdb46SRobert Mustacchi }
2100*4d9fdb46SRobert Mustacchi
2101*4d9fdb46SRobert Mustacchi
2102*4d9fdb46SRobert Mustacchi memcpy((void *) data, (const void *) code_al, codeal_bytes);
2103*4d9fdb46SRobert Mustacchi data += codeal_bytes;
2104*4d9fdb46SRobert Mustacchi
2105*4d9fdb46SRobert Mustacchi memcpy((void *) data, (const void *) data_al, data_align_bytes);
2106*4d9fdb46SRobert Mustacchi data += data_align_bytes;
2107*4d9fdb46SRobert Mustacchi
2108bc1f688bSRobert Mustacchi db = curcie->cie_ret_reg;
2109bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2110bc1f688bSRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
2111bc1f688bSRobert Mustacchi data += sizeof(Dwarf_Ubyte);
2112bc1f688bSRobert Mustacchi
2113*4d9fdb46SRobert Mustacchi if (dbg->de_irix_exc_augmentation &&
2114*4d9fdb46SRobert Mustacchi strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
2115*4d9fdb46SRobert Mustacchi
2116*4d9fdb46SRobert Mustacchi /* IRIX only */
2117*4d9fdb46SRobert Mustacchi memcpy((void *) data, (const void *) augmented_al,
2118*4d9fdb46SRobert Mustacchi irix_auglen_v0);
2119*4d9fdb46SRobert Mustacchi data += irix_auglen_v0;
2120bc1f688bSRobert Mustacchi }
2121bc1f688bSRobert Mustacchi memcpy((void *) data, (const void *) curcie->cie_inst,
2122bc1f688bSRobert Mustacchi curcie->cie_inst_bytes);
2123bc1f688bSRobert Mustacchi data += curcie->cie_inst_bytes;
2124*4d9fdb46SRobert Mustacchi
2125bc1f688bSRobert Mustacchi for (i = 0; i < pad; i++) {
2126bc1f688bSRobert Mustacchi *data = DW_CFA_nop;
2127bc1f688bSRobert Mustacchi data++;
2128bc1f688bSRobert Mustacchi }
2129bc1f688bSRobert Mustacchi curcie = curcie->cie_next;
2130bc1f688bSRobert Mustacchi }
2131bc1f688bSRobert Mustacchi /* calculate current offset */
2132*4d9fdb46SRobert Mustacchi cur_off = cie_offs[cie_no - 2] + cie_length +
2133*4d9fdb46SRobert Mustacchi OFFSET_PLUS_EXTENSION_SIZE;
2134bc1f688bSRobert Mustacchi
2135bc1f688bSRobert Mustacchi /* write out fde's */
2136bc1f688bSRobert Mustacchi curfde = dbg->de_frame_fdes;
2137bc1f688bSRobert Mustacchi while (curfde) {
2138bc1f688bSRobert Mustacchi Dwarf_P_Frame_Pgm curinst = 0;
2139bc1f688bSRobert Mustacchi long fde_length = 0;
2140*4d9fdb46SRobert Mustacchi int pad2 = 0;
2141bc1f688bSRobert Mustacchi Dwarf_P_Cie cie_ptr = 0;
2142*4d9fdb46SRobert Mustacchi Dwarf_Unsigned cie_index = 0;
2143*4d9fdb46SRobert Mustacchi /* index is a global in string.h, so don't name anything index. */
2144*4d9fdb46SRobert Mustacchi Dwarf_Unsigned indx = 0;
2145bc1f688bSRobert Mustacchi int oet_length = 0;
2146bc1f688bSRobert Mustacchi int afl_length = 0;
2147bc1f688bSRobert Mustacchi int res = 0;
2148bc1f688bSRobert Mustacchi int v0_augmentation = 0;
2149bc1f688bSRobert Mustacchi char afl_buff[ENCODE_SPACE_NEEDED];
2150bc1f688bSRobert Mustacchi
2151bc1f688bSRobert Mustacchi /* Find the CIE associated with this fde. */
2152bc1f688bSRobert Mustacchi cie_ptr = dbg->de_frame_cies;
2153bc1f688bSRobert Mustacchi cie_index = curfde->fde_cie;
2154*4d9fdb46SRobert Mustacchi indx = 1; /* The cie_index of the first cie is 1, not 0. */
2155*4d9fdb46SRobert Mustacchi while (cie_ptr && indx < cie_index) {
2156bc1f688bSRobert Mustacchi cie_ptr = cie_ptr->cie_next;
2157*4d9fdb46SRobert Mustacchi indx++;
2158bc1f688bSRobert Mustacchi }
2159bc1f688bSRobert Mustacchi if (cie_ptr == NULL) {
2160*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, DW_DLV_ERROR);
2161bc1f688bSRobert Mustacchi }
2162bc1f688bSRobert Mustacchi
2163*4d9fdb46SRobert Mustacchi fde_length = curfde->fde_n_bytes +
2164*4d9fdb46SRobert Mustacchi OFFSET_PLUS_EXTENSION_SIZE +
2165*4d9fdb46SRobert Mustacchi /* cie pointer */
2166*4d9fdb46SRobert Mustacchi address_size + /* initial loc */
2167*4d9fdb46SRobert Mustacchi address_size; /* address range */
2168*4d9fdb46SRobert Mustacchi if (dbg->de_irix_exc_augmentation &&
2169*4d9fdb46SRobert Mustacchi strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) {
2170*4d9fdb46SRobert Mustacchi
2171bc1f688bSRobert Mustacchi v0_augmentation = 1;
2172*4d9fdb46SRobert Mustacchi oet_length = DWARF_32BIT_SIZE;
2173bc1f688bSRobert Mustacchi /* encode the length of augmented fields. */
2174bc1f688bSRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(oet_length,
2175bc1f688bSRobert Mustacchi &afl_length, afl_buff,
2176bc1f688bSRobert Mustacchi sizeof(afl_buff));
2177bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
2178*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC,
2179*4d9fdb46SRobert Mustacchi DW_DLV_ERROR);
2180bc1f688bSRobert Mustacchi }
2181bc1f688bSRobert Mustacchi
2182*4d9fdb46SRobert Mustacchi fde_length +=
2183bc1f688bSRobert Mustacchi afl_length + /* augmented field length */
2184bc1f688bSRobert Mustacchi oet_length; /* exception_table offset */
2185bc1f688bSRobert Mustacchi }
2186bc1f688bSRobert Mustacchi
2187bc1f688bSRobert Mustacchi if (curfde->fde_die) {
2188bc1f688bSRobert Mustacchi /* IRIX/MIPS extension:
2189*4d9fdb46SRobert Mustacchi Using fde offset, generate DW_AT_MIPS_fde
2190*4d9fdb46SRobert Mustacchi attribute for the
2191bc1f688bSRobert Mustacchi die corresponding to this fde. */
2192*4d9fdb46SRobert Mustacchi res = _dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off,
2193*4d9fdb46SRobert Mustacchi error);
2194*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
2195*4d9fdb46SRobert Mustacchi return res;
2196bc1f688bSRobert Mustacchi }
2197bc1f688bSRobert Mustacchi }
2198bc1f688bSRobert Mustacchi
2199bc1f688bSRobert Mustacchi /* store relocation for cie pointer */
2200*4d9fdb46SRobert Mustacchi
2201*4d9fdb46SRobert Mustacchi res = dbg->de_relocate_by_name_symbol(dbg,
2202*4d9fdb46SRobert Mustacchi DEBUG_FRAME, cur_off +
2203*4d9fdb46SRobert Mustacchi OFFSET_PLUS_EXTENSION_SIZE /* r_offset */,
2204bc1f688bSRobert Mustacchi dbg->de_sect_name_idx[DEBUG_FRAME],
2205*4d9fdb46SRobert Mustacchi dwarf_drt_data_reloc, offset_size);
2206bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
2207*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res );
2208bc1f688bSRobert Mustacchi }
2209bc1f688bSRobert Mustacchi
2210bc1f688bSRobert Mustacchi /* store relocation information for initial location */
2211*4d9fdb46SRobert Mustacchi res = dbg->de_relocate_by_name_symbol(dbg,
2212*4d9fdb46SRobert Mustacchi DEBUG_FRAME,
2213*4d9fdb46SRobert Mustacchi cur_off + OFFSET_PLUS_EXTENSION_SIZE +
2214*4d9fdb46SRobert Mustacchi address_size /* r_offset */,
2215bc1f688bSRobert Mustacchi curfde->fde_r_symidx,
2216*4d9fdb46SRobert Mustacchi dwarf_drt_data_reloc, address_size);
2217bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
2218*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res);
2219bc1f688bSRobert Mustacchi }
2220bc1f688bSRobert Mustacchi /* Store the relocation information for the
2221bc1f688bSRobert Mustacchi offset_into_exception_info field, if the offset is valid (0
2222bc1f688bSRobert Mustacchi is a valid offset). */
2223bc1f688bSRobert Mustacchi if (v0_augmentation &&
2224bc1f688bSRobert Mustacchi curfde->fde_offset_into_exception_tables >= 0) {
2225bc1f688bSRobert Mustacchi
2226*4d9fdb46SRobert Mustacchi res = dbg->de_relocate_by_name_symbol(dbg,
2227*4d9fdb46SRobert Mustacchi DEBUG_FRAME,
2228*4d9fdb46SRobert Mustacchi /* r_offset, where in cie this field starts */
2229*4d9fdb46SRobert Mustacchi cur_off + OFFSET_PLUS_EXTENSION_SIZE +
2230*4d9fdb46SRobert Mustacchi offset_size + 2 * address_size +
2231bc1f688bSRobert Mustacchi afl_length,
2232bc1f688bSRobert Mustacchi curfde->fde_exception_table_symbol,
2233bc1f688bSRobert Mustacchi dwarf_drt_segment_rel,
2234*4d9fdb46SRobert Mustacchi DWARF_32BIT_SIZE);
2235bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
2236*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res);
2237bc1f688bSRobert Mustacchi }
2238bc1f688bSRobert Mustacchi }
2239bc1f688bSRobert Mustacchi
2240bc1f688bSRobert Mustacchi /* adjust for padding */
2241*4d9fdb46SRobert Mustacchi pad2 = (int) PADDING(fde_length, address_size);
2242*4d9fdb46SRobert Mustacchi fde_length += pad2;
2243bc1f688bSRobert Mustacchi
2244bc1f688bSRobert Mustacchi
2245bc1f688bSRobert Mustacchi /* write out fde */
2246*4d9fdb46SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, fde_length +
2247*4d9fdb46SRobert Mustacchi OFFSET_PLUS_EXTENSION_SIZE,
2248bc1f688bSRobert Mustacchi error);
2249bc1f688bSRobert Mustacchi du = fde_length;
2250bc1f688bSRobert Mustacchi {
2251bc1f688bSRobert Mustacchi if (extension_size) {
2252*4d9fdb46SRobert Mustacchi DISTINGUISHED_VALUE_ARRAY(v4);
2253bc1f688bSRobert Mustacchi
2254bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2255*4d9fdb46SRobert Mustacchi (const void *) &v4[0],
2256*4d9fdb46SRobert Mustacchi SIZEOFT32, extension_size);
2257bc1f688bSRobert Mustacchi data += extension_size;
2258bc1f688bSRobert Mustacchi }
2259bc1f688bSRobert Mustacchi /* length */
2260bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2261bc1f688bSRobert Mustacchi (const void *) &du,
2262*4d9fdb46SRobert Mustacchi sizeof(du), offset_size);
2263*4d9fdb46SRobert Mustacchi data += offset_size;
2264bc1f688bSRobert Mustacchi
2265bc1f688bSRobert Mustacchi /* offset to cie */
2266bc1f688bSRobert Mustacchi du = cie_offs[curfde->fde_cie - 1];
2267bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2268bc1f688bSRobert Mustacchi (const void *) &du,
2269*4d9fdb46SRobert Mustacchi sizeof(du), offset_size);
2270*4d9fdb46SRobert Mustacchi data += offset_size;
2271bc1f688bSRobert Mustacchi
2272bc1f688bSRobert Mustacchi du = curfde->fde_initloc;
2273bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2274bc1f688bSRobert Mustacchi (const void *) &du,
2275*4d9fdb46SRobert Mustacchi sizeof(du), address_size);
2276*4d9fdb46SRobert Mustacchi data += address_size;
2277bc1f688bSRobert Mustacchi
2278*4d9fdb46SRobert Mustacchi if (dbg->de_relocate_pair_by_symbol &&
2279bc1f688bSRobert Mustacchi curfde->fde_end_symbol != 0 &&
2280bc1f688bSRobert Mustacchi curfde->fde_addr_range == 0) {
2281bc1f688bSRobert Mustacchi /* symbolic reloc, need reloc for length What if we
2282bc1f688bSRobert Mustacchi really know the length? If so, should use the other
2283bc1f688bSRobert Mustacchi part of 'if'. */
2284bc1f688bSRobert Mustacchi Dwarf_Unsigned val;
2285bc1f688bSRobert Mustacchi
2286*4d9fdb46SRobert Mustacchi res = dbg->de_relocate_pair_by_symbol(dbg,
2287*4d9fdb46SRobert Mustacchi DEBUG_FRAME,
2288*4d9fdb46SRobert Mustacchi cur_off + 2 * offset_size + address_size,
2289*4d9fdb46SRobert Mustacchi /* r_offset */ curfde->fde_r_symidx,
2290bc1f688bSRobert Mustacchi curfde->fde_end_symbol,
2291bc1f688bSRobert Mustacchi dwarf_drt_first_of_length_pair,
2292*4d9fdb46SRobert Mustacchi address_size);
2293bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
2294bc1f688bSRobert Mustacchi {
2295bc1f688bSRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
2296*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
2297bc1f688bSRobert Mustacchi }
2298bc1f688bSRobert Mustacchi }
2299bc1f688bSRobert Mustacchi
2300bc1f688bSRobert Mustacchi /* arrange pre-calc so assem text can do .word end -
2301bc1f688bSRobert Mustacchi begin + val (gets val from stream) */
2302bc1f688bSRobert Mustacchi val = curfde->fde_end_symbol_offset -
2303bc1f688bSRobert Mustacchi curfde->fde_initloc;
2304bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, data,
2305bc1f688bSRobert Mustacchi (const void *) &val,
2306*4d9fdb46SRobert Mustacchi sizeof(val), address_size);
2307*4d9fdb46SRobert Mustacchi data += address_size;
2308bc1f688bSRobert Mustacchi } else {
2309bc1f688bSRobert Mustacchi du = curfde->fde_addr_range;
2310bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2311bc1f688bSRobert Mustacchi (const void *) &du,
2312*4d9fdb46SRobert Mustacchi sizeof(du), address_size);
2313*4d9fdb46SRobert Mustacchi data += address_size;
2314bc1f688bSRobert Mustacchi }
2315bc1f688bSRobert Mustacchi }
2316bc1f688bSRobert Mustacchi
2317bc1f688bSRobert Mustacchi if (v0_augmentation) {
2318*4d9fdb46SRobert Mustacchi /* IRIX only. */
2319bc1f688bSRobert Mustacchi /* write the encoded augmented field length. */
2320*4d9fdb46SRobert Mustacchi Dwarf_Signed dsw = 0;
2321*4d9fdb46SRobert Mustacchi
2322bc1f688bSRobert Mustacchi memcpy((void *) data, (const void *) afl_buff, afl_length);
2323bc1f688bSRobert Mustacchi data += afl_length;
2324bc1f688bSRobert Mustacchi /* write the offset_into_exception_tables field. */
2325*4d9fdb46SRobert Mustacchi dsw = (Dwarf_Signed)curfde->fde_offset_into_exception_tables;
2326*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2327*4d9fdb46SRobert Mustacchi (const void *) &dsw,
2328*4d9fdb46SRobert Mustacchi sizeof(dsw), DWARF_32BIT_SIZE);
2329*4d9fdb46SRobert Mustacchi data += DWARF_32BIT_SIZE;
2330bc1f688bSRobert Mustacchi }
2331bc1f688bSRobert Mustacchi
2332bc1f688bSRobert Mustacchi curinst = curfde->fde_inst;
2333bc1f688bSRobert Mustacchi if (curfde->fde_block) {
2334bc1f688bSRobert Mustacchi unsigned long size = curfde->fde_inst_block_size;
2335bc1f688bSRobert Mustacchi memcpy((void *) data, (const void *) curfde->fde_block, size);
2336bc1f688bSRobert Mustacchi data += size;
2337bc1f688bSRobert Mustacchi } else {
2338bc1f688bSRobert Mustacchi while (curinst) {
2339bc1f688bSRobert Mustacchi db = curinst->dfp_opcode;
2340bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2341bc1f688bSRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
2342bc1f688bSRobert Mustacchi data += sizeof(Dwarf_Ubyte);
2343bc1f688bSRobert Mustacchi memcpy((void *) data,
2344bc1f688bSRobert Mustacchi (const void *) curinst->dfp_args,
2345bc1f688bSRobert Mustacchi curinst->dfp_nbytes);
2346bc1f688bSRobert Mustacchi data += curinst->dfp_nbytes;
2347bc1f688bSRobert Mustacchi curinst = curinst->dfp_next;
2348bc1f688bSRobert Mustacchi }
2349bc1f688bSRobert Mustacchi }
2350bc1f688bSRobert Mustacchi /* padding */
2351*4d9fdb46SRobert Mustacchi for (i = 0; i < pad2; i++) {
2352bc1f688bSRobert Mustacchi *data = DW_CFA_nop;
2353bc1f688bSRobert Mustacchi data++;
2354bc1f688bSRobert Mustacchi }
2355*4d9fdb46SRobert Mustacchi cur_off += fde_length + offset_size;
2356bc1f688bSRobert Mustacchi curfde = curfde->fde_next;
2357bc1f688bSRobert Mustacchi }
2358bc1f688bSRobert Mustacchi
2359bc1f688bSRobert Mustacchi
2360*4d9fdb46SRobert Mustacchi *nbufs = dbg->de_n_debug_sect;
2361*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2362bc1f688bSRobert Mustacchi }
2363bc1f688bSRobert Mustacchi
2364bc1f688bSRobert Mustacchi /*
2365bc1f688bSRobert Mustacchi These functions remember all the markers we see along
2366bc1f688bSRobert Mustacchi with the right offset in the .debug_info section so that
2367bc1f688bSRobert Mustacchi we can dump them all back to the user with the section info.
2368bc1f688bSRobert Mustacchi */
2369bc1f688bSRobert Mustacchi
2370bc1f688bSRobert Mustacchi static int
marker_init(Dwarf_P_Debug dbg,unsigned count)2371bc1f688bSRobert Mustacchi marker_init(Dwarf_P_Debug dbg,
2372bc1f688bSRobert Mustacchi unsigned count)
2373bc1f688bSRobert Mustacchi {
2374bc1f688bSRobert Mustacchi dbg->de_marker_n_alloc = count;
2375bc1f688bSRobert Mustacchi dbg->de_markers = NULL;
2376bc1f688bSRobert Mustacchi if (count > 0) {
2377*4d9fdb46SRobert Mustacchi dbg->de_markers = _dwarf_p_get_alloc(dbg,
2378*4d9fdb46SRobert Mustacchi sizeof(struct Dwarf_P_Marker_s) * dbg->de_marker_n_alloc);
2379bc1f688bSRobert Mustacchi if (dbg->de_markers == NULL) {
2380bc1f688bSRobert Mustacchi dbg->de_marker_n_alloc = 0;
2381*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
2382bc1f688bSRobert Mustacchi }
2383bc1f688bSRobert Mustacchi }
2384*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2385bc1f688bSRobert Mustacchi }
2386bc1f688bSRobert Mustacchi
2387bc1f688bSRobert Mustacchi static int
marker_add(Dwarf_P_Debug dbg,Dwarf_Unsigned offset,Dwarf_Unsigned marker)2388bc1f688bSRobert Mustacchi marker_add(Dwarf_P_Debug dbg,
2389bc1f688bSRobert Mustacchi Dwarf_Unsigned offset,
2390bc1f688bSRobert Mustacchi Dwarf_Unsigned marker)
2391bc1f688bSRobert Mustacchi {
2392bc1f688bSRobert Mustacchi if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) {
2393bc1f688bSRobert Mustacchi unsigned n = dbg->de_marker_n_used++;
2394bc1f688bSRobert Mustacchi dbg->de_markers[n].ma_offset = offset;
2395bc1f688bSRobert Mustacchi dbg->de_markers[n].ma_marker = marker;
2396*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2397bc1f688bSRobert Mustacchi }
2398*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
2399bc1f688bSRobert Mustacchi }
2400bc1f688bSRobert Mustacchi
2401bc1f688bSRobert Mustacchi Dwarf_Signed
dwarf_get_die_markers(Dwarf_P_Debug dbg,Dwarf_P_Marker * marker_list,Dwarf_Unsigned * marker_count,Dwarf_Error * error)2402bc1f688bSRobert Mustacchi dwarf_get_die_markers(Dwarf_P_Debug dbg,
2403bc1f688bSRobert Mustacchi Dwarf_P_Marker * marker_list, /* pointer to a pointer */
2404bc1f688bSRobert Mustacchi Dwarf_Unsigned * marker_count,
2405bc1f688bSRobert Mustacchi Dwarf_Error * error)
2406bc1f688bSRobert Mustacchi {
2407*4d9fdb46SRobert Mustacchi int res = 0;
2408*4d9fdb46SRobert Mustacchi
2409*4d9fdb46SRobert Mustacchi res = dwarf_get_die_markers_a(dbg,marker_list,marker_count,
2410*4d9fdb46SRobert Mustacchi error);
2411*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
2412*4d9fdb46SRobert Mustacchi return DW_DLV_BADADDR;
2413*4d9fdb46SRobert Mustacchi }
2414*4d9fdb46SRobert Mustacchi return 0;
2415*4d9fdb46SRobert Mustacchi }
2416*4d9fdb46SRobert Mustacchi
2417*4d9fdb46SRobert Mustacchi int
dwarf_get_die_markers_a(Dwarf_P_Debug dbg,Dwarf_P_Marker * marker_list,Dwarf_Unsigned * marker_count,Dwarf_Error * error)2418*4d9fdb46SRobert Mustacchi dwarf_get_die_markers_a(Dwarf_P_Debug dbg,
2419*4d9fdb46SRobert Mustacchi Dwarf_P_Marker * marker_list, /* pointer to a pointer */
2420*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * marker_count,
2421*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
2422*4d9fdb46SRobert Mustacchi {
2423bc1f688bSRobert Mustacchi if (marker_list == NULL || marker_count == NULL) {
2424*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR);
2425bc1f688bSRobert Mustacchi }
2426bc1f688bSRobert Mustacchi if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) {
2427*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR);
2428bc1f688bSRobert Mustacchi }
2429bc1f688bSRobert Mustacchi
2430bc1f688bSRobert Mustacchi *marker_list = dbg->de_markers;
2431bc1f688bSRobert Mustacchi *marker_count = dbg->de_marker_n_used;
2432bc1f688bSRobert Mustacchi return DW_DLV_OK;
2433bc1f688bSRobert Mustacchi }
2434bc1f688bSRobert Mustacchi
2435bc1f688bSRobert Mustacchi /* These functions provide the offsets of DW_FORM_string
2436bc1f688bSRobert Mustacchi attributes in the section section_index. These information
2437bc1f688bSRobert Mustacchi will enable a producer app that is generating assembly
2438bc1f688bSRobert Mustacchi text output to easily emit those attributes in ascii form
2439*4d9fdb46SRobert Mustacchi without having to decode the byte stream. */
2440bc1f688bSRobert Mustacchi static int
string_attr_init(Dwarf_P_Debug dbg,Dwarf_Signed section_index,unsigned count)2441bc1f688bSRobert Mustacchi string_attr_init (Dwarf_P_Debug dbg,
2442bc1f688bSRobert Mustacchi Dwarf_Signed section_index,
2443bc1f688bSRobert Mustacchi unsigned count)
2444bc1f688bSRobert Mustacchi {
2445*4d9fdb46SRobert Mustacchi Dwarf_P_Per_Sect_String_Attrs sect_sa =
2446*4d9fdb46SRobert Mustacchi &dbg->de_sect_string_attr[section_index];
2447bc1f688bSRobert Mustacchi
2448bc1f688bSRobert Mustacchi sect_sa->sect_sa_n_alloc = count;
2449bc1f688bSRobert Mustacchi sect_sa->sect_sa_list = NULL;
2450bc1f688bSRobert Mustacchi if (count > 0) {
2451bc1f688bSRobert Mustacchi sect_sa->sect_sa_section_number = section_index;
2452bc1f688bSRobert Mustacchi sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg,
2453*4d9fdb46SRobert Mustacchi sizeof(struct Dwarf_P_String_Attr_s) * sect_sa->sect_sa_n_alloc);
2454bc1f688bSRobert Mustacchi if (sect_sa->sect_sa_list == NULL) {
2455bc1f688bSRobert Mustacchi sect_sa->sect_sa_n_alloc = 0;
2456*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
2457bc1f688bSRobert Mustacchi }
2458bc1f688bSRobert Mustacchi }
2459*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2460bc1f688bSRobert Mustacchi }
2461bc1f688bSRobert Mustacchi
2462bc1f688bSRobert Mustacchi static int
string_attr_add(Dwarf_P_Debug dbg,Dwarf_Signed section_index,Dwarf_Unsigned offset,Dwarf_P_Attribute attr)2463bc1f688bSRobert Mustacchi string_attr_add (Dwarf_P_Debug dbg,
2464bc1f688bSRobert Mustacchi Dwarf_Signed section_index,
2465bc1f688bSRobert Mustacchi Dwarf_Unsigned offset,
2466bc1f688bSRobert Mustacchi Dwarf_P_Attribute attr)
2467bc1f688bSRobert Mustacchi {
2468bc1f688bSRobert Mustacchi Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
2469bc1f688bSRobert Mustacchi if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) {
2470bc1f688bSRobert Mustacchi unsigned n = sect_sa->sect_sa_n_used++;
2471bc1f688bSRobert Mustacchi sect_sa->sect_sa_list[n].sa_offset = offset;
2472bc1f688bSRobert Mustacchi sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes;
2473*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2474bc1f688bSRobert Mustacchi }
2475bc1f688bSRobert Mustacchi
2476*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
2477bc1f688bSRobert Mustacchi }
2478bc1f688bSRobert Mustacchi
2479bc1f688bSRobert Mustacchi int
dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,Dwarf_Unsigned * count_of_sa_sections,int * drd_buffer_version,UNUSEDARG Dwarf_Error * error)2480bc1f688bSRobert Mustacchi dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,
2481bc1f688bSRobert Mustacchi Dwarf_Unsigned *
2482bc1f688bSRobert Mustacchi count_of_sa_sections,
2483bc1f688bSRobert Mustacchi int *drd_buffer_version,
2484*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Error *error)
2485bc1f688bSRobert Mustacchi {
2486*4d9fdb46SRobert Mustacchi int i = 0;
2487bc1f688bSRobert Mustacchi unsigned int count = 0;
2488bc1f688bSRobert Mustacchi
2489bc1f688bSRobert Mustacchi for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
2490bc1f688bSRobert Mustacchi if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) {
2491bc1f688bSRobert Mustacchi ++count;
2492bc1f688bSRobert Mustacchi }
2493bc1f688bSRobert Mustacchi }
2494bc1f688bSRobert Mustacchi *count_of_sa_sections = (Dwarf_Unsigned) count;
2495bc1f688bSRobert Mustacchi *drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
2496bc1f688bSRobert Mustacchi
2497bc1f688bSRobert Mustacchi return DW_DLV_OK;
2498bc1f688bSRobert Mustacchi }
2499bc1f688bSRobert Mustacchi
2500bc1f688bSRobert 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,UNUSEDARG Dwarf_Error * error)2501bc1f688bSRobert Mustacchi dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,
2502bc1f688bSRobert Mustacchi Dwarf_Signed *elf_section_index,
2503bc1f688bSRobert Mustacchi Dwarf_Unsigned *sect_sa_buffer_count,
2504bc1f688bSRobert Mustacchi Dwarf_P_String_Attr *sect_sa_buffer,
2505*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Error *error)
2506bc1f688bSRobert Mustacchi {
2507*4d9fdb46SRobert Mustacchi int i = 0;
2508bc1f688bSRobert Mustacchi int next = dbg->de_sect_sa_next_to_return;
2509bc1f688bSRobert Mustacchi
2510bc1f688bSRobert Mustacchi for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
2511bc1f688bSRobert Mustacchi Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i];
2512bc1f688bSRobert Mustacchi if (sect_sa->sect_sa_n_used > 0) {
2513bc1f688bSRobert Mustacchi dbg->de_sect_sa_next_to_return = i + 1;
2514bc1f688bSRobert Mustacchi *elf_section_index = sect_sa->sect_sa_section_number;
2515bc1f688bSRobert Mustacchi *sect_sa_buffer_count = sect_sa->sect_sa_n_used;
2516bc1f688bSRobert Mustacchi *sect_sa_buffer = sect_sa->sect_sa_list;
2517bc1f688bSRobert Mustacchi return DW_DLV_OK;
2518bc1f688bSRobert Mustacchi }
2519bc1f688bSRobert Mustacchi }
2520bc1f688bSRobert Mustacchi return DW_DLV_NO_ENTRY;
2521bc1f688bSRobert Mustacchi }
2522bc1f688bSRobert Mustacchi
2523bc1f688bSRobert Mustacchi
2524bc1f688bSRobert Mustacchi static int
has_sibling_die_already(Dwarf_P_Die d)2525*4d9fdb46SRobert Mustacchi has_sibling_die_already(Dwarf_P_Die d)
2526*4d9fdb46SRobert Mustacchi {
2527*4d9fdb46SRobert Mustacchi Dwarf_P_Attribute a = 0;
2528*4d9fdb46SRobert Mustacchi for(a = d->di_attrs; a ; a = a->ar_next) {
2529*4d9fdb46SRobert Mustacchi if(a->ar_attribute == DW_AT_sibling) {
2530*4d9fdb46SRobert Mustacchi return TRUE;
2531*4d9fdb46SRobert Mustacchi }
2532*4d9fdb46SRobert Mustacchi }
2533*4d9fdb46SRobert Mustacchi return FALSE;
2534*4d9fdb46SRobert Mustacchi }
2535*4d9fdb46SRobert Mustacchi
2536*4d9fdb46SRobert Mustacchi /* For DW_FORM_strp we need to set the symindex so we need
2537*4d9fdb46SRobert Mustacchi to check that such applies. */
2538*4d9fdb46SRobert Mustacchi static int
if_relocatable_string_form(Dwarf_P_Debug dbg,Dwarf_P_Attribute curattr,int * debug_str_reloc,Dwarf_Error * error)2539*4d9fdb46SRobert Mustacchi if_relocatable_string_form(Dwarf_P_Debug dbg, Dwarf_P_Attribute curattr,
2540*4d9fdb46SRobert Mustacchi int *debug_str_reloc,
2541*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
2542*4d9fdb46SRobert Mustacchi {
2543*4d9fdb46SRobert Mustacchi if (curattr->ar_rel_type == R_MIPS_NONE) {
2544*4d9fdb46SRobert Mustacchi *debug_str_reloc = 0;
2545*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2546*4d9fdb46SRobert Mustacchi }
2547*4d9fdb46SRobert Mustacchi if (curattr->ar_attribute_form != DW_FORM_strp) {
2548*4d9fdb46SRobert Mustacchi _dwarf_p_error(dbg, error,DW_DLE_DEBUGSTR_UNEXPECTED_REL);
2549*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
2550*4d9fdb46SRobert Mustacchi }
2551*4d9fdb46SRobert Mustacchi if (curattr->ar_rel_type != dbg->de_offset_reloc) {
2552*4d9fdb46SRobert Mustacchi _dwarf_p_error(dbg, error,DW_DLE_DEBUGSTR_UNEXPECTED_REL);
2553*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
2554*4d9fdb46SRobert Mustacchi }
2555*4d9fdb46SRobert Mustacchi *debug_str_reloc = 1;
2556*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2557*4d9fdb46SRobert Mustacchi }
2558*4d9fdb46SRobert Mustacchi
2559*4d9fdb46SRobert Mustacchi /* Tries to see if given attribute and form combination
2560*4d9fdb46SRobert Mustacchi of the attr exists in the given abbreviation.
2561*4d9fdb46SRobert Mustacchi abbrevs and attrs are sorted in attrnum order. */
2562*4d9fdb46SRobert Mustacchi static int
_dwarf_pro_match_attr(Dwarf_P_Attribute attr,Dwarf_P_Abbrev abbrev,int no_attr)2563*4d9fdb46SRobert Mustacchi _dwarf_pro_match_attr(Dwarf_P_Attribute attr,
2564*4d9fdb46SRobert Mustacchi Dwarf_P_Abbrev abbrev, int no_attr)
2565*4d9fdb46SRobert Mustacchi {
2566*4d9fdb46SRobert Mustacchi int i = 0;
2567*4d9fdb46SRobert Mustacchi Dwarf_P_Attribute curatp = attr;
2568*4d9fdb46SRobert Mustacchi
2569*4d9fdb46SRobert Mustacchi for (i = 0; i < no_attr && curatp; i++,curatp = curatp->ar_next ) {
2570*4d9fdb46SRobert Mustacchi if (curatp->ar_attribute != abbrev->abb_attrs[i] ||
2571*4d9fdb46SRobert Mustacchi curatp->ar_attribute_form != abbrev->abb_forms[i]) {
2572*4d9fdb46SRobert Mustacchi return 0;
2573*4d9fdb46SRobert Mustacchi }
2574*4d9fdb46SRobert Mustacchi /* If either is implicit_const need special
2575*4d9fdb46SRobert Mustacchi check for matching val. */
2576*4d9fdb46SRobert Mustacchi if (curatp->ar_attribute_form == DW_FORM_implicit_const) {
2577*4d9fdb46SRobert Mustacchi if (abbrev->abb_forms[i] == DW_FORM_implicit_const) {
2578*4d9fdb46SRobert Mustacchi if (curatp->ar_implicit_const !=
2579*4d9fdb46SRobert Mustacchi abbrev->abb_implicits[i]) {
2580*4d9fdb46SRobert Mustacchi return 0;
2581*4d9fdb46SRobert Mustacchi }
2582*4d9fdb46SRobert Mustacchi } else {
2583*4d9fdb46SRobert Mustacchi return 0;
2584*4d9fdb46SRobert Mustacchi }
2585*4d9fdb46SRobert Mustacchi } else {
2586*4d9fdb46SRobert Mustacchi if (abbrev->abb_forms[i] == DW_FORM_implicit_const) {
2587*4d9fdb46SRobert Mustacchi return 0;
2588*4d9fdb46SRobert Mustacchi }
2589*4d9fdb46SRobert Mustacchi }
2590*4d9fdb46SRobert Mustacchi }
2591*4d9fdb46SRobert Mustacchi return 1;
2592*4d9fdb46SRobert Mustacchi }
2593*4d9fdb46SRobert Mustacchi
2594*4d9fdb46SRobert Mustacchi static int
verify_ab_no_dups(struct Dwarf_Sort_Abbrev_s * sortab,int attrcount)2595*4d9fdb46SRobert Mustacchi verify_ab_no_dups(struct Dwarf_Sort_Abbrev_s *sortab,
2596*4d9fdb46SRobert Mustacchi int attrcount)
2597*4d9fdb46SRobert Mustacchi {
2598*4d9fdb46SRobert Mustacchi int k = 0;
2599*4d9fdb46SRobert Mustacchi unsigned preva = 0;
2600*4d9fdb46SRobert Mustacchi struct Dwarf_Sort_Abbrev_s *ab = sortab;
2601*4d9fdb46SRobert Mustacchi
2602*4d9fdb46SRobert Mustacchi if (attrcount < 2) {
2603*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2604*4d9fdb46SRobert Mustacchi }
2605*4d9fdb46SRobert Mustacchi for(k = 0; k < attrcount; ++k,++ab) {
2606*4d9fdb46SRobert Mustacchi if (k) {
2607*4d9fdb46SRobert Mustacchi if (preva >= ab->dsa_attr) {
2608*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
2609*4d9fdb46SRobert Mustacchi }
2610*4d9fdb46SRobert Mustacchi }
2611*4d9fdb46SRobert Mustacchi preva = ab->dsa_attr;
2612*4d9fdb46SRobert Mustacchi }
2613*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2614*4d9fdb46SRobert Mustacchi }
2615*4d9fdb46SRobert Mustacchi
2616*4d9fdb46SRobert Mustacchi static int
abcompare(const void * l_in,const void * r_in)2617*4d9fdb46SRobert Mustacchi abcompare(const void *l_in, const void *r_in)
2618*4d9fdb46SRobert Mustacchi {
2619*4d9fdb46SRobert Mustacchi struct Dwarf_Sort_Abbrev_s *l =
2620*4d9fdb46SRobert Mustacchi (struct Dwarf_Sort_Abbrev_s *)l_in;
2621*4d9fdb46SRobert Mustacchi struct Dwarf_Sort_Abbrev_s *r =
2622*4d9fdb46SRobert Mustacchi (struct Dwarf_Sort_Abbrev_s *)r_in;
2623*4d9fdb46SRobert Mustacchi if (l->dsa_attr < r->dsa_attr) {
2624*4d9fdb46SRobert Mustacchi return -1;
2625*4d9fdb46SRobert Mustacchi }
2626*4d9fdb46SRobert Mustacchi if (l->dsa_attr > r->dsa_attr) {
2627*4d9fdb46SRobert Mustacchi return +1;
2628*4d9fdb46SRobert Mustacchi }
2629*4d9fdb46SRobert Mustacchi /* ASSERT: This never happens in correct dwarf. */
2630*4d9fdb46SRobert Mustacchi return 0;
2631*4d9fdb46SRobert Mustacchi }
2632*4d9fdb46SRobert Mustacchi
2633*4d9fdb46SRobert Mustacchi /* Handles abbreviations. It takes a die, searches through
2634*4d9fdb46SRobert Mustacchi current list of abbreviations for a matching one. If it
2635*4d9fdb46SRobert Mustacchi finds one, it returns a pointer to the abbrev through
2636*4d9fdb46SRobert Mustacchi the ab_out pointer, and if it does not,
2637*4d9fdb46SRobert Mustacchi it returns a new abbrev through the ab_out pointer.
2638*4d9fdb46SRobert Mustacchi
2639*4d9fdb46SRobert Mustacchi The die->die_attrs are sorted by attribute and the curabbrev
2640*4d9fdb46SRobert Mustacchi attrs are too.
2641*4d9fdb46SRobert Mustacchi
2642*4d9fdb46SRobert Mustacchi It is up to the user of this function to
2643*4d9fdb46SRobert Mustacchi link it up to the abbreviation head. If it is a new abbrev
2644*4d9fdb46SRobert Mustacchi abb_idx has 0. */
2645*4d9fdb46SRobert Mustacchi static int
_dwarf_pro_getabbrev(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_P_Abbrev head,Dwarf_P_Abbrev * ab_out,Dwarf_Error * error)2646*4d9fdb46SRobert Mustacchi _dwarf_pro_getabbrev(Dwarf_P_Debug dbg,
2647*4d9fdb46SRobert Mustacchi Dwarf_P_Die die, Dwarf_P_Abbrev head,
2648*4d9fdb46SRobert Mustacchi Dwarf_P_Abbrev*ab_out,Dwarf_Error *error)
2649*4d9fdb46SRobert Mustacchi {
2650*4d9fdb46SRobert Mustacchi Dwarf_P_Abbrev curabbrev = 0;
2651*4d9fdb46SRobert Mustacchi Dwarf_P_Attribute curattr = 0;
2652*4d9fdb46SRobert Mustacchi int match = 0;
2653*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *forms = 0;
2654*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *attrs = 0;
2655*4d9fdb46SRobert Mustacchi Dwarf_Signed *implicits = 0;
2656*4d9fdb46SRobert Mustacchi int attrcount = die->di_n_attr;
2657*4d9fdb46SRobert Mustacchi
2658*4d9fdb46SRobert Mustacchi curabbrev = head;
2659*4d9fdb46SRobert Mustacchi /* Loop thru the currently known abbreviations needed
2660*4d9fdb46SRobert Mustacchi to see if we can share an existing abbrev. */
2661*4d9fdb46SRobert Mustacchi while (curabbrev) {
2662*4d9fdb46SRobert Mustacchi if ((die->di_tag == curabbrev->abb_tag) &&
2663*4d9fdb46SRobert Mustacchi ((die->di_child != NULL &&
2664*4d9fdb46SRobert Mustacchi curabbrev->abb_children == DW_CHILDREN_yes) ||
2665*4d9fdb46SRobert Mustacchi (die->di_child == NULL &&
2666*4d9fdb46SRobert Mustacchi curabbrev->abb_children == DW_CHILDREN_no)) &&
2667*4d9fdb46SRobert Mustacchi (attrcount == curabbrev->abb_n_attr)) {
2668*4d9fdb46SRobert Mustacchi
2669*4d9fdb46SRobert Mustacchi /* There is a chance of a match, basic
2670*4d9fdb46SRobert Mustacchi characterists match. Now Check the attrs and
2671*4d9fdb46SRobert Mustacchi forms. */
2672*4d9fdb46SRobert Mustacchi curattr = die->di_attrs;
2673*4d9fdb46SRobert Mustacchi match = _dwarf_pro_match_attr(curattr,
2674*4d9fdb46SRobert Mustacchi curabbrev,
2675*4d9fdb46SRobert Mustacchi (int) curabbrev->abb_n_attr);
2676*4d9fdb46SRobert Mustacchi if (match == 1) {
2677*4d9fdb46SRobert Mustacchi /* This tag/children/abbrev-list matches
2678*4d9fdb46SRobert Mustacchi the incoming die needs exactly. Reuse
2679*4d9fdb46SRobert Mustacchi this abbreviation. */
2680*4d9fdb46SRobert Mustacchi *ab_out = curabbrev;
2681*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2682*4d9fdb46SRobert Mustacchi }
2683*4d9fdb46SRobert Mustacchi }
2684*4d9fdb46SRobert Mustacchi curabbrev = curabbrev->abb_next;
2685*4d9fdb46SRobert Mustacchi }
2686*4d9fdb46SRobert Mustacchi /* no match, create new abbreviation */
2687*4d9fdb46SRobert Mustacchi if (attrcount) {
2688*4d9fdb46SRobert Mustacchi forms = (Dwarf_Unsigned *)
2689*4d9fdb46SRobert Mustacchi _dwarf_p_get_alloc(die->di_dbg,
2690*4d9fdb46SRobert Mustacchi sizeof(Dwarf_Unsigned) * attrcount);
2691*4d9fdb46SRobert Mustacchi if (forms == NULL) {
2692*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
2693*4d9fdb46SRobert Mustacchi }
2694*4d9fdb46SRobert Mustacchi attrs = (Dwarf_Unsigned *)
2695*4d9fdb46SRobert Mustacchi _dwarf_p_get_alloc(die->di_dbg,
2696*4d9fdb46SRobert Mustacchi sizeof(Dwarf_Unsigned) * attrcount);
2697*4d9fdb46SRobert Mustacchi if (attrs == NULL) {
2698*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
2699*4d9fdb46SRobert Mustacchi }
2700*4d9fdb46SRobert Mustacchi implicits = (Dwarf_Signed *)
2701*4d9fdb46SRobert Mustacchi _dwarf_p_get_alloc(die->di_dbg,
2702*4d9fdb46SRobert Mustacchi sizeof(Dwarf_Signed) * attrcount);
2703*4d9fdb46SRobert Mustacchi if (implicits == NULL) {
2704*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
2705*4d9fdb46SRobert Mustacchi }
2706*4d9fdb46SRobert Mustacchi }
2707*4d9fdb46SRobert Mustacchi curattr = die->di_attrs;
2708*4d9fdb46SRobert Mustacchi if (forms && attrs && attrcount) {
2709*4d9fdb46SRobert Mustacchi struct Dwarf_Sort_Abbrev_s *sortab = 0;
2710*4d9fdb46SRobert Mustacchi struct Dwarf_Sort_Abbrev_s *ap = 0;
2711*4d9fdb46SRobert Mustacchi int k = 0;
2712*4d9fdb46SRobert Mustacchi int res = 0;
2713*4d9fdb46SRobert Mustacchi
2714*4d9fdb46SRobert Mustacchi sortab = (struct Dwarf_Sort_Abbrev_s *)
2715*4d9fdb46SRobert Mustacchi malloc(sizeof(struct Dwarf_Sort_Abbrev_s)*attrcount);
2716*4d9fdb46SRobert Mustacchi if(!sortab) {
2717*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
2718*4d9fdb46SRobert Mustacchi }
2719*4d9fdb46SRobert Mustacchi /* ASSERT curattr->ar_next chain length == attrcount */
2720*4d9fdb46SRobert Mustacchi ap = sortab;
2721*4d9fdb46SRobert Mustacchi for(; curattr; ++ap, curattr = curattr->ar_next) {
2722*4d9fdb46SRobert Mustacchi ap->dsa_attr = curattr->ar_attribute;
2723*4d9fdb46SRobert Mustacchi ap->dsa_form = curattr->ar_attribute_form;
2724*4d9fdb46SRobert Mustacchi ap->dsa_implicitvalue = curattr->ar_implicit_const;
2725*4d9fdb46SRobert Mustacchi ap->dsa_attrp = 0;
2726*4d9fdb46SRobert Mustacchi }
2727*4d9fdb46SRobert Mustacchi
2728*4d9fdb46SRobert Mustacchi qsort(sortab,attrcount,sizeof(struct Dwarf_Sort_Abbrev_s),
2729*4d9fdb46SRobert Mustacchi abcompare);
2730*4d9fdb46SRobert Mustacchi ap = sortab;
2731*4d9fdb46SRobert Mustacchi k = 0;
2732*4d9fdb46SRobert Mustacchi res = verify_ab_no_dups(sortab,attrcount);
2733*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
2734*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg,DW_DLE_DUP_ATTR_ON_DIE,DW_DLV_ERROR);
2735*4d9fdb46SRobert Mustacchi }
2736*4d9fdb46SRobert Mustacchi for( ; k < attrcount; ++k,++ap) {
2737*4d9fdb46SRobert Mustacchi attrs[k] = ap->dsa_attr;
2738*4d9fdb46SRobert Mustacchi forms[k] = ap->dsa_form;
2739*4d9fdb46SRobert Mustacchi implicits[k] = ap->dsa_implicitvalue;
2740*4d9fdb46SRobert Mustacchi }
2741*4d9fdb46SRobert Mustacchi free(sortab);
2742*4d9fdb46SRobert Mustacchi }
2743*4d9fdb46SRobert Mustacchi
2744*4d9fdb46SRobert Mustacchi curabbrev = (Dwarf_P_Abbrev)
2745*4d9fdb46SRobert Mustacchi _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s));
2746*4d9fdb46SRobert Mustacchi if (curabbrev == NULL) {
2747*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
2748*4d9fdb46SRobert Mustacchi }
2749*4d9fdb46SRobert Mustacchi
2750*4d9fdb46SRobert Mustacchi if (die->di_child == NULL) {
2751*4d9fdb46SRobert Mustacchi curabbrev->abb_children = DW_CHILDREN_no;
2752*4d9fdb46SRobert Mustacchi } else {
2753*4d9fdb46SRobert Mustacchi curabbrev->abb_children = DW_CHILDREN_yes;
2754*4d9fdb46SRobert Mustacchi }
2755*4d9fdb46SRobert Mustacchi curabbrev->abb_tag = die->di_tag;
2756*4d9fdb46SRobert Mustacchi curabbrev->abb_attrs = attrs;
2757*4d9fdb46SRobert Mustacchi curabbrev->abb_forms = forms;
2758*4d9fdb46SRobert Mustacchi curabbrev->abb_implicits = implicits;
2759*4d9fdb46SRobert Mustacchi curabbrev->abb_n_attr = attrcount;
2760*4d9fdb46SRobert Mustacchi curabbrev->abb_idx = 0;
2761*4d9fdb46SRobert Mustacchi curabbrev->abb_next = NULL;
2762*4d9fdb46SRobert Mustacchi *ab_out = curabbrev;
2763*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2764*4d9fdb46SRobert Mustacchi }
2765*4d9fdb46SRobert Mustacchi
2766*4d9fdb46SRobert Mustacchi /* Generate debug_info and debug_abbrev sections */
2767*4d9fdb46SRobert Mustacchi
2768*4d9fdb46SRobert Mustacchi
2769*4d9fdb46SRobert Mustacchi /* DWARF 2,3,4 */
2770*4d9fdb46SRobert Mustacchi static int
generate_debuginfo_header_2(Dwarf_P_Debug dbg,unsigned * abbrev_offset_io,unsigned char ** data_io,int * cu_header_size_out,Dwarf_Small ** abbr_off_ptr_out,Dwarf_Half version,int extension_size,Dwarf_Ubyte address_size,Dwarf_Error * error)2771*4d9fdb46SRobert Mustacchi generate_debuginfo_header_2(Dwarf_P_Debug dbg,
2772*4d9fdb46SRobert Mustacchi unsigned *abbrev_offset_io,
2773*4d9fdb46SRobert Mustacchi unsigned char **data_io,
2774*4d9fdb46SRobert Mustacchi int *cu_header_size_out,
2775*4d9fdb46SRobert Mustacchi Dwarf_Small **abbr_off_ptr_out,
2776*4d9fdb46SRobert Mustacchi Dwarf_Half version,
2777*4d9fdb46SRobert Mustacchi int extension_size,
2778*4d9fdb46SRobert Mustacchi Dwarf_Ubyte address_size,
2779*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
2780*4d9fdb46SRobert Mustacchi {
2781*4d9fdb46SRobert Mustacchi unsigned abbrev_offset = 0;
2782*4d9fdb46SRobert Mustacchi unsigned char * data = 0;
2783*4d9fdb46SRobert Mustacchi int offset_size = dbg->de_dwarf_offset_size;
2784*4d9fdb46SRobert Mustacchi int elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
2785*4d9fdb46SRobert Mustacchi int cu_header_size = 0;
2786*4d9fdb46SRobert Mustacchi Dwarf_Unsigned du = 0;
2787*4d9fdb46SRobert Mustacchi Dwarf_Small *abbr_off_ptr = 0;
2788*4d9fdb46SRobert Mustacchi
2789*4d9fdb46SRobert Mustacchi /* write cu header. abbrev_offset used to
2790*4d9fdb46SRobert Mustacchi generate relocation record below */
2791*4d9fdb46SRobert Mustacchi abbrev_offset = OFFSET_PLUS_EXTENSION_SIZE +
2792*4d9fdb46SRobert Mustacchi DWARF_HALF_SIZE ;
2793*4d9fdb46SRobert Mustacchi
2794*4d9fdb46SRobert Mustacchi cu_header_size = abbrev_offset +
2795*4d9fdb46SRobert Mustacchi offset_size + sizeof(Dwarf_Ubyte);
2796*4d9fdb46SRobert Mustacchi
2797*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, cu_header_size,
2798*4d9fdb46SRobert Mustacchi error);
2799*4d9fdb46SRobert Mustacchi if (extension_size) {
2800*4d9fdb46SRobert Mustacchi /* This for a dwarf-standard 64bit offset. */
2801*4d9fdb46SRobert Mustacchi DISTINGUISHED_VALUE_ARRAY(v4);
2802*4d9fdb46SRobert Mustacchi
2803*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2804*4d9fdb46SRobert Mustacchi (const void *) &v4[0], SIZEOFT32, extension_size);
2805*4d9fdb46SRobert Mustacchi data += extension_size;
2806*4d9fdb46SRobert Mustacchi }
2807*4d9fdb46SRobert Mustacchi abbr_off_ptr = data;
2808*4d9fdb46SRobert Mustacchi du = 0; /* length of debug_info, not counting
2809*4d9fdb46SRobert Mustacchi this field itself (unknown at this point). */
2810*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2811*4d9fdb46SRobert Mustacchi (const void *) &du, sizeof(du), offset_size);
2812*4d9fdb46SRobert Mustacchi data += offset_size;
2813*4d9fdb46SRobert Mustacchi
2814*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version,
2815*4d9fdb46SRobert Mustacchi sizeof(version), DWARF_HALF_SIZE);
2816*4d9fdb46SRobert Mustacchi data += DWARF_HALF_SIZE;
2817*4d9fdb46SRobert Mustacchi
2818*4d9fdb46SRobert Mustacchi du = 0;/* offset into abbrev table, not yet known. */
2819*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2820*4d9fdb46SRobert Mustacchi (const void *) &du, sizeof(du), offset_size);
2821*4d9fdb46SRobert Mustacchi data += offset_size;
2822*4d9fdb46SRobert Mustacchi
2823*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &address_size,
2824*4d9fdb46SRobert Mustacchi sizeof(address_size), sizeof(Dwarf_Ubyte));
2825*4d9fdb46SRobert Mustacchi data += sizeof(Dwarf_Ubyte);
2826*4d9fdb46SRobert Mustacchi
2827*4d9fdb46SRobert Mustacchi /* We have filled the chunk we got with GET_CHUNK.
2828*4d9fdb46SRobert Mustacchi At this point we
2829*4d9fdb46SRobert Mustacchi no longer dare use "data" as a
2830*4d9fdb46SRobert Mustacchi pointer any longer except to refer to that first
2831*4d9fdb46SRobert Mustacchi small chunk for the cu header to update
2832*4d9fdb46SRobert Mustacchi the section length. */
2833*4d9fdb46SRobert Mustacchi *abbrev_offset_io = abbrev_offset;
2834*4d9fdb46SRobert Mustacchi *data_io = data;
2835*4d9fdb46SRobert Mustacchi *cu_header_size_out = cu_header_size;
2836*4d9fdb46SRobert Mustacchi *abbr_off_ptr_out = abbr_off_ptr;
2837*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2838*4d9fdb46SRobert Mustacchi }
2839*4d9fdb46SRobert Mustacchi
2840*4d9fdb46SRobert Mustacchi /* DWARF 5 */
2841*4d9fdb46SRobert Mustacchi static int
generate_debuginfo_header_5(Dwarf_P_Debug dbg,unsigned * abbrev_offset_io,unsigned char ** data_io,int * cu_header_size_out,Dwarf_Small ** abbr_off_ptr_out,Dwarf_Half version,Dwarf_Ubyte unit_type,int extension_size,Dwarf_Ubyte address_size,Dwarf_Error * error)2842*4d9fdb46SRobert Mustacchi generate_debuginfo_header_5(Dwarf_P_Debug dbg,
2843*4d9fdb46SRobert Mustacchi unsigned *abbrev_offset_io,
2844*4d9fdb46SRobert Mustacchi unsigned char **data_io,
2845*4d9fdb46SRobert Mustacchi int *cu_header_size_out,
2846*4d9fdb46SRobert Mustacchi Dwarf_Small **abbr_off_ptr_out,
2847*4d9fdb46SRobert Mustacchi Dwarf_Half version,
2848*4d9fdb46SRobert Mustacchi Dwarf_Ubyte unit_type,
2849*4d9fdb46SRobert Mustacchi int extension_size,
2850*4d9fdb46SRobert Mustacchi Dwarf_Ubyte address_size,
2851*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
2852*4d9fdb46SRobert Mustacchi {
2853*4d9fdb46SRobert Mustacchi int offset_size = dbg->de_dwarf_offset_size;
2854*4d9fdb46SRobert Mustacchi unsigned abbrev_offset = 0;
2855*4d9fdb46SRobert Mustacchi unsigned char * data = 0;
2856*4d9fdb46SRobert Mustacchi int elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
2857*4d9fdb46SRobert Mustacchi int cu_header_size = 0;
2858*4d9fdb46SRobert Mustacchi Dwarf_Unsigned du = 0;
2859*4d9fdb46SRobert Mustacchi Dwarf_Small *abbr_off_ptr = 0;
2860*4d9fdb46SRobert Mustacchi
2861*4d9fdb46SRobert Mustacchi
2862*4d9fdb46SRobert Mustacchi /* write cu header. abbrev_offset used to
2863*4d9fdb46SRobert Mustacchi generate relocation record below */
2864*4d9fdb46SRobert Mustacchi abbrev_offset = OFFSET_PLUS_EXTENSION_SIZE +
2865*4d9fdb46SRobert Mustacchi DWARF_HALF_SIZE + /* version stamp */
2866*4d9fdb46SRobert Mustacchi sizeof(unit_type) +
2867*4d9fdb46SRobert Mustacchi sizeof(Dwarf_Ubyte);
2868*4d9fdb46SRobert Mustacchi cu_header_size = abbrev_offset + offset_size;
2869*4d9fdb46SRobert Mustacchi
2870*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, cu_header_size,
2871*4d9fdb46SRobert Mustacchi error);
2872*4d9fdb46SRobert Mustacchi if (extension_size) {
2873*4d9fdb46SRobert Mustacchi /* Impossible in DW5, really, is for IRIX64. But we allow it. */
2874*4d9fdb46SRobert Mustacchi DISTINGUISHED_VALUE_ARRAY(v4);
2875*4d9fdb46SRobert Mustacchi
2876*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2877*4d9fdb46SRobert Mustacchi (const void *) &v4[0], SIZEOFT32, extension_size);
2878*4d9fdb46SRobert Mustacchi data += extension_size;
2879*4d9fdb46SRobert Mustacchi }
2880*4d9fdb46SRobert Mustacchi abbr_off_ptr = data;
2881*4d9fdb46SRobert Mustacchi du = 0; /* length of debug_info, not counting
2882*4d9fdb46SRobert Mustacchi this field itself (unknown at this point). */
2883*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2884*4d9fdb46SRobert Mustacchi (const void *) &du, sizeof(du), offset_size);
2885*4d9fdb46SRobert Mustacchi data += offset_size;
2886*4d9fdb46SRobert Mustacchi
2887*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2888*4d9fdb46SRobert Mustacchi (const void *) &version,
2889*4d9fdb46SRobert Mustacchi sizeof(version), DWARF_HALF_SIZE);
2890*4d9fdb46SRobert Mustacchi data += DWARF_HALF_SIZE;
2891*4d9fdb46SRobert Mustacchi
2892*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2893*4d9fdb46SRobert Mustacchi (const void *) &unit_type,
2894*4d9fdb46SRobert Mustacchi sizeof(unit_type), sizeof(Dwarf_Ubyte));
2895*4d9fdb46SRobert Mustacchi data += sizeof(Dwarf_Ubyte);
2896*4d9fdb46SRobert Mustacchi
2897*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &address_size,
2898*4d9fdb46SRobert Mustacchi sizeof(address_size), sizeof(Dwarf_Ubyte));
2899*4d9fdb46SRobert Mustacchi data += sizeof(Dwarf_Ubyte);
2900*4d9fdb46SRobert Mustacchi
2901*4d9fdb46SRobert Mustacchi du = 0;/* offset into abbrev table, not yet known. */
2902*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
2903*4d9fdb46SRobert Mustacchi (const void *) &du, sizeof(du), offset_size);
2904*4d9fdb46SRobert Mustacchi data += offset_size;
2905*4d9fdb46SRobert Mustacchi
2906*4d9fdb46SRobert Mustacchi /* We have filled the chunk we got with GET_CHUNK.
2907*4d9fdb46SRobert Mustacchi At this point we
2908*4d9fdb46SRobert Mustacchi no longer dare use "data" as a pointer any
2909*4d9fdb46SRobert Mustacchi longer except to refer to that first small chunk for the cu
2910*4d9fdb46SRobert Mustacchi header to update the section length. */
2911*4d9fdb46SRobert Mustacchi
2912*4d9fdb46SRobert Mustacchi *abbrev_offset_io = abbrev_offset;
2913*4d9fdb46SRobert Mustacchi *data_io = data;
2914*4d9fdb46SRobert Mustacchi *cu_header_size_out = cu_header_size;
2915*4d9fdb46SRobert Mustacchi *abbr_off_ptr_out = abbr_off_ptr;
2916*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2917*4d9fdb46SRobert Mustacchi }
2918*4d9fdb46SRobert Mustacchi
2919*4d9fdb46SRobert Mustacchi /* Write out debug_abbrev section */
2920*4d9fdb46SRobert Mustacchi static int
write_out_debug_abbrev(Dwarf_P_Debug dbg,Dwarf_P_Abbrev abbrev_head,Dwarf_Error * error)2921*4d9fdb46SRobert Mustacchi write_out_debug_abbrev(Dwarf_P_Debug dbg,
2922*4d9fdb46SRobert Mustacchi Dwarf_P_Abbrev abbrev_head,
2923*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
2924*4d9fdb46SRobert Mustacchi {
2925*4d9fdb46SRobert Mustacchi Dwarf_P_Abbrev curabbrev = abbrev_head;
2926*4d9fdb46SRobert Mustacchi unsigned char *data = 0;
2927*4d9fdb46SRobert Mustacchi int res = 0;
2928*4d9fdb46SRobert Mustacchi int abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV];
2929*4d9fdb46SRobert Mustacchi
2930*4d9fdb46SRobert Mustacchi while (curabbrev) {
2931*4d9fdb46SRobert Mustacchi int idx = 0;
2932*4d9fdb46SRobert Mustacchi unsigned lebcount = 0;
2933*4d9fdb46SRobert Mustacchi Dwarf_Ubyte db = 0;
2934*4d9fdb46SRobert Mustacchi
2935*4d9fdb46SRobert Mustacchi res = write_uval(curabbrev->abb_idx,dbg,abbrevsectno,
2936*4d9fdb46SRobert Mustacchi &lebcount,error);
2937*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
2938*4d9fdb46SRobert Mustacchi return res;
2939*4d9fdb46SRobert Mustacchi }
2940*4d9fdb46SRobert Mustacchi
2941*4d9fdb46SRobert Mustacchi res = write_uval(curabbrev->abb_tag,dbg,abbrevsectno,
2942*4d9fdb46SRobert Mustacchi &lebcount,error);
2943*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
2944*4d9fdb46SRobert Mustacchi return res;
2945*4d9fdb46SRobert Mustacchi }
2946*4d9fdb46SRobert Mustacchi
2947*4d9fdb46SRobert Mustacchi db = curabbrev->abb_children;
2948*4d9fdb46SRobert Mustacchi res = write_ubyte(db,dbg,abbrevsectno,&lebcount,error);
2949*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
2950*4d9fdb46SRobert Mustacchi return res;
2951*4d9fdb46SRobert Mustacchi }
2952*4d9fdb46SRobert Mustacchi
2953*4d9fdb46SRobert Mustacchi /* add attributes and forms */
2954*4d9fdb46SRobert Mustacchi for (idx = 0; idx < curabbrev->abb_n_attr; idx++) {
2955*4d9fdb46SRobert Mustacchi res =write_uval(curabbrev->abb_attrs[idx],
2956*4d9fdb46SRobert Mustacchi dbg,abbrevsectno,
2957*4d9fdb46SRobert Mustacchi &lebcount,error);
2958*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
2959*4d9fdb46SRobert Mustacchi return res;
2960*4d9fdb46SRobert Mustacchi }
2961*4d9fdb46SRobert Mustacchi res =write_uval(curabbrev->abb_forms[idx],
2962*4d9fdb46SRobert Mustacchi dbg,abbrevsectno,
2963*4d9fdb46SRobert Mustacchi &lebcount,error);
2964*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
2965*4d9fdb46SRobert Mustacchi return res;
2966*4d9fdb46SRobert Mustacchi }
2967*4d9fdb46SRobert Mustacchi if (curabbrev->abb_forms[idx] == DW_FORM_implicit_const){
2968*4d9fdb46SRobert Mustacchi res =write_sval(curabbrev->abb_implicits[idx],
2969*4d9fdb46SRobert Mustacchi dbg,abbrevsectno,
2970*4d9fdb46SRobert Mustacchi &lebcount,error);
2971*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
2972*4d9fdb46SRobert Mustacchi return res;
2973*4d9fdb46SRobert Mustacchi }
2974*4d9fdb46SRobert Mustacchi }
2975*4d9fdb46SRobert Mustacchi }
2976*4d9fdb46SRobert Mustacchi /* Two zeros, for last entry, see dwarf2 sec 7.5.3 */
2977*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, abbrevsectno, data, 2, error);
2978*4d9fdb46SRobert Mustacchi *data = 0;
2979*4d9fdb46SRobert Mustacchi data++;
2980*4d9fdb46SRobert Mustacchi *data = 0;
2981*4d9fdb46SRobert Mustacchi
2982*4d9fdb46SRobert Mustacchi curabbrev = curabbrev->abb_next;
2983*4d9fdb46SRobert Mustacchi }
2984*4d9fdb46SRobert Mustacchi /* one zero, for end of cu, see dwarf2 sec 7.5.3 */
2985*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, abbrevsectno, data, 1, error);
2986*4d9fdb46SRobert Mustacchi *data = 0;
2987*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
2988*4d9fdb46SRobert Mustacchi }
2989*4d9fdb46SRobert Mustacchi
2990*4d9fdb46SRobert Mustacchi static int
sort_die_attrs(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Error * error)2991*4d9fdb46SRobert Mustacchi sort_die_attrs(Dwarf_P_Debug dbg,Dwarf_P_Die die,
2992*4d9fdb46SRobert Mustacchi Dwarf_Error *error)
2993*4d9fdb46SRobert Mustacchi {
2994*4d9fdb46SRobert Mustacchi struct Dwarf_Sort_Abbrev_s *sortab = 0;
2995*4d9fdb46SRobert Mustacchi struct Dwarf_Sort_Abbrev_s *ap = 0;
2996*4d9fdb46SRobert Mustacchi Dwarf_P_Attribute at = 0;
2997*4d9fdb46SRobert Mustacchi Dwarf_P_Attribute sorted_attrlist = 0;
2998*4d9fdb46SRobert Mustacchi Dwarf_P_Attribute sorted_tail = 0;
2999*4d9fdb46SRobert Mustacchi int attrcount = die->di_n_attr;
3000*4d9fdb46SRobert Mustacchi int res = 0;
3001*4d9fdb46SRobert Mustacchi unsigned ct = 0;
3002*4d9fdb46SRobert Mustacchi
3003*4d9fdb46SRobert Mustacchi int k = 0;
3004*4d9fdb46SRobert Mustacchi
3005*4d9fdb46SRobert Mustacchi if (attrcount < 2) {
3006*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
3007*4d9fdb46SRobert Mustacchi }
3008*4d9fdb46SRobert Mustacchi
3009*4d9fdb46SRobert Mustacchi sortab = (struct Dwarf_Sort_Abbrev_s *)
3010*4d9fdb46SRobert Mustacchi malloc(sizeof(struct Dwarf_Sort_Abbrev_s)*attrcount);
3011*4d9fdb46SRobert Mustacchi if(!sortab) {
3012*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
3013*4d9fdb46SRobert Mustacchi }
3014*4d9fdb46SRobert Mustacchi /* ASSERT at->ar_next chain length == attrcount */
3015*4d9fdb46SRobert Mustacchi ap = sortab;
3016*4d9fdb46SRobert Mustacchi at = die->di_attrs;
3017*4d9fdb46SRobert Mustacchi for(; at; ++ap, at = at->ar_next) {
3018*4d9fdb46SRobert Mustacchi ap->dsa_attr = at->ar_attribute;
3019*4d9fdb46SRobert Mustacchi ap->dsa_form = at->ar_attribute_form;
3020*4d9fdb46SRobert Mustacchi ap->dsa_attrp = at;
3021*4d9fdb46SRobert Mustacchi ++ct;
3022*4d9fdb46SRobert Mustacchi }
3023*4d9fdb46SRobert Mustacchi qsort(sortab,attrcount,sizeof(struct Dwarf_Sort_Abbrev_s),
3024*4d9fdb46SRobert Mustacchi abcompare);
3025*4d9fdb46SRobert Mustacchi res = verify_ab_no_dups(sortab,attrcount);
3026*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
3027*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DUP_ATTR_ON_DIE, DW_DLV_ERROR);
3028*4d9fdb46SRobert Mustacchi }
3029*4d9fdb46SRobert Mustacchi ap = sortab;
3030*4d9fdb46SRobert Mustacchi k = 0;
3031*4d9fdb46SRobert Mustacchi for( ; k < attrcount; ++k,++ap) {
3032*4d9fdb46SRobert Mustacchi Dwarf_P_Attribute localptr = ap->dsa_attrp;
3033*4d9fdb46SRobert Mustacchi if (!sorted_attrlist) {
3034*4d9fdb46SRobert Mustacchi sorted_attrlist = localptr;
3035*4d9fdb46SRobert Mustacchi sorted_tail = sorted_attrlist;
3036*4d9fdb46SRobert Mustacchi localptr->ar_next = 0;
3037*4d9fdb46SRobert Mustacchi continue;
3038*4d9fdb46SRobert Mustacchi }
3039*4d9fdb46SRobert Mustacchi sorted_tail->ar_next = localptr;
3040*4d9fdb46SRobert Mustacchi sorted_tail = localptr;
3041*4d9fdb46SRobert Mustacchi localptr->ar_next = 0;
3042*4d9fdb46SRobert Mustacchi }
3043*4d9fdb46SRobert Mustacchi /* Now replace the list with the same pointers
3044*4d9fdb46SRobert Mustacchi but in order sorted by attribute. */
3045*4d9fdb46SRobert Mustacchi die->di_attrs = sorted_attrlist;
3046*4d9fdb46SRobert Mustacchi free(sortab);
3047*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
3048*4d9fdb46SRobert Mustacchi }
3049*4d9fdb46SRobert Mustacchi
3050*4d9fdb46SRobert Mustacchi
3051*4d9fdb46SRobert Mustacchi
3052*4d9fdb46SRobert Mustacchi static int
_dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)3053*4d9fdb46SRobert Mustacchi _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
3054*4d9fdb46SRobert Mustacchi Dwarf_Signed *nbufs,
3055*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
3056bc1f688bSRobert Mustacchi {
3057bc1f688bSRobert Mustacchi int elfsectno_of_debug_info = 0;
3058bc1f688bSRobert Mustacchi unsigned char *data = 0;
3059bc1f688bSRobert Mustacchi int cu_header_size = 0;
3060bc1f688bSRobert Mustacchi Dwarf_P_Abbrev curabbrev = 0;
3061bc1f688bSRobert Mustacchi Dwarf_P_Abbrev abbrev_head = 0;
3062bc1f688bSRobert Mustacchi Dwarf_P_Abbrev abbrev_tail = 0;
3063bc1f688bSRobert Mustacchi Dwarf_P_Die curdie = 0;
3064bc1f688bSRobert Mustacchi Dwarf_P_Die first_child = 0;
3065*4d9fdb46SRobert Mustacchi Dwarf_Unsigned dw = 0;
3066bc1f688bSRobert Mustacchi Dwarf_Unsigned du = 0;
3067bc1f688bSRobert Mustacchi Dwarf_Half dh = 0;
3068bc1f688bSRobert Mustacchi Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */
3069bc1f688bSRobert Mustacchi int n_abbrevs = 0;
3070*4d9fdb46SRobert Mustacchi unsigned abbrev_offset = 0;
3071bc1f688bSRobert Mustacchi int res = 0;
3072bc1f688bSRobert Mustacchi unsigned marker_count = 0;
3073bc1f688bSRobert Mustacchi unsigned string_attr_count = 0;
3074bc1f688bSRobert Mustacchi unsigned string_attr_offset = 0;
3075*4d9fdb46SRobert Mustacchi Dwarf_Small *abbr_off_ptr = 0;
3076bc1f688bSRobert Mustacchi
3077*4d9fdb46SRobert Mustacchi int offset_size = dbg->de_dwarf_offset_size;
3078*4d9fdb46SRobert Mustacchi /* extension_size is oddly names. The standard calls
3079*4d9fdb46SRobert Mustacchi for a 64bit offset to have a 4 byte 0xffff
3080*4d9fdb46SRobert Mustacchi while original IRIX64 did not.
3081*4d9fdb46SRobert Mustacchi So if dbg->de_64bit_extension set this is a standard
3082*4d9fdb46SRobert Mustacchi DWARF 64bit offset and if de_64bit_extension not set
3083*4d9fdb46SRobert Mustacchi this is non-standard IRIX64 64 bit offset. */
3084*4d9fdb46SRobert Mustacchi Dwarf_Half version = dbg->de_output_version;
3085bc1f688bSRobert Mustacchi int extension_size = dbg->de_64bit_extension ? 4 : 0;
3086bc1f688bSRobert Mustacchi
3087*4d9fdb46SRobert Mustacchi /* For now just assume DW_UT_compile FIXME */
3088*4d9fdb46SRobert Mustacchi Dwarf_Ubyte unit_type = DW_UT_compile;
3089*4d9fdb46SRobert Mustacchi Dwarf_Ubyte address_size = 0;
3090*4d9fdb46SRobert Mustacchi
3091bc1f688bSRobert Mustacchi elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
3092*4d9fdb46SRobert Mustacchi address_size = dbg->de_pointer_size;
3093*4d9fdb46SRobert Mustacchi if (version < 5) {
3094*4d9fdb46SRobert Mustacchi res = generate_debuginfo_header_2(dbg,
3095*4d9fdb46SRobert Mustacchi &abbrev_offset,
3096*4d9fdb46SRobert Mustacchi &data,
3097*4d9fdb46SRobert Mustacchi &cu_header_size,
3098*4d9fdb46SRobert Mustacchi &abbr_off_ptr,
3099*4d9fdb46SRobert Mustacchi version, extension_size, address_size,
3100bc1f688bSRobert Mustacchi error);
3101*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
3102*4d9fdb46SRobert Mustacchi return res;
3103bc1f688bSRobert Mustacchi }
3104*4d9fdb46SRobert Mustacchi } else if (version == 5) {
3105*4d9fdb46SRobert Mustacchi res = generate_debuginfo_header_5(dbg,
3106*4d9fdb46SRobert Mustacchi &abbrev_offset,
3107*4d9fdb46SRobert Mustacchi &data,
3108*4d9fdb46SRobert Mustacchi &cu_header_size,
3109*4d9fdb46SRobert Mustacchi &abbr_off_ptr,
3110*4d9fdb46SRobert Mustacchi version, unit_type, extension_size, address_size,
3111*4d9fdb46SRobert Mustacchi error);
3112*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
3113*4d9fdb46SRobert Mustacchi return res;
3114*4d9fdb46SRobert Mustacchi }
3115*4d9fdb46SRobert Mustacchi } else {
3116*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_VERSION_STAMP_ERROR,
3117*4d9fdb46SRobert Mustacchi DW_DLV_ERROR);
3118*4d9fdb46SRobert Mustacchi }
3119bc1f688bSRobert Mustacchi
3120bc1f688bSRobert Mustacchi curdie = dbg->de_dies;
3121bc1f688bSRobert Mustacchi
3122*4d9fdb46SRobert Mustacchi /* Create AT_macro_info if appropriate */
3123*4d9fdb46SRobert Mustacchi if( version < 5) {
3124bc1f688bSRobert Mustacchi if (dbg->de_first_macinfo != NULL) {
3125*4d9fdb46SRobert Mustacchi res = _dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error);
3126*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
3127*4d9fdb46SRobert Mustacchi return res;
3128*4d9fdb46SRobert Mustacchi }
3129*4d9fdb46SRobert Mustacchi }
3130*4d9fdb46SRobert Mustacchi } else {
3131*4d9fdb46SRobert Mustacchi /* FIXME need to add code to emit DWARF5 macro data. */
3132*4d9fdb46SRobert Mustacchi #if 0
3133*4d9fdb46SRobert Mustacchi res = _dwarf_pro_add_AT_macro5_info(dbg, curdie, 0, error);
3134*4d9fdb46SRobert Mustacchi #endif
3135bc1f688bSRobert Mustacchi }
3136bc1f688bSRobert Mustacchi
3137*4d9fdb46SRobert Mustacchi /* Create AT_stmt_list attribute if necessary */
3138*4d9fdb46SRobert Mustacchi if (dwarf_need_debug_line_section(dbg) == TRUE) {
3139*4d9fdb46SRobert Mustacchi res =_dwarf_pro_add_AT_stmt_list(dbg, curdie, error);
3140*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
3141*4d9fdb46SRobert Mustacchi return res;
3142*4d9fdb46SRobert Mustacchi }
3143*4d9fdb46SRobert Mustacchi }
3144bc1f688bSRobert Mustacchi die_off = cu_header_size;
3145bc1f688bSRobert Mustacchi
3146*4d9fdb46SRobert Mustacchi /* Relocation for abbrev offset in cu header store relocation
3147bc1f688bSRobert Mustacchi record in linked list */
3148*4d9fdb46SRobert Mustacchi res = dbg->de_relocate_by_name_symbol(dbg,
3149*4d9fdb46SRobert Mustacchi DEBUG_INFO,
3150*4d9fdb46SRobert Mustacchi abbrev_offset /* r_offset */,
3151bc1f688bSRobert Mustacchi dbg->de_sect_name_idx[DEBUG_ABBREV],
3152*4d9fdb46SRobert Mustacchi dwarf_drt_data_reloc, offset_size);
3153bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
3154*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
3155bc1f688bSRobert Mustacchi }
3156bc1f688bSRobert Mustacchi
3157*4d9fdb46SRobert Mustacchi /* Pass 0: only top level dies, add at_sibling attribute to those
3158*4d9fdb46SRobert Mustacchi dies with children, but if and only if
3159*4d9fdb46SRobert Mustacchi there is no sibling attribute already. */
3160bc1f688bSRobert Mustacchi first_child = curdie->di_child;
3161bc1f688bSRobert Mustacchi while (first_child && first_child->di_right) {
3162*4d9fdb46SRobert Mustacchi if (first_child->di_child) {
3163*4d9fdb46SRobert Mustacchi if (!has_sibling_die_already(first_child)) {
3164bc1f688bSRobert Mustacchi dwarf_add_AT_reference(dbg,
3165bc1f688bSRobert Mustacchi first_child,
3166bc1f688bSRobert Mustacchi DW_AT_sibling,
3167bc1f688bSRobert Mustacchi first_child->di_right, error);
3168*4d9fdb46SRobert Mustacchi }
3169*4d9fdb46SRobert Mustacchi }
3170bc1f688bSRobert Mustacchi first_child = first_child->di_right;
3171bc1f688bSRobert Mustacchi }
3172bc1f688bSRobert Mustacchi
3173*4d9fdb46SRobert Mustacchi /* Pass 1: create abbrev info, get die offsets, calc relocations */
3174*4d9fdb46SRobert Mustacchi abbrev_head = abbrev_tail = NULL;
3175bc1f688bSRobert Mustacchi marker_count = 0;
3176bc1f688bSRobert Mustacchi string_attr_count = 0;
3177bc1f688bSRobert Mustacchi while (curdie != NULL) {
3178bc1f688bSRobert Mustacchi int nbytes = 0;
3179*4d9fdb46SRobert Mustacchi Dwarf_P_Attribute curattr = 0;
3180bc1f688bSRobert Mustacchi char *space = 0;
3181*4d9fdb46SRobert Mustacchi int cres = 0;
3182bc1f688bSRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED];
3183bc1f688bSRobert Mustacchi
3184bc1f688bSRobert Mustacchi curdie->di_offset = die_off;
3185bc1f688bSRobert Mustacchi
3186*4d9fdb46SRobert Mustacchi if (curdie->di_marker != 0) {
3187bc1f688bSRobert Mustacchi marker_count++;
3188*4d9fdb46SRobert Mustacchi }
3189*4d9fdb46SRobert Mustacchi cres =sort_die_attrs(dbg,curdie,error);
3190*4d9fdb46SRobert Mustacchi if (cres != DW_DLV_OK) {
3191*4d9fdb46SRobert Mustacchi /* DW_DLV_NO_ENTRY is impossible. */
3192*4d9fdb46SRobert Mustacchi return cres;
3193*4d9fdb46SRobert Mustacchi }
3194*4d9fdb46SRobert Mustacchi /* Find or create a final abbrev record for the
3195*4d9fdb46SRobert Mustacchi debug_abbrev section we will write (below). */
3196*4d9fdb46SRobert Mustacchi cres = _dwarf_pro_getabbrev(dbg,curdie, abbrev_head,&curabbrev,
3197*4d9fdb46SRobert Mustacchi error);
3198*4d9fdb46SRobert Mustacchi if (cres != DW_DLV_OK) {
3199*4d9fdb46SRobert Mustacchi return cres;
3200bc1f688bSRobert Mustacchi }
3201bc1f688bSRobert Mustacchi if (abbrev_head == NULL) {
3202bc1f688bSRobert Mustacchi n_abbrevs = 1;
3203bc1f688bSRobert Mustacchi curabbrev->abb_idx = n_abbrevs;
3204bc1f688bSRobert Mustacchi abbrev_tail = abbrev_head = curabbrev;
3205bc1f688bSRobert Mustacchi } else {
3206*4d9fdb46SRobert Mustacchi /* Check if it is a new abbreviation, if yes, add to tail */
3207bc1f688bSRobert Mustacchi if (curabbrev->abb_idx == 0) {
3208bc1f688bSRobert Mustacchi n_abbrevs++;
3209bc1f688bSRobert Mustacchi curabbrev->abb_idx = n_abbrevs;
3210bc1f688bSRobert Mustacchi abbrev_tail->abb_next = curabbrev;
3211bc1f688bSRobert Mustacchi abbrev_tail = curabbrev;
3212bc1f688bSRobert Mustacchi }
3213bc1f688bSRobert Mustacchi }
3214*4d9fdb46SRobert Mustacchi /* We know the abbrev number to use now.
3215*4d9fdb46SRobert Mustacchi So create the bytes of the leb with the
3216*4d9fdb46SRobert Mustacchi value and save those bytes in di_abbrev,
3217*4d9fdb46SRobert Mustacchi we will emit in Pass 2 (below). */
3218*4d9fdb46SRobert Mustacchi cres = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx,
3219bc1f688bSRobert Mustacchi &nbytes,
3220bc1f688bSRobert Mustacchi buff1, sizeof(buff1));
3221*4d9fdb46SRobert Mustacchi if (cres != DW_DLV_OK) {
3222*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
3223bc1f688bSRobert Mustacchi }
3224bc1f688bSRobert Mustacchi space = _dwarf_p_get_alloc(dbg, nbytes);
3225bc1f688bSRobert Mustacchi if (space == NULL) {
3226*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
3227bc1f688bSRobert Mustacchi }
3228bc1f688bSRobert Mustacchi memcpy(space, buff1, nbytes);
3229bc1f688bSRobert Mustacchi curdie->di_abbrev = space;
3230bc1f688bSRobert Mustacchi curdie->di_abbrev_nbytes = nbytes;
3231bc1f688bSRobert Mustacchi die_off += nbytes;
3232bc1f688bSRobert Mustacchi
3233*4d9fdb46SRobert Mustacchi /* The abbrev and DIE attr lists match, so the die
3234*4d9fdb46SRobert Mustacchi abbrevs are in the correct order,
3235*4d9fdb46SRobert Mustacchi curdie->di_attrs. */
3236bc1f688bSRobert Mustacchi
3237*4d9fdb46SRobert Mustacchi /* Now we attach the attributes list to the die. */
3238bc1f688bSRobert Mustacchi curattr = curdie->di_attrs;
3239bc1f688bSRobert Mustacchi
3240bc1f688bSRobert Mustacchi while (curattr) {
3241bc1f688bSRobert Mustacchi if (curattr->ar_rel_type != R_MIPS_NONE) {
3242*4d9fdb46SRobert Mustacchi int rres=0;
3243bc1f688bSRobert Mustacchi switch (curattr->ar_attribute) {
3244bc1f688bSRobert Mustacchi case DW_AT_stmt_list:
3245bc1f688bSRobert Mustacchi curattr->ar_rel_symidx =
3246bc1f688bSRobert Mustacchi dbg->de_sect_name_idx[DEBUG_LINE];
3247bc1f688bSRobert Mustacchi break;
3248bc1f688bSRobert Mustacchi case DW_AT_MIPS_fde:
3249bc1f688bSRobert Mustacchi curattr->ar_rel_symidx =
3250bc1f688bSRobert Mustacchi dbg->de_sect_name_idx[DEBUG_FRAME];
3251bc1f688bSRobert Mustacchi break;
3252bc1f688bSRobert Mustacchi case DW_AT_macro_info:
3253bc1f688bSRobert Mustacchi curattr->ar_rel_symidx =
3254bc1f688bSRobert Mustacchi dbg->de_sect_name_idx[DEBUG_MACINFO];
3255bc1f688bSRobert Mustacchi break;
3256*4d9fdb46SRobert Mustacchi /* See also: pro_forms.c for same strings attribute list. */
3257*4d9fdb46SRobert Mustacchi case DW_AT_comp_dir:
3258*4d9fdb46SRobert Mustacchi case DW_AT_const_value:
3259*4d9fdb46SRobert Mustacchi case DW_AT_linkage_name: /* DWARF5 */
3260*4d9fdb46SRobert Mustacchi case DW_AT_MIPS_abstract_name:
3261*4d9fdb46SRobert Mustacchi case DW_AT_MIPS_linkage_name:
3262*4d9fdb46SRobert Mustacchi case DW_AT_name:
3263*4d9fdb46SRobert Mustacchi case DW_AT_producer: {
3264*4d9fdb46SRobert Mustacchi int is_debug_str = 0;
3265*4d9fdb46SRobert Mustacchi int nres = if_relocatable_string_form(dbg,curattr,
3266*4d9fdb46SRobert Mustacchi &is_debug_str,error);
3267*4d9fdb46SRobert Mustacchi if (nres != DW_DLV_OK) {
3268*4d9fdb46SRobert Mustacchi return res;
3269*4d9fdb46SRobert Mustacchi }
3270*4d9fdb46SRobert Mustacchi if (is_debug_str) {
3271*4d9fdb46SRobert Mustacchi curattr->ar_rel_symidx =
3272*4d9fdb46SRobert Mustacchi dbg->de_sect_name_idx[DEBUG_STR];
3273*4d9fdb46SRobert Mustacchi }
3274*4d9fdb46SRobert Mustacchi }
3275*4d9fdb46SRobert Mustacchi break;
3276bc1f688bSRobert Mustacchi default:
3277bc1f688bSRobert Mustacchi break;
3278bc1f688bSRobert Mustacchi }
3279*4d9fdb46SRobert Mustacchi rres = dbg->de_relocate_by_name_symbol(dbg,
3280*4d9fdb46SRobert Mustacchi DEBUG_INFO,
3281*4d9fdb46SRobert Mustacchi die_off + curattr->ar_rel_offset,/* r_offset */
3282bc1f688bSRobert Mustacchi curattr->ar_rel_symidx,
3283bc1f688bSRobert Mustacchi dwarf_drt_data_reloc,
3284bc1f688bSRobert Mustacchi curattr->ar_reloc_len);
3285bc1f688bSRobert Mustacchi
3286*4d9fdb46SRobert Mustacchi if (rres != DW_DLV_OK) {
3287*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
3288bc1f688bSRobert Mustacchi }
3289bc1f688bSRobert Mustacchi }
3290bc1f688bSRobert Mustacchi if (curattr->ar_attribute_form == DW_FORM_string) {
3291bc1f688bSRobert Mustacchi string_attr_count++;
3292bc1f688bSRobert Mustacchi }
3293bc1f688bSRobert Mustacchi die_off += curattr->ar_nbytes;
3294bc1f688bSRobert Mustacchi curattr = curattr->ar_next;
3295bc1f688bSRobert Mustacchi }
3296*4d9fdb46SRobert Mustacchi /* Depth first access to all the DIEs. */
3297*4d9fdb46SRobert Mustacchi if (curdie->di_child) {
3298bc1f688bSRobert Mustacchi curdie = curdie->di_child;
3299*4d9fdb46SRobert Mustacchi } else {
3300bc1f688bSRobert Mustacchi while (curdie != NULL && curdie->di_right == NULL) {
3301bc1f688bSRobert Mustacchi curdie = curdie->di_parent;
3302*4d9fdb46SRobert Mustacchi /* See -nonrootsibling- below */
3303*4d9fdb46SRobert Mustacchi if (curdie != NULL) {
3304*4d9fdb46SRobert Mustacchi die_off++;
3305bc1f688bSRobert Mustacchi }
3306*4d9fdb46SRobert Mustacchi }
3307*4d9fdb46SRobert Mustacchi if (curdie != NULL) {
3308bc1f688bSRobert Mustacchi curdie = curdie->di_right;
3309bc1f688bSRobert Mustacchi }
3310*4d9fdb46SRobert Mustacchi }
3311bc1f688bSRobert Mustacchi
3312*4d9fdb46SRobert Mustacchi } /* end while (curdie != NULL), the per-die loop */
3313bc1f688bSRobert Mustacchi
3314bc1f688bSRobert Mustacchi res = marker_init(dbg, marker_count);
3315*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
3316*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
3317bc1f688bSRobert Mustacchi }
3318bc1f688bSRobert Mustacchi res = string_attr_init(dbg, DEBUG_INFO, string_attr_count);
3319*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
3320*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
3321bc1f688bSRobert Mustacchi }
3322bc1f688bSRobert Mustacchi
3323bc1f688bSRobert Mustacchi /* Pass 2: Write out the die information Here 'data' is a
3324bc1f688bSRobert Mustacchi temporary, one block for each GET_CHUNK. 'data' is overused. */
3325bc1f688bSRobert Mustacchi curdie = dbg->de_dies;
3326bc1f688bSRobert Mustacchi while (curdie != NULL) {
3327bc1f688bSRobert Mustacchi Dwarf_P_Attribute curattr;
3328bc1f688bSRobert Mustacchi
3329bc1f688bSRobert Mustacchi if (curdie->di_marker != 0) {
3330bc1f688bSRobert Mustacchi res = marker_add(dbg, curdie->di_offset, curdie->di_marker);
3331*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
3332*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
3333bc1f688bSRobert Mustacchi }
3334bc1f688bSRobert Mustacchi }
3335bc1f688bSRobert Mustacchi
3336*4d9fdb46SRobert Mustacchi /* Index to abbreviation table */
3337*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, elfsectno_of_debug_info,
3338bc1f688bSRobert Mustacchi data, curdie->di_abbrev_nbytes, error);
3339bc1f688bSRobert Mustacchi memcpy((void *) data,
3340bc1f688bSRobert Mustacchi (const void *) curdie->di_abbrev,
3341bc1f688bSRobert Mustacchi curdie->di_abbrev_nbytes);
3342bc1f688bSRobert Mustacchi
3343bc1f688bSRobert Mustacchi /* Attribute values - need to fill in all form attributes */
3344bc1f688bSRobert Mustacchi curattr = curdie->di_attrs;
3345*4d9fdb46SRobert Mustacchi string_attr_offset = curdie->di_offset +
3346*4d9fdb46SRobert Mustacchi curdie->di_abbrev_nbytes;
3347bc1f688bSRobert Mustacchi while (curattr) {
3348*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data,
3349bc1f688bSRobert Mustacchi (unsigned long) curattr->ar_nbytes, error);
3350bc1f688bSRobert Mustacchi switch (curattr->ar_attribute_form) {
3351bc1f688bSRobert Mustacchi case DW_FORM_ref1:
3352bc1f688bSRobert Mustacchi {
3353*4d9fdb46SRobert Mustacchi Dwarf_Ubyte db = 0;
3354bc1f688bSRobert Mustacchi if (curattr->ar_ref_die->di_offset >
3355bc1f688bSRobert Mustacchi (unsigned) 0xff) {
3356*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR);
3357bc1f688bSRobert Mustacchi }
3358bc1f688bSRobert Mustacchi db = curattr->ar_ref_die->di_offset;
3359bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
3360bc1f688bSRobert Mustacchi (const void *) &db,
3361bc1f688bSRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte));
3362bc1f688bSRobert Mustacchi break;
3363bc1f688bSRobert Mustacchi }
3364bc1f688bSRobert Mustacchi case DW_FORM_ref2:
3365bc1f688bSRobert Mustacchi {
3366bc1f688bSRobert Mustacchi if (curattr->ar_ref_die->di_offset >
3367bc1f688bSRobert Mustacchi (unsigned) 0xffff) {
3368*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR);
3369bc1f688bSRobert Mustacchi }
3370bc1f688bSRobert Mustacchi dh = curattr->ar_ref_die->di_offset;
3371bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
3372bc1f688bSRobert Mustacchi (const void *) &dh,
3373*4d9fdb46SRobert Mustacchi sizeof(dh), DWARF_HALF_SIZE);
3374bc1f688bSRobert Mustacchi break;
3375bc1f688bSRobert Mustacchi }
3376bc1f688bSRobert Mustacchi case DW_FORM_ref_addr:
3377bc1f688bSRobert Mustacchi {
3378bc1f688bSRobert Mustacchi /* curattr->ar_ref_die == NULL!
3379*4d9fdb46SRobert Mustacchi
3380*4d9fdb46SRobert Mustacchi DW_FORM_ref_addr doesn't take a CU-offset.
3381*4d9fdb46SRobert Mustacchi This is different than other refs.
3382*4d9fdb46SRobert Mustacchi This value will be set by the user of the
3383*4d9fdb46SRobert Mustacchi producer library using a relocation.
3384*4d9fdb46SRobert Mustacchi No need to set a value here. */
3385bc1f688bSRobert Mustacchi break;
3386bc1f688bSRobert Mustacchi
3387bc1f688bSRobert Mustacchi }
3388bc1f688bSRobert Mustacchi case DW_FORM_ref4:
3389bc1f688bSRobert Mustacchi {
3390bc1f688bSRobert Mustacchi if (curattr->ar_ref_die->di_offset >
3391bc1f688bSRobert Mustacchi (unsigned) 0xffffffff) {
3392*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW,
3393*4d9fdb46SRobert Mustacchi DW_DLV_ERROR);
3394bc1f688bSRobert Mustacchi }
3395*4d9fdb46SRobert Mustacchi dw = (Dwarf_Unsigned) curattr->ar_ref_die->di_offset;
3396bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
3397bc1f688bSRobert Mustacchi (const void *) &dw,
3398*4d9fdb46SRobert Mustacchi sizeof(dw), DWARF_32BIT_SIZE);
3399bc1f688bSRobert Mustacchi break;
3400bc1f688bSRobert Mustacchi }
3401bc1f688bSRobert Mustacchi case DW_FORM_ref8:
3402bc1f688bSRobert Mustacchi du = curattr->ar_ref_die->di_offset;
3403bc1f688bSRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data,
3404bc1f688bSRobert Mustacchi (const void *) &du,
3405*4d9fdb46SRobert Mustacchi sizeof(du), DWARF_64BIT_SIZE);
3406bc1f688bSRobert Mustacchi break;
3407bc1f688bSRobert Mustacchi case DW_FORM_ref_udata:
3408bc1f688bSRobert Mustacchi { /* unsigned leb128 offset */
3409bc1f688bSRobert Mustacchi
3410*4d9fdb46SRobert Mustacchi int nbytesx;
3411bc1f688bSRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED];
3412bc1f688bSRobert Mustacchi
3413bc1f688bSRobert Mustacchi res =
3414bc1f688bSRobert Mustacchi _dwarf_pro_encode_leb128_nm(curattr->
3415bc1f688bSRobert Mustacchi ar_ref_die->
3416*4d9fdb46SRobert Mustacchi di_offset, &nbytesx,
3417bc1f688bSRobert Mustacchi buff1,
3418bc1f688bSRobert Mustacchi sizeof(buff1));
3419bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
3420*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC,
3421*4d9fdb46SRobert Mustacchi DW_DLV_ERROR);
3422bc1f688bSRobert Mustacchi }
3423*4d9fdb46SRobert Mustacchi memcpy(data, buff1, nbytesx);
3424bc1f688bSRobert Mustacchi break;
3425bc1f688bSRobert Mustacchi }
3426bc1f688bSRobert Mustacchi default:
3427*4d9fdb46SRobert Mustacchi if(curattr->ar_nbytes) {
3428bc1f688bSRobert Mustacchi memcpy((void *) data,
3429bc1f688bSRobert Mustacchi (const void *) curattr->ar_data,
3430bc1f688bSRobert Mustacchi curattr->ar_nbytes);
3431*4d9fdb46SRobert Mustacchi }
3432bc1f688bSRobert Mustacchi break;
3433bc1f688bSRobert Mustacchi }
3434bc1f688bSRobert Mustacchi if (curattr->ar_attribute_form == DW_FORM_string) {
3435bc1f688bSRobert Mustacchi string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr);
3436bc1f688bSRobert Mustacchi }
3437bc1f688bSRobert Mustacchi string_attr_offset += curattr->ar_nbytes;
3438bc1f688bSRobert Mustacchi curattr = curattr->ar_next;
3439bc1f688bSRobert Mustacchi }
3440bc1f688bSRobert Mustacchi
3441bc1f688bSRobert Mustacchi /* depth first search */
3442*4d9fdb46SRobert Mustacchi if (curdie->di_child) {
3443bc1f688bSRobert Mustacchi curdie = curdie->di_child;
3444*4d9fdb46SRobert Mustacchi } else {
3445bc1f688bSRobert Mustacchi while (curdie != NULL && curdie->di_right == NULL) {
3446*4d9fdb46SRobert Mustacchi /* -nonrootsibling-
3447*4d9fdb46SRobert Mustacchi A null die should only be written for terminating
3448*4d9fdb46SRobert Mustacchi siblings, not the root. Adding a terminating die
3449*4d9fdb46SRobert Mustacchi for the root will cause, after object files are
3450*4d9fdb46SRobert Mustacchi linked, warnings to be generated with newer
3451*4d9fdb46SRobert Mustacchi versions of readelf. */
3452*4d9fdb46SRobert Mustacchi if (!curdie->di_parent) {
3453*4d9fdb46SRobert Mustacchi /* The parent is not a DIE so ending a sibling
3454*4d9fdb46SRobert Mustacchi chain makes no sense (wastes a byte). */
3455*4d9fdb46SRobert Mustacchi break;
3456*4d9fdb46SRobert Mustacchi }
3457*4d9fdb46SRobert Mustacchi GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, 1, error);
3458bc1f688bSRobert Mustacchi *data = '\0';
3459bc1f688bSRobert Mustacchi curdie = curdie->di_parent;
3460bc1f688bSRobert Mustacchi }
3461bc1f688bSRobert Mustacchi if (curdie != NULL)
3462bc1f688bSRobert Mustacchi curdie = curdie->di_right;
3463bc1f688bSRobert Mustacchi }
3464bc1f688bSRobert Mustacchi } /* end while (curdir != NULL) */
3465bc1f688bSRobert Mustacchi
3466*4d9fdb46SRobert Mustacchi /* Write out debug_info size, now that we know it
3467*4d9fdb46SRobert Mustacchi This is back-patching the CU header we created
3468*4d9fdb46SRobert Mustacchi above. */
3469*4d9fdb46SRobert Mustacchi du = die_off - OFFSET_PLUS_EXTENSION_SIZE;
3470*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) abbr_off_ptr,
3471*4d9fdb46SRobert Mustacchi (const void *) &du, sizeof(du), offset_size);
3472bc1f688bSRobert Mustacchi
3473bc1f688bSRobert Mustacchi
3474bc1f688bSRobert Mustacchi data = 0; /* Emphasise not usable now */
3475bc1f688bSRobert Mustacchi
3476*4d9fdb46SRobert Mustacchi res = write_out_debug_abbrev(dbg,
3477*4d9fdb46SRobert Mustacchi abbrev_head, error);
3478bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
3479*4d9fdb46SRobert Mustacchi return res;
3480bc1f688bSRobert Mustacchi }
3481bc1f688bSRobert Mustacchi
3482*4d9fdb46SRobert Mustacchi *nbufs = dbg->de_n_debug_sect;
3483*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
3484bc1f688bSRobert Mustacchi }
3485bc1f688bSRobert Mustacchi
3486*4d9fdb46SRobert Mustacchi static int
_dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg,UNUSEDARG Dwarf_Signed * nbufs,Dwarf_Error * error UNUSEDARG)3487*4d9fdb46SRobert Mustacchi _dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg,
3488*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Signed *nbufs,
3489*4d9fdb46SRobert Mustacchi Dwarf_Error * error UNUSEDARG)
3490*4d9fdb46SRobert Mustacchi {
3491*4d9fdb46SRobert Mustacchi #if 0
3492*4d9fdb46SRobert Mustacchi int elfsectno_of_debug_names = dbg->de_elf_sects[DEBUG_NAMES];
3493*4d9fdb46SRobert Mustacchi FIXME: Needs implementation
3494*4d9fdb46SRobert Mustacchi unsigned char *data = 0;
3495bc1f688bSRobert Mustacchi
3496*4d9fdb46SRobert Mustacchi GET_CHUNK(dbg, elfsectno_of_debug_names, data,
3497*4d9fdb46SRobert Mustacchi dbg->de_debug_names->ds_nbytes,
3498*4d9fdb46SRobert Mustacchi error);
3499*4d9fdb46SRobert Mustacchi memcpy(data,dbg->de_debug_names->ds_data,dbg->de_debug_names->ds_nbytes);
3500*4d9fdb46SRobert Mustacchi #endif
3501*4d9fdb46SRobert Mustacchi *nbufs = dbg->de_n_debug_sect;
3502*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
3503*4d9fdb46SRobert Mustacchi }
3504bc1f688bSRobert Mustacchi
3505*4d9fdb46SRobert Mustacchi static int
_dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)3506*4d9fdb46SRobert Mustacchi _dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg,
3507*4d9fdb46SRobert Mustacchi Dwarf_Signed *nbufs,
3508*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
3509*4d9fdb46SRobert Mustacchi {
3510*4d9fdb46SRobert Mustacchi int elfsectno_of_debug_str = 0;
3511*4d9fdb46SRobert Mustacchi unsigned char *data = 0;
3512*4d9fdb46SRobert Mustacchi
3513*4d9fdb46SRobert Mustacchi elfsectno_of_debug_str = dbg->de_elf_sects[DEBUG_STR];
3514*4d9fdb46SRobert Mustacchi GET_CHUNK(dbg, elfsectno_of_debug_str, data, dbg->de_debug_str->ds_nbytes,
3515*4d9fdb46SRobert Mustacchi error);
3516*4d9fdb46SRobert Mustacchi memcpy(data,dbg->de_debug_str->ds_data,dbg->de_debug_str->ds_nbytes);
3517*4d9fdb46SRobert Mustacchi *nbufs = dbg->de_n_debug_sect;
3518*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
3519*4d9fdb46SRobert Mustacchi }
3520*4d9fdb46SRobert Mustacchi static int
_dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)3521*4d9fdb46SRobert Mustacchi _dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg,
3522*4d9fdb46SRobert Mustacchi Dwarf_Signed *nbufs,
3523*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
3524*4d9fdb46SRobert Mustacchi {
3525*4d9fdb46SRobert Mustacchi int elfsectno_of_debug_line_str = 0;
3526*4d9fdb46SRobert Mustacchi unsigned char *data = 0;
3527*4d9fdb46SRobert Mustacchi
3528*4d9fdb46SRobert Mustacchi elfsectno_of_debug_line_str = dbg->de_elf_sects[DEBUG_LINE_STR];
3529*4d9fdb46SRobert Mustacchi GET_CHUNK(dbg, elfsectno_of_debug_line_str, data,
3530*4d9fdb46SRobert Mustacchi dbg->de_debug_line_str->ds_nbytes,
3531*4d9fdb46SRobert Mustacchi error);
3532*4d9fdb46SRobert Mustacchi memcpy(data,dbg->de_debug_line_str->ds_data,
3533*4d9fdb46SRobert Mustacchi dbg->de_debug_line_str->ds_nbytes);
3534*4d9fdb46SRobert Mustacchi *nbufs = dbg->de_n_debug_sect;
3535*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
3536bc1f688bSRobert Mustacchi }
3537bc1f688bSRobert Mustacchi
3538bc1f688bSRobert Mustacchi
3539*4d9fdb46SRobert Mustacchi /* Get a buffer of section data.
3540bc1f688bSRobert Mustacchi section_idx is the elf-section number that this data applies to.
3541bc1f688bSRobert Mustacchi length shows length of returned data
3542*4d9fdb46SRobert Mustacchi This is the original format. Hard to check for error. */
3543*4d9fdb46SRobert Mustacchi
3544bc1f688bSRobert Mustacchi /*ARGSUSED*/ /* pretend all args used */
3545bc1f688bSRobert Mustacchi Dwarf_Ptr
dwarf_get_section_bytes(Dwarf_P_Debug dbg,UNUSEDARG Dwarf_Signed dwarf_section,Dwarf_Signed * section_idx,Dwarf_Unsigned * length,Dwarf_Error * error)3546bc1f688bSRobert Mustacchi dwarf_get_section_bytes(Dwarf_P_Debug dbg,
3547*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Signed dwarf_section,
3548bc1f688bSRobert Mustacchi Dwarf_Signed * section_idx,
3549bc1f688bSRobert Mustacchi Dwarf_Unsigned * length, Dwarf_Error * error)
3550bc1f688bSRobert Mustacchi {
3551*4d9fdb46SRobert Mustacchi Dwarf_Ptr s_bytes = 0;
3552*4d9fdb46SRobert Mustacchi int res = 0;
3553bc1f688bSRobert Mustacchi
3554*4d9fdb46SRobert Mustacchi res = dwarf_get_section_bytes_a(dbg,
3555*4d9fdb46SRobert Mustacchi dwarf_section,
3556*4d9fdb46SRobert Mustacchi section_idx,
3557*4d9fdb46SRobert Mustacchi length,
3558*4d9fdb46SRobert Mustacchi &s_bytes,
3559*4d9fdb46SRobert Mustacchi error);
3560*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
3561*4d9fdb46SRobert Mustacchi return (Dwarf_Ptr)DW_DLV_BADADDR;
3562*4d9fdb46SRobert Mustacchi }
3563*4d9fdb46SRobert Mustacchi if (res == DW_DLV_NO_ENTRY) {
3564*4d9fdb46SRobert Mustacchi return NULL;
3565*4d9fdb46SRobert Mustacchi }
3566*4d9fdb46SRobert Mustacchi return s_bytes;
3567bc1f688bSRobert Mustacchi }
3568bc1f688bSRobert Mustacchi
3569*4d9fdb46SRobert Mustacchi /* Get a buffer of section data.
3570*4d9fdb46SRobert Mustacchi section_idx is the elf-section number that this data applies to.
3571*4d9fdb46SRobert Mustacchi length shows length of returned data
3572*4d9fdb46SRobert Mustacchi This is the September 2016 format. Preferred. */
3573*4d9fdb46SRobert Mustacchi int
dwarf_get_section_bytes_a(Dwarf_P_Debug dbg,UNUSEDARG Dwarf_Signed dwarf_section,Dwarf_Signed * section_idx,Dwarf_Unsigned * length,Dwarf_Ptr * section_bytes,Dwarf_Error * error)3574*4d9fdb46SRobert Mustacchi dwarf_get_section_bytes_a(Dwarf_P_Debug dbg,
3575*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Signed dwarf_section,
3576*4d9fdb46SRobert Mustacchi Dwarf_Signed * section_idx,
3577*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * length,
3578*4d9fdb46SRobert Mustacchi Dwarf_Ptr * section_bytes,
3579*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
3580*4d9fdb46SRobert Mustacchi {
3581*4d9fdb46SRobert Mustacchi Dwarf_Ptr buf = 0;
3582*4d9fdb46SRobert Mustacchi
3583*4d9fdb46SRobert Mustacchi if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
3584*4d9fdb46SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR);
3585*4d9fdb46SRobert Mustacchi }
3586*4d9fdb46SRobert Mustacchi *section_bytes = 0;
3587*4d9fdb46SRobert Mustacchi *length = 0;
3588bc1f688bSRobert Mustacchi if (dbg->de_debug_sects == 0) {
3589bc1f688bSRobert Mustacchi /* no more data !! */
3590*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
3591bc1f688bSRobert Mustacchi }
3592bc1f688bSRobert Mustacchi if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
3593bc1f688bSRobert Mustacchi /* no data ever entered !! */
3594*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
3595bc1f688bSRobert Mustacchi }
3596bc1f688bSRobert Mustacchi *section_idx = dbg->de_debug_sects->ds_elf_sect_no;
3597bc1f688bSRobert Mustacchi *length = dbg->de_debug_sects->ds_nbytes;
3598bc1f688bSRobert Mustacchi
3599bc1f688bSRobert Mustacchi buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data;
3600bc1f688bSRobert Mustacchi
3601*4d9fdb46SRobert Mustacchi /* Here is the iterator so the next call gets
3602*4d9fdb46SRobert Mustacchi the next section. */
3603bc1f688bSRobert Mustacchi dbg->de_debug_sects = dbg->de_debug_sects->ds_next;
3604bc1f688bSRobert Mustacchi
3605bc1f688bSRobert Mustacchi /* We may want to call the section stuff more than once: see
3606bc1f688bSRobert Mustacchi dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */
3607bc1f688bSRobert Mustacchi
3608*4d9fdb46SRobert Mustacchi *section_bytes = buf;
3609*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
3610bc1f688bSRobert Mustacchi }
3611bc1f688bSRobert Mustacchi
3612*4d9fdb46SRobert Mustacchi /* No errors possible. */
3613bc1f688bSRobert Mustacchi void
dwarf_reset_section_bytes(Dwarf_P_Debug dbg)3614bc1f688bSRobert Mustacchi dwarf_reset_section_bytes(Dwarf_P_Debug dbg)
3615bc1f688bSRobert Mustacchi {
3616bc1f688bSRobert Mustacchi dbg->de_debug_sects = dbg->de_first_debug_sect;
3617bc1f688bSRobert Mustacchi /* No need to reset; commented out decrement. dbg->de_n_debug_sect
3618bc1f688bSRobert Mustacchi = ???; */
3619bc1f688bSRobert Mustacchi dbg->de_reloc_next_to_return = 0;
3620bc1f688bSRobert Mustacchi dbg->de_sect_sa_next_to_return = 0;
3621bc1f688bSRobert Mustacchi }
3622bc1f688bSRobert Mustacchi
3623*4d9fdb46SRobert Mustacchi /* Storage handler. Gets either a new chunk of memory, or
3624bc1f688bSRobert Mustacchi a pointer in existing memory, from the linked list attached
3625bc1f688bSRobert Mustacchi to dbg at de_debug_sects, depending on size of nbytes
3626bc1f688bSRobert Mustacchi
3627bc1f688bSRobert Mustacchi Assume dbg not null, checked in top level routine
3628bc1f688bSRobert Mustacchi
3629bc1f688bSRobert Mustacchi Returns a pointer to the allocated buffer space for the
3630bc1f688bSRobert Mustacchi lib to fill in, predincrements next-to-use count so the
3631bc1f688bSRobert Mustacchi space requested is already counted 'used'
3632bc1f688bSRobert Mustacchi when this returns (ie, reserved).
3633bc1f688bSRobert Mustacchi
3634bc1f688bSRobert Mustacchi */
3635bc1f688bSRobert Mustacchi Dwarf_Small *
_dwarf_pro_buffer(Dwarf_P_Debug dbg,int elfsectno,unsigned long nbytes)3636bc1f688bSRobert Mustacchi _dwarf_pro_buffer(Dwarf_P_Debug dbg,
3637bc1f688bSRobert Mustacchi int elfsectno, unsigned long nbytes)
3638bc1f688bSRobert Mustacchi {
3639*4d9fdb46SRobert Mustacchi Dwarf_P_Section_Data cursect = 0;
3640bc1f688bSRobert Mustacchi
3641bc1f688bSRobert Mustacchi cursect = dbg->de_current_active_section;
3642bc1f688bSRobert Mustacchi /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must
3643bc1f688bSRobert Mustacchi not match any legit section number. test to have just two
3644bc1f688bSRobert Mustacchi clauses (no NULL pointer test) See dwarf_producer_init(). */
3645bc1f688bSRobert Mustacchi if ((cursect->ds_elf_sect_no != elfsectno) ||
3646bc1f688bSRobert Mustacchi ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc)
3647bc1f688bSRobert Mustacchi ) {
3648bc1f688bSRobert Mustacchi
3649bc1f688bSRobert Mustacchi /* Either the elf section has changed or there is not enough
3650bc1f688bSRobert Mustacchi space in the current section.
3651bc1f688bSRobert Mustacchi
3652bc1f688bSRobert Mustacchi Create a new Dwarf_P_Section_Data_s for the chunk. and have
3653bc1f688bSRobert Mustacchi space 'on the end' for the buffer itself so we just do one
3654*4d9fdb46SRobert Mustacchi malloc (not two). */
3655bc1f688bSRobert Mustacchi unsigned long space = nbytes;
3656bc1f688bSRobert Mustacchi
3657bc1f688bSRobert Mustacchi if (nbytes < CHUNK_SIZE)
3658bc1f688bSRobert Mustacchi space = CHUNK_SIZE;
3659bc1f688bSRobert Mustacchi
3660bc1f688bSRobert Mustacchi cursect = (Dwarf_P_Section_Data)
3661bc1f688bSRobert Mustacchi _dwarf_p_get_alloc(dbg,
3662bc1f688bSRobert Mustacchi sizeof(struct Dwarf_P_Section_Data_s)
3663bc1f688bSRobert Mustacchi + space);
3664*4d9fdb46SRobert Mustacchi if (cursect == NULL) {
3665bc1f688bSRobert Mustacchi return (NULL);
3666*4d9fdb46SRobert Mustacchi }
3667bc1f688bSRobert Mustacchi
3668bc1f688bSRobert Mustacchi /* _dwarf_p_get_alloc zeroes the space... */
3669bc1f688bSRobert Mustacchi
3670bc1f688bSRobert Mustacchi cursect->ds_data = (char *) cursect +
3671bc1f688bSRobert Mustacchi sizeof(struct Dwarf_P_Section_Data_s);
3672bc1f688bSRobert Mustacchi cursect->ds_orig_alloc = space;
3673bc1f688bSRobert Mustacchi cursect->ds_elf_sect_no = elfsectno;
3674bc1f688bSRobert Mustacchi cursect->ds_nbytes = nbytes; /* reserve this number of bytes
3675*4d9fdb46SRobert Mustacchi of space for caller to fill in */
3676bc1f688bSRobert Mustacchi /* Now link on the end of the list, and mark this one as the
3677bc1f688bSRobert Mustacchi current one */
3678bc1f688bSRobert Mustacchi
3679bc1f688bSRobert Mustacchi if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
3680*4d9fdb46SRobert Mustacchi /* The only entry is the special one for 'no entry' so
3681bc1f688bSRobert Mustacchi delete that phony one while adding this initial real
3682bc1f688bSRobert Mustacchi one. */
3683bc1f688bSRobert Mustacchi dbg->de_debug_sects = cursect;
3684bc1f688bSRobert Mustacchi dbg->de_current_active_section = cursect;
3685bc1f688bSRobert Mustacchi dbg->de_first_debug_sect = cursect;
3686bc1f688bSRobert Mustacchi } else {
3687bc1f688bSRobert Mustacchi dbg->de_current_active_section->ds_next = cursect;
3688bc1f688bSRobert Mustacchi dbg->de_current_active_section = cursect;
3689bc1f688bSRobert Mustacchi }
3690bc1f688bSRobert Mustacchi dbg->de_n_debug_sect++;
3691bc1f688bSRobert Mustacchi
3692bc1f688bSRobert Mustacchi return ((Dwarf_Small *) cursect->ds_data);
3693bc1f688bSRobert Mustacchi }
3694bc1f688bSRobert Mustacchi
3695bc1f688bSRobert Mustacchi /* There is enough space in the current buffer */
3696bc1f688bSRobert Mustacchi {
3697bc1f688bSRobert Mustacchi Dwarf_Small *space_for_caller = (Dwarf_Small *)
3698bc1f688bSRobert Mustacchi (cursect->ds_data + cursect->ds_nbytes);
3699bc1f688bSRobert Mustacchi
3700bc1f688bSRobert Mustacchi cursect->ds_nbytes += nbytes;
3701bc1f688bSRobert Mustacchi return space_for_caller;
3702bc1f688bSRobert Mustacchi }
3703bc1f688bSRobert Mustacchi }
3704