xref: /illumos-gate/usr/src/lib/libdwarf/common/pro_section.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
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