149d3bc91SRichard Lowe /*
207dc1947SRichard Lowe   Copyright (C) 2000,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
3*4d9fdb46SRobert Mustacchi   Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved.
407dc1947SRichard Lowe   Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
5*4d9fdb46SRobert Mustacchi   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
6*4d9fdb46SRobert 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.
11*4d9fdb46SRobert 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.
16*4d9fdb46SRobert 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.
24*4d9fdb46SRobert 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.
2949d3bc91SRichard Lowe 
3007dc1947SRichard Lowe */
3107dc1947SRichard Lowe 
3249d3bc91SRichard Lowe #include "config.h"
3349d3bc91SRichard Lowe #include "libdwarfdefs.h"
3449d3bc91SRichard Lowe #include <stdio.h>
35*4d9fdb46SRobert Mustacchi #ifdef HAVE_STRING_H
3649d3bc91SRichard Lowe #include <string.h>
37*4d9fdb46SRobert Mustacchi #endif /* HAVE_STRING_H */
3849d3bc91SRichard Lowe #ifdef   HAVE_ELFACCESS_H
3949d3bc91SRichard Lowe #include <elfaccess.h>
4049d3bc91SRichard Lowe #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 */
5149d3bc91SRichard Lowe #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"
5949d3bc91SRichard Lowe #include "pro_section.h"
6049d3bc91SRichard Lowe #include "pro_line.h"
6149d3bc91SRichard Lowe #include "pro_frame.h"
6249d3bc91SRichard Lowe #include "pro_die.h"
6349d3bc91SRichard Lowe #include "pro_macinfo.h"
6449d3bc91SRichard Lowe #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 */
7149d3bc91SRichard Lowe 
7249d3bc91SRichard Lowe #ifndef SHF_MIPS_NOSTRIP
7349d3bc91SRichard Lowe /* if this is not defined, we probably don't need it: just use 0 */
7449d3bc91SRichard Lowe #define SHF_MIPS_NOSTRIP 0
7549d3bc91SRichard Lowe #endif
7649d3bc91SRichard Lowe #ifndef R_MIPS_NONE
7749d3bc91SRichard Lowe #define R_MIPS_NONE 0
7849d3bc91SRichard Lowe #endif
7949d3bc91SRichard Lowe 
8049d3bc91SRichard Lowe #ifndef TRUE
8149d3bc91SRichard Lowe #define TRUE 1
8249d3bc91SRichard Lowe #endif
8349d3bc91SRichard Lowe #ifndef FALSE
8449d3bc91SRichard Lowe #define FALSE 0
8549d3bc91SRichard Lowe #endif
8649d3bc91SRichard Lowe 
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
12507dc1947SRichard Lowe and sectnames (below).  REL_SEC_PREFIX is either ".rel" or ".rela"
12607dc1947SRichard Lowe see pro_incl.h
12749d3bc91SRichard Lowe */
128*4d9fdb46SRobert Mustacchi const char *_dwarf_rel_section_names[] = {
12907dc1947SRichard Lowe     REL_SEC_PREFIX ".debug_info",
13007dc1947SRichard Lowe     REL_SEC_PREFIX ".debug_line",
131*4d9fdb46SRobert Mustacchi     REL_SEC_PREFIX ".debug_abbrev",     /* Nothing here refers to anything. */
13207dc1947SRichard Lowe     REL_SEC_PREFIX ".debug_frame",
13307dc1947SRichard Lowe     REL_SEC_PREFIX ".debug_aranges",
13407dc1947SRichard Lowe     REL_SEC_PREFIX ".debug_pubnames",
13507dc1947SRichard Lowe     REL_SEC_PREFIX ".debug_funcnames",  /* sgi extension */
13607dc1947SRichard Lowe     REL_SEC_PREFIX ".debug_typenames",  /* sgi extension */
13707dc1947SRichard Lowe     REL_SEC_PREFIX ".debug_varnames",   /* sgi extension */
13807dc1947SRichard Lowe     REL_SEC_PREFIX ".debug_weaknames",  /* sgi extension */
13907dc1947SRichard Lowe     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. */
15149d3bc91SRichard Lowe };
15249d3bc91SRichard Lowe 
153*4d9fdb46SRobert Mustacchi /*  names of sections. Ensure that it matches the defines
154*4d9fdb46SRobert Mustacchi     in pro_section.h, in the same order
155*4d9fdb46SRobert Mustacchi     Must match also _dwarf_rel_section_names above
15649d3bc91SRichard Lowe */
157*4d9fdb46SRobert Mustacchi const char *_dwarf_sectnames[] = {
15849d3bc91SRichard Lowe     ".debug_info",
15949d3bc91SRichard Lowe     ".debug_line",
16049d3bc91SRichard Lowe     ".debug_abbrev",
16149d3bc91SRichard Lowe     ".debug_frame",
16249d3bc91SRichard Lowe     ".debug_aranges",
16349d3bc91SRichard Lowe     ".debug_pubnames",
16407dc1947SRichard Lowe     ".debug_funcnames",         /* sgi extension */
16507dc1947SRichard Lowe     ".debug_typenames",         /* sgi extension */
16607dc1947SRichard Lowe     ".debug_varnames",          /* sgi extension */
16707dc1947SRichard Lowe     ".debug_weaknames",         /* sgi extension */
16849d3bc91SRichard Lowe     ".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 */
17949d3bc91SRichard Lowe };
18049d3bc91SRichard Lowe 
18149d3bc91SRichard Lowe 
18249d3bc91SRichard Lowe 
18349d3bc91SRichard Lowe 
184*4d9fdb46SRobert Mustacchi static const Dwarf_Ubyte std_opcode_len[] = { 0, /* DW_LNS_copy */
18507dc1947SRichard Lowe     1,                          /* DW_LNS_advance_pc */
18607dc1947SRichard Lowe     1,                          /* DW_LNS_advance_line */
18707dc1947SRichard Lowe     1,                          /* DW_LNS_set_file */
18807dc1947SRichard Lowe     1,                          /* DW_LNS_set_column */
18907dc1947SRichard Lowe     0,                          /* DW_LNS_negate_stmt */
19007dc1947SRichard Lowe     0,                          /* DW_LNS_set_basic_block */
19107dc1947SRichard Lowe     0,                          /* DW_LNS_const_add_pc */
19207dc1947SRichard Lowe     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 */
19849d3bc91SRichard Lowe };
19949d3bc91SRichard Lowe 
200*4d9fdb46SRobert Mustacchi /*  struct to hold relocation entries. Its mantained as a linked
201*4d9fdb46SRobert Mustacchi     list of relocation structs, and will then be written at as a
202*4d9fdb46SRobert Mustacchi     whole into the relocation section. Whether its 32 bit or
203*4d9fdb46SRobert Mustacchi     64 bit will be obtained from Dwarf_Debug pointer.
20449d3bc91SRichard Lowe */
20549d3bc91SRichard Lowe 
20649d3bc91SRichard Lowe typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel;
20749d3bc91SRichard Lowe struct Dwarf_P_Rel_s {
20849d3bc91SRichard Lowe     Dwarf_P_Rel dr_next;
20949d3bc91SRichard Lowe     void *dr_rel_datap;
21049d3bc91SRichard Lowe };
21149d3bc91SRichard Lowe typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head;
21249d3bc91SRichard Lowe struct Dwarf_P_Rel_Head_s {
21349d3bc91SRichard Lowe     struct Dwarf_P_Rel_s *drh_head;
21449d3bc91SRichard Lowe     struct Dwarf_P_Rel_s *drh_tail;
21549d3bc91SRichard Lowe };
21649d3bc91SRichard Lowe 
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);
22449d3bc91SRichard Lowe static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
225*4d9fdb46SRobert Mustacchi     Dwarf_Signed *nbufs, Dwarf_Error * error);
22649d3bc91SRichard Lowe static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
227*4d9fdb46SRobert Mustacchi     Dwarf_Signed *nbufs, Dwarf_Error * error);
22849d3bc91SRichard Lowe static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
229*4d9fdb46SRobert Mustacchi     Dwarf_Signed *nbufs, Dwarf_Error * error);
230*4d9fdb46SRobert 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 
27849d3bc91SRichard Lowe 
279*4d9fdb46SRobert Mustacchi /* These macros used as return value for _dwarf_pro_get_opc. */
28007dc1947SRichard Lowe #define         OPC_INCS_ZERO           -1
28107dc1947SRichard Lowe #define         OPC_OUT_OF_RANGE        -2
28207dc1947SRichard Lowe #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 }
316*4d9fdb46SRobert Mustacchi 
31749d3bc91SRichard Lowe 
31849d3bc91SRichard Lowe 
319*4d9fdb46SRobert Mustacchi /*  OFFSET_PLUS_EXTENSION_SIZE is the size of the 'length' field in total.
320*4d9fdb46SRobert Mustacchi     Which may be 4,8, or 12 bytes!
321*4d9fdb46SRobert Mustacchi     4 is standard DWARF2.
322*4d9fdb46SRobert Mustacchi     8 is non-standard MIPS-IRIX 64-bit.
323*4d9fdb46SRobert Mustacchi     12 is standard DWARF3 for 64 bit offsets.
324*4d9fdb46SRobert Mustacchi     Used in various routines: local variable names
325*4d9fdb46SRobert Mustacchi     must match the names here.
32607dc1947SRichard Lowe */
327*4d9fdb46SRobert Mustacchi #define OFFSET_PLUS_EXTENSION_SIZE (offset_size + extension_size)
32849d3bc91SRichard Lowe 
329*4d9fdb46SRobert Mustacchi /*  Return TRUE if we need the section, FALSE otherwise
33049d3bc91SRichard Lowe 
331*4d9fdb46SRobert Mustacchi     If any of the 'line-data-related' calls were made
332*4d9fdb46SRobert Mustacchi     including file or directory entries,
333*4d9fdb46SRobert Mustacchi     produce .debug_line .
33449d3bc91SRichard Lowe 
33549d3bc91SRichard Lowe */
33649d3bc91SRichard Lowe static int
dwarf_need_debug_line_section(Dwarf_P_Debug dbg)33749d3bc91SRichard Lowe dwarf_need_debug_line_section(Dwarf_P_Debug dbg)
33849d3bc91SRichard Lowe {
339*4d9fdb46SRobert Mustacchi     if (dbg->de_output_version > 4) {
340*4d9fdb46SRobert Mustacchi         return FALSE;
341*4d9fdb46SRobert Mustacchi     }
34249d3bc91SRichard Lowe     if (dbg->de_lines == NULL && dbg->de_file_entries == NULL
34307dc1947SRichard Lowe         && dbg->de_inc_dirs == NULL) {
34407dc1947SRichard Lowe         return FALSE;
34549d3bc91SRichard Lowe     }
34649d3bc91SRichard Lowe     return TRUE;
34749d3bc91SRichard Lowe }
34849d3bc91SRichard Lowe 
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
36649d3bc91SRichard Lowe     it can be written on disk.
36749d3bc91SRichard Lowe     Called exactly once per execution.
368*4d9fdb46SRobert Mustacchi     This is the traditional interface. Bad interface design.
36949d3bc91SRichard Lowe */
37049d3bc91SRichard Lowe Dwarf_Signed
dwarf_transform_to_disk_form(Dwarf_P_Debug dbg,Dwarf_Error * error)37149d3bc91SRichard Lowe dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error)
37249d3bc91SRichard Lowe {
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
393*4d9fdb46SRobert 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
396*4d9fdb46SRobert Mustacchi         buffers one at a time. */
397*4d9fdb46SRobert Mustacchi     Dwarf_Signed nbufs = 0;
39807dc1947SRichard Lowe     int sect = 0;
39907dc1947SRichard Lowe     int err = 0;
40007dc1947SRichard Lowe     Dwarf_Unsigned du = 0;
40149d3bc91SRichard Lowe 
40249d3bc91SRichard Lowe     if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
403*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR);
40449d3bc91SRichard Lowe     }
40549d3bc91SRichard Lowe 
40649d3bc91SRichard Lowe     /* Create dwarf section headers */
40749d3bc91SRichard Lowe     for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) {
40807dc1947SRichard Lowe         long flags = 0;
40907dc1947SRichard Lowe 
41007dc1947SRichard Lowe         switch (sect) {
41107dc1947SRichard Lowe 
41207dc1947SRichard Lowe         case DEBUG_INFO:
413*4d9fdb46SRobert Mustacchi             if (dbg->de_dies == NULL) {
41407dc1947SRichard Lowe                 continue;
415*4d9fdb46SRobert Mustacchi             }
41607dc1947SRichard Lowe             break;
41707dc1947SRichard Lowe 
41807dc1947SRichard Lowe         case DEBUG_LINE:
41907dc1947SRichard Lowe             if (dwarf_need_debug_line_section(dbg) == FALSE) {
42007dc1947SRichard Lowe                 continue;
42107dc1947SRichard Lowe             }
42207dc1947SRichard Lowe             break;
42307dc1947SRichard Lowe 
42407dc1947SRichard Lowe         case DEBUG_ABBREV:
425*4d9fdb46SRobert Mustacchi             if (dbg->de_dies == NULL) {
42607dc1947SRichard Lowe                 continue;
427*4d9fdb46SRobert Mustacchi             }
42807dc1947SRichard Lowe             break;
42907dc1947SRichard Lowe 
43007dc1947SRichard Lowe         case DEBUG_FRAME:
431*4d9fdb46SRobert Mustacchi             if (dbg->de_frame_cies == NULL) {
43207dc1947SRichard Lowe                 continue;
433*4d9fdb46SRobert Mustacchi             }
43407dc1947SRichard Lowe             flags = SHF_MIPS_NOSTRIP;
43507dc1947SRichard Lowe             break;
43607dc1947SRichard Lowe 
43707dc1947SRichard Lowe         case DEBUG_ARANGES:
438*4d9fdb46SRobert Mustacchi             if (dbg->de_arange == NULL) {
43907dc1947SRichard Lowe                 continue;
440*4d9fdb46SRobert Mustacchi             }
44107dc1947SRichard Lowe             break;
44207dc1947SRichard Lowe 
44307dc1947SRichard Lowe         case DEBUG_PUBNAMES:
44407dc1947SRichard Lowe             if (dbg->de_simple_name_headers[dwarf_snk_pubname].
445*4d9fdb46SRobert Mustacchi                 sn_head == NULL) {
446*4d9fdb46SRobert 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) {
45207dc1947SRichard Lowe                 continue;
453*4d9fdb46SRobert Mustacchi             }
45407dc1947SRichard Lowe             break;
45507dc1947SRichard Lowe 
45607dc1947SRichard Lowe         case DEBUG_STR:
457*4d9fdb46SRobert Mustacchi             if (dbg->de_debug_str->ds_data == NULL) {
45807dc1947SRichard Lowe                 continue;
459*4d9fdb46SRobert Mustacchi             }
46007dc1947SRichard Lowe             break;
46107dc1947SRichard Lowe 
46207dc1947SRichard Lowe         case DEBUG_FUNCNAMES:
46307dc1947SRichard Lowe             if (dbg->de_simple_name_headers[dwarf_snk_funcname].
464*4d9fdb46SRobert Mustacchi                 sn_head == NULL) {
46507dc1947SRichard Lowe                 continue;
466*4d9fdb46SRobert Mustacchi             }
46707dc1947SRichard Lowe             break;
46807dc1947SRichard Lowe 
46907dc1947SRichard Lowe         case DEBUG_TYPENAMES:
47007dc1947SRichard Lowe             if (dbg->de_simple_name_headers[dwarf_snk_typename].
471*4d9fdb46SRobert Mustacchi                 sn_head == NULL) {
47207dc1947SRichard Lowe                 continue;
473*4d9fdb46SRobert Mustacchi             }
47407dc1947SRichard Lowe             break;
47507dc1947SRichard Lowe 
47607dc1947SRichard Lowe         case DEBUG_VARNAMES:
47707dc1947SRichard Lowe             if (dbg->de_simple_name_headers[dwarf_snk_varname].
478*4d9fdb46SRobert Mustacchi                 sn_head == NULL) {
47907dc1947SRichard Lowe                 continue;
480*4d9fdb46SRobert Mustacchi             }
48107dc1947SRichard Lowe             break;
48207dc1947SRichard Lowe 
48307dc1947SRichard Lowe         case DEBUG_WEAKNAMES:
48407dc1947SRichard Lowe             if (dbg->de_simple_name_headers[dwarf_snk_weakname].
485*4d9fdb46SRobert Mustacchi                 sn_head == NULL) {
48607dc1947SRichard Lowe                 continue;
487*4d9fdb46SRobert Mustacchi             }
48807dc1947SRichard Lowe             break;
48907dc1947SRichard Lowe 
49007dc1947SRichard Lowe         case DEBUG_MACINFO:
491*4d9fdb46SRobert Mustacchi             if (dbg->de_first_macinfo == NULL) {
492*4d9fdb46SRobert 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) {
49707dc1947SRichard Lowe                 continue;
498*4d9fdb46SRobert Mustacchi             }
49907dc1947SRichard Lowe             break;
50007dc1947SRichard Lowe         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. */
52307dc1947SRichard Lowe             continue;
52407dc1947SRichard Lowe         default:
52507dc1947SRichard Lowe             /* logic error: missing a case */
526*4d9fdb46SRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR);
52707dc1947SRichard Lowe         }
52807dc1947SRichard Lowe         {
529*4d9fdb46SRobert Mustacchi             int new_base_elf_sect = 0;
53007dc1947SRichard Lowe 
531*4d9fdb46SRobert Mustacchi             if (dbg->de_callback_func) {
53207dc1947SRichard Lowe                 new_base_elf_sect =
533*4d9fdb46SRobert Mustacchi                     dbg->de_callback_func(_dwarf_sectnames[sect],
53407dc1947SRichard Lowe                         /* rec size */ 1,
53507dc1947SRichard Lowe                         SECTION_TYPE,
536*4d9fdb46SRobert Mustacchi                         flags, SHN_UNDEF, 0, &du,
537*4d9fdb46SRobert Mustacchi                         dbg->de_user_data, &err);
53807dc1947SRichard Lowe             }
53907dc1947SRichard Lowe             if (new_base_elf_sect == -1) {
54007dc1947SRichard Lowe                 DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR,
541*4d9fdb46SRobert Mustacchi                     DW_DLV_ERROR);
54207dc1947SRichard Lowe             }
54307dc1947SRichard Lowe             dbg->de_elf_sects[sect] = new_base_elf_sect;
54407dc1947SRichard Lowe             dbg->de_sect_name_idx[sect] = du;
54507dc1947SRichard Lowe         }
54649d3bc91SRichard Lowe     }
54749d3bc91SRichard Lowe 
54849d3bc91SRichard Lowe     nbufs = 0;
54949d3bc91SRichard Lowe 
550*4d9fdb46SRobert Mustacchi     /*  Changing the order in which the sections are generated may cause
551*4d9fdb46SRobert Mustacchi         problems because of relocations. */
55249d3bc91SRichard Lowe 
55349d3bc91SRichard Lowe     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;
55707dc1947SRichard Lowe         }
55849d3bc91SRichard Lowe     }
55949d3bc91SRichard Lowe 
56049d3bc91SRichard Lowe     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;
56407dc1947SRichard Lowe         }
56549d3bc91SRichard Lowe     }
56649d3bc91SRichard Lowe     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;
57307dc1947SRichard Lowe         }
57449d3bc91SRichard Lowe     }
57549d3bc91SRichard Lowe 
57649d3bc91SRichard Lowe     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;
58007dc1947SRichard Lowe         }
58149d3bc91SRichard Lowe     }
58249d3bc91SRichard Lowe 
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;
59307dc1947SRichard Lowe         }
59449d3bc91SRichard Lowe     }
59549d3bc91SRichard Lowe 
59649d3bc91SRichard Lowe 
59749d3bc91SRichard Lowe 
598*4d9fdb46SRobert 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;
60207dc1947SRichard Lowe         }
60349d3bc91SRichard Lowe     }
604*4d9fdb46SRobert Mustacchi     if (dbg->de_output_version < 5) {
605*4d9fdb46SRobert Mustacchi         if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) {
606*4d9fdb46SRobert Mustacchi             int res = _dwarf_transform_simplename_to_disk(dbg,
607*4d9fdb46SRobert Mustacchi                 dwarf_snk_pubname,
608*4d9fdb46SRobert Mustacchi                 DEBUG_PUBNAMES,
609*4d9fdb46SRobert Mustacchi                 &nbufs,
610*4d9fdb46SRobert 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;
623*4d9fdb46SRobert Mustacchi             }
624*4d9fdb46SRobert Mustacchi         }
62549d3bc91SRichard Lowe 
626*4d9fdb46SRobert Mustacchi         if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) {
627*4d9fdb46SRobert Mustacchi             int res = _dwarf_transform_simplename_to_disk(dbg,
628*4d9fdb46SRobert Mustacchi                 dwarf_snk_funcname,
629*4d9fdb46SRobert Mustacchi                 DEBUG_FUNCNAMES,
630*4d9fdb46SRobert Mustacchi                 &nbufs,
631*4d9fdb46SRobert Mustacchi                 error);
632*4d9fdb46SRobert Mustacchi             if (res == DW_DLV_ERROR) {
633*4d9fdb46SRobert Mustacchi                 return res;
634*4d9fdb46SRobert Mustacchi             }
63507dc1947SRichard Lowe         }
63649d3bc91SRichard Lowe 
637*4d9fdb46SRobert Mustacchi         if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) {
638*4d9fdb46SRobert Mustacchi             int res = _dwarf_transform_simplename_to_disk(dbg,
639*4d9fdb46SRobert Mustacchi                 dwarf_snk_typename,
640*4d9fdb46SRobert Mustacchi                 DEBUG_TYPENAMES,
641*4d9fdb46SRobert Mustacchi                 &nbufs,
642*4d9fdb46SRobert Mustacchi                 error);
643*4d9fdb46SRobert Mustacchi             if (res == DW_DLV_ERROR) {
644*4d9fdb46SRobert Mustacchi                 return res;
645*4d9fdb46SRobert Mustacchi             }
64607dc1947SRichard Lowe         }
64749d3bc91SRichard Lowe 
648*4d9fdb46SRobert Mustacchi         if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) {
649*4d9fdb46SRobert Mustacchi             int res = _dwarf_transform_simplename_to_disk(dbg,
650*4d9fdb46SRobert Mustacchi                 dwarf_snk_varname,
651*4d9fdb46SRobert Mustacchi                 DEBUG_VARNAMES,
652*4d9fdb46SRobert Mustacchi                 &nbufs,
653*4d9fdb46SRobert Mustacchi                 error);
654*4d9fdb46SRobert Mustacchi             if (res == DW_DLV_ERROR) {
655*4d9fdb46SRobert Mustacchi                 return res;
656*4d9fdb46SRobert Mustacchi             }
657*4d9fdb46SRobert Mustacchi         }
65807dc1947SRichard Lowe 
659*4d9fdb46SRobert 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;
666*4d9fdb46SRobert Mustacchi             }
66707dc1947SRichard Lowe         }
66849d3bc91SRichard Lowe     }
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;
69207dc1947SRichard Lowe         }
69349d3bc91SRichard Lowe     }
694*4d9fdb46SRobert Mustacchi #endif
69549d3bc91SRichard Lowe 
69649d3bc91SRichard Lowe     {
697*4d9fdb46SRobert Mustacchi         Dwarf_Signed new_chunks = 0;
69807dc1947SRichard Lowe         int res = 0;
69907dc1947SRichard Lowe 
700*4d9fdb46SRobert Mustacchi         res = dbg->de_transform_relocs_to_disk(dbg, &new_chunks);
70107dc1947SRichard Lowe         if (res != DW_DLV_OK) {
702*4d9fdb46SRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_RELOCS_ERROR,
703*4d9fdb46SRobert Mustacchi                 DW_DLV_ERROR);
70407dc1947SRichard Lowe         }
705*4d9fdb46SRobert Mustacchi         nbufs += new_chunks;
70649d3bc91SRichard Lowe     }
707*4d9fdb46SRobert Mustacchi     *count = nbufs;
708*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
70949d3bc91SRichard Lowe }
71049d3bc91SRichard Lowe 
71149d3bc91SRichard Lowe 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)
71849d3bc91SRichard Lowe {
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 }
72649d3bc91SRichard Lowe 
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 {
75049d3bc91SRichard Lowe     char buff1[ENCODE_SPACE_NEEDED];
751*4d9fdb46SRobert Mustacchi     int nbytes = 0;
752*4d9fdb46SRobert Mustacchi     int res = 0;
75349d3bc91SRichard Lowe 
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);
75949d3bc91SRichard Lowe     }
760*4d9fdb46SRobert Mustacchi     *uval_len_out = nbytes;
761*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
762*4d9fdb46SRobert Mustacchi }
76349d3bc91SRichard Lowe 
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);
77949d3bc91SRichard Lowe     }
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 }
78549d3bc91SRichard Lowe 
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 }
80849d3bc91SRichard Lowe 
80949d3bc91SRichard Lowe 
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 }
83149d3bc91SRichard Lowe 
83249d3bc91SRichard Lowe 
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);
84749d3bc91SRichard Lowe     }
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 }
85549d3bc91SRichard Lowe 
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;
86849d3bc91SRichard Lowe 
869*4d9fdb46SRobert Mustacchi     /*  entry format itself */
870*4d9fdb46SRobert Mustacchi     calculated_size += sizeof_ubyte(dbg);
87149d3bc91SRichard Lowe 
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;
87749d3bc91SRichard Lowe 
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;
90349d3bc91SRichard Lowe     }
904*4d9fdb46SRobert Mustacchi     *size_out = calculated_size;
905*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
906*4d9fdb46SRobert Mustacchi }
90749d3bc91SRichard Lowe 
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;
93149d3bc91SRichard Lowe     }
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;
1298*4d9fdb46SRobert Mustacchi 
1299*4d9fdb46SRobert Mustacchi     /* include directories */
1300*4d9fdb46SRobert Mustacchi     curdir = dbg->de_inc_dirs;
1301*4d9fdb46SRobert Mustacchi     while (curdir) {
1302*4d9fdb46SRobert Mustacchi         prolog_size += strlen(curdir->dfe_name) + 1;
1303*4d9fdb46SRobert Mustacchi         curdir = curdir->dfe_next;
1304*4d9fdb46SRobert Mustacchi     }
1305*4d9fdb46SRobert Mustacchi     prolog_size++; /* last null following last directory
1306*4d9fdb46SRobert Mustacchi         entry. */
1307*4d9fdb46SRobert Mustacchi 
1308*4d9fdb46SRobert Mustacchi     /* file entries */
1309*4d9fdb46SRobert Mustacchi     curentry = dbg->de_file_entries;
1310*4d9fdb46SRobert Mustacchi     while (curentry) {
1311*4d9fdb46SRobert Mustacchi         prolog_size +=
1312*4d9fdb46SRobert Mustacchi             strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes;
1313*4d9fdb46SRobert Mustacchi         curentry = curentry->dfe_next;
1314*4d9fdb46SRobert Mustacchi     }
1315*4d9fdb46SRobert Mustacchi     prolog_size++; /* last null byte */
1316*4d9fdb46SRobert Mustacchi     *prolog_size_out = prolog_size;
1317*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1318*4d9fdb46SRobert Mustacchi }
131949d3bc91SRichard Lowe 
1320*4d9fdb46SRobert 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;
1338*4d9fdb46SRobert Mustacchi 
1339*4d9fdb46SRobert Mustacchi     /* all data named cur* are used to loop thru linked lists */
1340*4d9fdb46SRobert 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 
1378*4d9fdb46SRobert Mustacchi     start_line_sec = data;
1379*4d9fdb46SRobert Mustacchi 
1380*4d9fdb46SRobert Mustacchi     /* Copy the prologue data into 'data' */
1381*4d9fdb46SRobert Mustacchi     /* total_length */
1382*4d9fdb46SRobert Mustacchi     du = 0;
1383*4d9fdb46SRobert Mustacchi     if (extension_size) {
1384*4d9fdb46SRobert Mustacchi         DISTINGUISHED_VALUE_ARRAY(v4);
1385*4d9fdb46SRobert Mustacchi 
1386*4d9fdb46SRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0],
1387*4d9fdb46SRobert Mustacchi         SIZEOFT32, extension_size);
1388*4d9fdb46SRobert Mustacchi         data += extension_size;
1389*4d9fdb46SRobert Mustacchi     }
1390*4d9fdb46SRobert 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. */
1393*4d9fdb46SRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
1394*4d9fdb46SRobert Mustacchi         sizeof(du), offset_size);
1395*4d9fdb46SRobert Mustacchi     data += offset_size;
1396*4d9fdb46SRobert Mustacchi 
1397*4d9fdb46SRobert Mustacchi     dh =  inits->pi_linetable_version;
1398*4d9fdb46SRobert 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);
1411*4d9fdb46SRobert 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;
1426*4d9fdb46SRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1427*4d9fdb46SRobert Mustacchi         sizeof(db), sizeof(Dwarf_Ubyte));
1428*4d9fdb46SRobert 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;
1433*4d9fdb46SRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1434*4d9fdb46SRobert Mustacchi             sizeof(db), sizeof(Dwarf_Ubyte));
1435*4d9fdb46SRobert Mustacchi         data += sizeof(Dwarf_Ubyte);
1436*4d9fdb46SRobert Mustacchi     }
1437*4d9fdb46SRobert Mustacchi 
1438*4d9fdb46SRobert Mustacchi     db =  inits->pi_default_is_stmt;
1439*4d9fdb46SRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1440*4d9fdb46SRobert Mustacchi         sizeof(db), sizeof(Dwarf_Ubyte));
1441*4d9fdb46SRobert Mustacchi     data += sizeof(Dwarf_Ubyte);
1442*4d9fdb46SRobert Mustacchi     db =  inits->pi_line_base;
1443*4d9fdb46SRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1444*4d9fdb46SRobert Mustacchi         sizeof(db), sizeof(Dwarf_Ubyte));
1445*4d9fdb46SRobert 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;
1451*4d9fdb46SRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1452*4d9fdb46SRobert Mustacchi         sizeof(db), sizeof(Dwarf_Ubyte));
1453*4d9fdb46SRobert Mustacchi     data += sizeof(Dwarf_Ubyte);
1454*4d9fdb46SRobert 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;
1458*4d9fdb46SRobert Mustacchi 
1459*4d9fdb46SRobert Mustacchi     if (version < 5) {
1460*4d9fdb46SRobert Mustacchi         /* copy over include directories */
1461*4d9fdb46SRobert Mustacchi         curdir = dbg->de_inc_dirs;
1462*4d9fdb46SRobert 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;
1466*4d9fdb46SRobert Mustacchi         }
1467*4d9fdb46SRobert Mustacchi         *data = '\0';               /* last null */
1468*4d9fdb46SRobert Mustacchi         data++;
1469*4d9fdb46SRobert Mustacchi 
1470*4d9fdb46SRobert Mustacchi         /* copy file entries */
1471*4d9fdb46SRobert Mustacchi         curentry = dbg->de_file_entries;
1472*4d9fdb46SRobert Mustacchi         while (curentry) {
1473*4d9fdb46SRobert Mustacchi             strcpy((char *) data, curentry->dfe_name);
1474*4d9fdb46SRobert Mustacchi             data += strlen(curentry->dfe_name) + 1;
1475*4d9fdb46SRobert Mustacchi             /* copies of leb numbers, no endian issues */
1476*4d9fdb46SRobert Mustacchi             memcpy((void *) data,
1477*4d9fdb46SRobert Mustacchi                 (const void *) curentry->dfe_args, curentry->dfe_nbytes);
1478*4d9fdb46SRobert Mustacchi             data += curentry->dfe_nbytes;
1479*4d9fdb46SRobert Mustacchi             curentry = curentry->dfe_next;
1480*4d9fdb46SRobert Mustacchi         }
1481*4d9fdb46SRobert Mustacchi         *data = '\0';
1482*4d9fdb46SRobert 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     }
1539*4d9fdb46SRobert 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         }
1548*4d9fdb46SRobert Mustacchi         sum_bytes += prolog_size;
1549*4d9fdb46SRobert Mustacchi     }
155049d3bc91SRichard Lowe 
155149d3bc91SRichard Lowe     curline = dbg->de_lines;
155249d3bc91SRichard Lowe     prevline = (Dwarf_P_Line)
155307dc1947SRichard Lowe         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
155449d3bc91SRichard Lowe     if (prevline == NULL) {
1555*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR);
155649d3bc91SRichard Lowe     }
1557*4d9fdb46SRobert Mustacchi     _dwarf_pro_reg_init(dbg,prevline);
155849d3bc91SRichard Lowe     /* generate opcodes for line numbers */
155949d3bc91SRichard Lowe     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
1562*4d9fdb46SRobert Mustacchi             generated, if special opcode or end
1563*4d9fdb46SRobert Mustacchi             sequence */
1564*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned addr_adv = 0;
1565*4d9fdb46SRobert Mustacchi         int line_adv = 0;           /* supposed to be a reasonably small
1566*4d9fdb46SRobert Mustacchi             number, so the size should not be a
1567*4d9fdb46SRobert Mustacchi             problem. ? */
156807dc1947SRichard Lowe 
156907dc1947SRichard Lowe         no_lns_copy = 0;
157007dc1947SRichard Lowe         if (curline->dpl_opc != 0) {
1571*4d9fdb46SRobert Mustacchi             int inst_bytes = 0;     /* no of bytes in extended opcode */
1572*4d9fdb46SRobert Mustacchi             unsigned writelen = 0;
157307dc1947SRichard Lowe 
157407dc1947SRichard Lowe             switch (curline->dpl_opc) {
157507dc1947SRichard Lowe             case DW_LNE_end_sequence:
157607dc1947SRichard Lowe                 /* Advance pc to end of text section. */
157707dc1947SRichard Lowe                 addr_adv = curline->dpl_address - prevline->dpl_address;
157807dc1947SRichard Lowe                 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);
158407dc1947SRichard Lowe                     if (res != DW_DLV_OK) {
1585*4d9fdb46SRobert Mustacchi                         return res;
158607dc1947SRichard Lowe                     }
1587*4d9fdb46SRobert Mustacchi                     sum_bytes += writelen;
158807dc1947SRichard Lowe                     prevline->dpl_address = curline->dpl_address;
158907dc1947SRichard Lowe                 }
159007dc1947SRichard Lowe 
159107dc1947SRichard Lowe                 /* first null byte */
159207dc1947SRichard Lowe                 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;
159907dc1947SRichard Lowe 
160007dc1947SRichard Lowe                 /* write length of extended opcode */
160107dc1947SRichard Lowe                 inst_bytes = sizeof(Dwarf_Ubyte);
1602*4d9fdb46SRobert Mustacchi                 res = write_uval(inst_bytes,dbg,elfsectno,
1603*4d9fdb46SRobert Mustacchi                     &writelen,error);
160407dc1947SRichard Lowe                 if (res != DW_DLV_OK) {
1605*4d9fdb46SRobert Mustacchi                     return res;
160607dc1947SRichard Lowe                 }
1607*4d9fdb46SRobert Mustacchi                 sum_bytes += writelen;
160807dc1947SRichard Lowe 
160907dc1947SRichard Lowe                 /* 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 
161707dc1947SRichard Lowe                 /* reset value to original values */
1618*4d9fdb46SRobert Mustacchi                 _dwarf_pro_reg_init(dbg,prevline);
161907dc1947SRichard Lowe                 no_lns_copy = 1;
1620*4d9fdb46SRobert Mustacchi                 /*  this is set only for end_sequence, so that a
1621*4d9fdb46SRobert Mustacchi                     dw_lns_copy is not generated */
162207dc1947SRichard Lowe                 break;
162307dc1947SRichard Lowe 
162407dc1947SRichard Lowe             case DW_LNE_set_address:
162507dc1947SRichard Lowe 
162607dc1947SRichard Lowe                 /* first null byte */
162707dc1947SRichard Lowe                 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;
163407dc1947SRichard Lowe 
163507dc1947SRichard Lowe                 /* 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);
163907dc1947SRichard Lowe                 if (res != DW_DLV_OK) {
1640*4d9fdb46SRobert Mustacchi                     return res;
164107dc1947SRichard Lowe                 }
1642*4d9fdb46SRobert Mustacchi                 sum_bytes += writelen;
164307dc1947SRichard Lowe 
164407dc1947SRichard Lowe                 /* 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;
165107dc1947SRichard Lowe 
165207dc1947SRichard Lowe                 /* reloc for address */
1653*4d9fdb46SRobert Mustacchi                 res = dbg->de_relocate_by_name_symbol(dbg,
1654*4d9fdb46SRobert Mustacchi                     DEBUG_LINE,
165507dc1947SRichard Lowe                     sum_bytes,  /* r_offset  */
165607dc1947SRichard Lowe                     curline->dpl_r_symidx,
165707dc1947SRichard Lowe                     dwarf_drt_data_reloc,
1658*4d9fdb46SRobert Mustacchi                     offset_size);
165907dc1947SRichard Lowe                 if (res != DW_DLV_OK) {
1660*4d9fdb46SRobert Mustacchi                     DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, DW_DLV_ERROR);
166107dc1947SRichard Lowe                 }
166207dc1947SRichard Lowe 
166307dc1947SRichard Lowe                 /* write offset (address) */
166407dc1947SRichard Lowe                 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;
167107dc1947SRichard Lowe                 prevline->dpl_address = curline->dpl_address;
167207dc1947SRichard Lowe                 no_lns_copy = 1;
167307dc1947SRichard Lowe                 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);
168507dc1947SRichard Lowe                 if (res != DW_DLV_OK) {
1686*4d9fdb46SRobert Mustacchi                     return res;
168707dc1947SRichard Lowe                 }
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);
169307dc1947SRichard Lowe                 if (res != DW_DLV_OK) {
1694*4d9fdb46SRobert Mustacchi                     return res;
169507dc1947SRichard Lowe                 }
1696*4d9fdb46SRobert Mustacchi                 val_len++;
169707dc1947SRichard Lowe 
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;
1724*4d9fdb46SRobert Mustacchi             }
1725*4d9fdb46SRobert 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             }
1761*4d9fdb46SRobert Mustacchi             if (curline->dpl_file != prevline->dpl_file) {
1762*4d9fdb46SRobert 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);
1766*4d9fdb46SRobert Mustacchi                 if (res != DW_DLV_OK) {
1767*4d9fdb46SRobert Mustacchi                     return res;
1768*4d9fdb46SRobert Mustacchi                 }
1769*4d9fdb46SRobert Mustacchi                 sum_bytes += writelen;
1770*4d9fdb46SRobert Mustacchi 
1771*4d9fdb46SRobert Mustacchi                 prevline->dpl_file = curline->dpl_file;
1772*4d9fdb46SRobert Mustacchi             }
1773*4d9fdb46SRobert Mustacchi             if (curline->dpl_column != prevline->dpl_column) {
1774*4d9fdb46SRobert Mustacchi                 db = DW_LNS_set_column;
1775*4d9fdb46SRobert Mustacchi                 res = write_opcode_uval(db,dbg,
1776*4d9fdb46SRobert Mustacchi                     elfsectno, curline->dpl_column , &writelen,error);
1777*4d9fdb46SRobert Mustacchi                 if (res != DW_DLV_OK) {
1778*4d9fdb46SRobert Mustacchi                     return res;
1779*4d9fdb46SRobert Mustacchi                 }
1780*4d9fdb46SRobert Mustacchi                 sum_bytes += writelen;
178107dc1947SRichard Lowe                 prevline->dpl_column = curline->dpl_column;
178207dc1947SRichard Lowe             }
178307dc1947SRichard Lowe             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;
179007dc1947SRichard Lowe                 prevline->dpl_is_stmt = curline->dpl_is_stmt;
179107dc1947SRichard Lowe             }
179207dc1947SRichard Lowe             if (curline->dpl_basic_block == true &&
179307dc1947SRichard Lowe                 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;
180007dc1947SRichard Lowe                 prevline->dpl_basic_block = curline->dpl_basic_block;
180107dc1947SRichard Lowe             }
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 
184707dc1947SRichard Lowe             addr_adv = curline->dpl_address - prevline->dpl_address;
184807dc1947SRichard Lowe 
184907dc1947SRichard Lowe             line_adv = (int) (curline->dpl_line - prevline->dpl_line);
185007dc1947SRichard Lowe             if ((addr_adv % MIN_INST_LENGTH) != 0) {
1851*4d9fdb46SRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, DW_DLV_ERROR);
185207dc1947SRichard Lowe             }
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. */
185607dc1947SRichard Lowe                 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;
186207dc1947SRichard Lowe                 prevline->dpl_basic_block = false;
186307dc1947SRichard Lowe                 prevline->dpl_address = curline->dpl_address;
186407dc1947SRichard Lowe                 prevline->dpl_line = curline->dpl_line;
186507dc1947SRichard Lowe             } else {
1866*4d9fdb46SRobert Mustacchi                 /*  opc says use standard opcodes. */
186707dc1947SRichard Lowe                 if (addr_adv > 0) {
186807dc1947SRichard Lowe                     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);
187407dc1947SRichard Lowe                     if (res != DW_DLV_OK) {
1875*4d9fdb46SRobert Mustacchi                         return res;
187607dc1947SRichard Lowe                     }
1877*4d9fdb46SRobert Mustacchi                     sum_bytes += writelen;
187807dc1947SRichard Lowe                     prevline->dpl_basic_block = false;
187907dc1947SRichard Lowe                     prevline->dpl_address = curline->dpl_address;
188007dc1947SRichard Lowe                 }
188107dc1947SRichard Lowe                 if (line_adv != 0) {
188207dc1947SRichard Lowe                     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);
188707dc1947SRichard Lowe                     if (res != DW_DLV_OK) {
1888*4d9fdb46SRobert Mustacchi                         return res;
188907dc1947SRichard Lowe                     }
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;
189907dc1947SRichard Lowe                     prevline->dpl_basic_block = false;
190007dc1947SRichard Lowe                     prevline->dpl_line = curline->dpl_line;
190107dc1947SRichard Lowe                 }
190207dc1947SRichard Lowe             }
1903*4d9fdb46SRobert Mustacchi         }   /* ends else for opc <= 0 */
190407dc1947SRichard Lowe         if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq
1905*4d9fdb46SRobert 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;
191207dc1947SRichard Lowe             prevline->dpl_basic_block = false;
191307dc1947SRichard Lowe         }
191407dc1947SRichard Lowe         curline = curline->dpl_next;
191549d3bc91SRichard Lowe     }
191649d3bc91SRichard Lowe 
191749d3bc91SRichard Lowe     /* write total length field */
1918*4d9fdb46SRobert Mustacchi     du = sum_bytes - OFFSET_PLUS_EXTENSION_SIZE;
191949d3bc91SRichard Lowe     {
192007dc1947SRichard Lowe         start_line_sec += extension_size;
192107dc1947SRichard Lowe         WRITE_UNALIGNED(dbg, (void *) start_line_sec,
1922*4d9fdb46SRobert Mustacchi             (const void *) &du, sizeof(du), offset_size);
192349d3bc91SRichard Lowe     }
192449d3bc91SRichard Lowe 
1925*4d9fdb46SRobert Mustacchi     *nbufs = dbg->de_n_debug_sect;
1926*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
192749d3bc91SRichard Lowe }
192849d3bc91SRichard Lowe 
1929*4d9fdb46SRobert Mustacchi /*
1930*4d9fdb46SRobert Mustacchi     Generate debug_frame section  */
193149d3bc91SRichard Lowe 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)
193549d3bc91SRichard Lowe {
193607dc1947SRichard Lowe     int elfsectno = 0;
193707dc1947SRichard Lowe     int i = 0;
193849d3bc91SRichard Lowe     int firsttime = 1;
193907dc1947SRichard Lowe     Dwarf_P_Cie curcie = 0;
194007dc1947SRichard Lowe     Dwarf_P_Fde curfde = 0;
194107dc1947SRichard Lowe     unsigned char *data = 0;
194207dc1947SRichard Lowe     Dwarf_Unsigned du = 0;
194307dc1947SRichard Lowe     Dwarf_Ubyte db = 0;
194407dc1947SRichard Lowe     long *cie_offs = 0;   /* Holds byte offsets for links to fde's */
194507dc1947SRichard Lowe     unsigned long cie_length = 0;
194607dc1947SRichard Lowe     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;
1950*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cur_off = 0; /* current offset of written data, held
1951*4d9fdb46SRobert Mustacchi         for relocation info */
195249d3bc91SRichard Lowe 
195349d3bc91SRichard Lowe     elfsectno = dbg->de_elf_sects[DEBUG_FRAME];
195449d3bc91SRichard Lowe 
195549d3bc91SRichard Lowe     curcie = dbg->de_frame_cies;
195649d3bc91SRichard Lowe     cie_length = 0;
195749d3bc91SRichard Lowe     cie_offs = (long *)
195807dc1947SRichard Lowe         _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie);
195949d3bc91SRichard Lowe     if (cie_offs == NULL) {
1960*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR);
196149d3bc91SRichard Lowe     }
1962*4d9fdb46SRobert Mustacchi     /*  Generate cie number as we go along.  This writes
1963*4d9fdb46SRobert Mustacchi         all CIEs first before any FDEs, which is rather
1964*4d9fdb46SRobert Mustacchi         different from the order a compiler might like (which
1965*4d9fdb46SRobert Mustacchi         might be each CIE followed by its FDEs then the next CIE, and
1966*4d9fdb46SRobert Mustacchi         so on). */
196749d3bc91SRichard Lowe     cie_no = 1;
196849d3bc91SRichard Lowe     while (curcie) {
196907dc1947SRichard Lowe         char *code_al = 0;
1970*4d9fdb46SRobert Mustacchi         int codeal_bytes = 0;
197107dc1947SRichard Lowe         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 */
197407dc1947SRichard Lowe         int res = 0;
197507dc1947SRichard Lowe         char buff1[ENCODE_SPACE_NEEDED];
197607dc1947SRichard Lowe         char buff2[ENCODE_SPACE_NEEDED];
197707dc1947SRichard Lowe         char buff3[ENCODE_SPACE_NEEDED];
197807dc1947SRichard Lowe         char *augmentation = 0;
197907dc1947SRichard Lowe         char *augmented_al = 0;
198007dc1947SRichard Lowe         long augmented_fields_length = 0;
1981*4d9fdb46SRobert Mustacchi         int irix_auglen_v0 = 0;
1982*4d9fdb46SRobert Mustacchi         Dwarf_Half version = curcie->cie_version;
198307dc1947SRichard Lowe 
198407dc1947SRichard Lowe         res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align,
1985*4d9fdb46SRobert Mustacchi             &codeal_bytes,
1986*4d9fdb46SRobert Mustacchi             buff1, sizeof(buff1));
198707dc1947SRichard Lowe         if (res != DW_DLV_OK) {
1988*4d9fdb46SRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR);
198907dc1947SRichard Lowe         }
1990*4d9fdb46SRobert Mustacchi         /*  Before April 1999, the following was using an unsigned
1991*4d9fdb46SRobert Mustacchi             encode. That worked ok even though the decoder used the
1992*4d9fdb46SRobert Mustacchi             correct signed leb read, but doing the encode correctly
1993*4d9fdb46SRobert Mustacchi             (according to the dwarf spec) saves space in the output file
1994*4d9fdb46SRobert Mustacchi             and is completely compatible.
199507dc1947SRichard Lowe 
1996*4d9fdb46SRobert Mustacchi             Note the actual stored amount on MIPS was 10 bytes (!) to
1997*4d9fdb46SRobert Mustacchi             store the value -4. (hex)fc ffffffff ffffffff 01 The
1998*4d9fdb46SRobert Mustacchi             libdwarf consumer consumed all 10 bytes too!
199907dc1947SRichard Lowe 
2000*4d9fdb46SRobert Mustacchi             old version res =
2001*4d9fdb46SRobert Mustacchi             _dwarf_pro_encode_leb128_nm(curcie->cie_data_align,
200207dc1947SRichard Lowe 
2003*4d9fdb46SRobert Mustacchi             below is corrected signed version. */
200407dc1947SRichard Lowe         res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align,
2005*4d9fdb46SRobert Mustacchi             &data_align_bytes,
2006*4d9fdb46SRobert Mustacchi             buff2, sizeof(buff2));
200707dc1947SRichard Lowe         if (res != DW_DLV_OK) {
2008*4d9fdb46SRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR);
200907dc1947SRichard Lowe         }
201007dc1947SRichard Lowe         code_al = buff1;
201107dc1947SRichard Lowe         data_al = buff2;
201207dc1947SRichard Lowe 
201307dc1947SRichard Lowe         /* get the correct offset */
201407dc1947SRichard Lowe         if (firsttime) {
201507dc1947SRichard Lowe             cie_offs[cie_no - 1] = 0;
201607dc1947SRichard Lowe             firsttime = 0;
201707dc1947SRichard Lowe         } else {
201807dc1947SRichard Lowe             cie_offs[cie_no - 1] = cie_offs[cie_no - 2] +
2019*4d9fdb46SRobert Mustacchi                 (long) cie_length + OFFSET_PLUS_EXTENSION_SIZE;
202007dc1947SRichard Lowe         }
202107dc1947SRichard Lowe         cie_no++;
202207dc1947SRichard Lowe         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. */
203407dc1947SRichard Lowe             augmented_fields_length = 0;
203507dc1947SRichard Lowe             res = _dwarf_pro_encode_leb128_nm(augmented_fields_length,
2036*4d9fdb46SRobert Mustacchi                 &irix_auglen_v0, buff3,
2037*4d9fdb46SRobert Mustacchi                 sizeof(buff3));
203807dc1947SRichard Lowe             augmented_al = buff3;
203907dc1947SRichard Lowe             if (res != DW_DLV_OK) {
2040*4d9fdb46SRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC,
2041*4d9fdb46SRobert Mustacchi                     DW_DLV_ERROR);
204207dc1947SRichard Lowe             }
2043*4d9fdb46SRobert Mustacchi             cie_length += irix_auglen_v0 ;       /* augmentation length */
2044*4d9fdb46SRobert 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);
205107dc1947SRichard Lowe         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);
205907dc1947SRichard Lowe         if (extension_size) {
2060*4d9fdb46SRobert Mustacchi             DISTINGUISHED_VALUE_ARRAY(v4);
206107dc1947SRichard Lowe 
206207dc1947SRichard Lowe             WRITE_UNALIGNED(dbg, (void *) data,
2063*4d9fdb46SRobert Mustacchi                 (const void *) &v4[0],
2064*4d9fdb46SRobert Mustacchi                 SIZEOFT32, extension_size);
206507dc1947SRichard Lowe             data += extension_size;
206607dc1947SRichard Lowe 
206707dc1947SRichard Lowe         }
206807dc1947SRichard Lowe         du = cie_length;
206907dc1947SRichard Lowe         /* total length of cie */
207007dc1947SRichard Lowe         WRITE_UNALIGNED(dbg, (void *) data,
2071*4d9fdb46SRobert Mustacchi             (const void *) &du, sizeof(du), offset_size);
2072*4d9fdb46SRobert Mustacchi         data += offset_size;
207307dc1947SRichard Lowe 
207407dc1947SRichard Lowe         /* cie-id is a special value. */
207507dc1947SRichard Lowe         du = DW_CIE_ID;
207607dc1947SRichard Lowe         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
2077*4d9fdb46SRobert Mustacchi             sizeof(du), offset_size);
2078*4d9fdb46SRobert Mustacchi         data += offset_size;
207907dc1947SRichard Lowe 
208007dc1947SRichard Lowe         db = curcie->cie_version;
208107dc1947SRichard Lowe         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2082*4d9fdb46SRobert Mustacchi             sizeof(db), sizeof(Dwarf_Ubyte));
208307dc1947SRichard Lowe         data += sizeof(Dwarf_Ubyte);
2084*4d9fdb46SRobert Mustacchi 
208507dc1947SRichard Lowe         strcpy((char *) data, curcie->cie_aug);
208607dc1947SRichard Lowe         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 
210807dc1947SRichard Lowe         db = curcie->cie_ret_reg;
210907dc1947SRichard Lowe         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2110*4d9fdb46SRobert Mustacchi             sizeof(db), sizeof(Dwarf_Ubyte));
211107dc1947SRichard Lowe         data += sizeof(Dwarf_Ubyte);
211207dc1947SRichard Lowe 
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;
212007dc1947SRichard Lowe         }
212107dc1947SRichard Lowe         memcpy((void *) data, (const void *) curcie->cie_inst,
2122*4d9fdb46SRobert Mustacchi             curcie->cie_inst_bytes);
212307dc1947SRichard Lowe         data += curcie->cie_inst_bytes;
2124*4d9fdb46SRobert Mustacchi 
212507dc1947SRichard Lowe         for (i = 0; i < pad; i++) {
212607dc1947SRichard Lowe             *data = DW_CFA_nop;
212707dc1947SRichard Lowe             data++;
212807dc1947SRichard Lowe         }
212907dc1947SRichard Lowe         curcie = curcie->cie_next;
213049d3bc91SRichard Lowe     }
213149d3bc91SRichard Lowe     /* calculate current offset */
2132*4d9fdb46SRobert Mustacchi     cur_off = cie_offs[cie_no - 2] + cie_length +
2133*4d9fdb46SRobert Mustacchi         OFFSET_PLUS_EXTENSION_SIZE;
213449d3bc91SRichard Lowe 
213549d3bc91SRichard Lowe     /* write out fde's */
213649d3bc91SRichard Lowe     curfde = dbg->de_frame_fdes;
213749d3bc91SRichard Lowe     while (curfde) {
213807dc1947SRichard Lowe         Dwarf_P_Frame_Pgm curinst = 0;
213907dc1947SRichard Lowe         long fde_length = 0;
2140*4d9fdb46SRobert Mustacchi         int pad2 = 0;
214107dc1947SRichard Lowe         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;
214507dc1947SRichard Lowe         int oet_length = 0;
2146*4d9fdb46SRobert Mustacchi         int afl_length = 0;
214707dc1947SRichard Lowe         int res = 0;
214807dc1947SRichard Lowe         int v0_augmentation = 0;
214907dc1947SRichard Lowe         char afl_buff[ENCODE_SPACE_NEEDED];
215007dc1947SRichard Lowe 
215107dc1947SRichard Lowe         /* Find the CIE associated with this fde. */
215207dc1947SRichard Lowe         cie_ptr = dbg->de_frame_cies;
215307dc1947SRichard Lowe         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) {
215607dc1947SRichard Lowe             cie_ptr = cie_ptr->cie_next;
2157*4d9fdb46SRobert Mustacchi             indx++;
215807dc1947SRichard Lowe         }
215907dc1947SRichard Lowe         if (cie_ptr == NULL) {
2160*4d9fdb46SRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, DW_DLV_ERROR);
216107dc1947SRichard Lowe         }
216207dc1947SRichard Lowe 
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 
217107dc1947SRichard Lowe             v0_augmentation = 1;
2172*4d9fdb46SRobert Mustacchi             oet_length = DWARF_32BIT_SIZE;
217307dc1947SRichard Lowe             /* encode the length of augmented fields. */
217407dc1947SRichard Lowe             res = _dwarf_pro_encode_leb128_nm(oet_length,
2175*4d9fdb46SRobert Mustacchi                 &afl_length, afl_buff,
2176*4d9fdb46SRobert Mustacchi                 sizeof(afl_buff));
217707dc1947SRichard Lowe             if (res != DW_DLV_OK) {
2178*4d9fdb46SRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC,
2179*4d9fdb46SRobert Mustacchi                     DW_DLV_ERROR);
218007dc1947SRichard Lowe             }
218107dc1947SRichard Lowe 
2182*4d9fdb46SRobert Mustacchi             fde_length +=
218307dc1947SRichard Lowe                 afl_length +    /* augmented field length */
218407dc1947SRichard Lowe                 oet_length;     /* exception_table offset */
218507dc1947SRichard Lowe         }
218607dc1947SRichard Lowe 
218707dc1947SRichard Lowe         if (curfde->fde_die) {
2188*4d9fdb46SRobert Mustacchi             /*  IRIX/MIPS extension:
2189*4d9fdb46SRobert Mustacchi                 Using fde offset, generate DW_AT_MIPS_fde
2190*4d9fdb46SRobert Mustacchi                 attribute for the
2191*4d9fdb46SRobert 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;
219607dc1947SRichard Lowe             }
219707dc1947SRichard Lowe         }
219807dc1947SRichard Lowe 
219907dc1947SRichard Lowe         /* 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 */,
2204*4d9fdb46SRobert Mustacchi             dbg->de_sect_name_idx[DEBUG_FRAME],
2205*4d9fdb46SRobert Mustacchi             dwarf_drt_data_reloc, offset_size);
220607dc1947SRichard Lowe         if (res != DW_DLV_OK) {
2207*4d9fdb46SRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res );
220807dc1947SRichard Lowe         }
220907dc1947SRichard Lowe 
221007dc1947SRichard Lowe         /* 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 */,
2215*4d9fdb46SRobert Mustacchi             curfde->fde_r_symidx,
2216*4d9fdb46SRobert Mustacchi             dwarf_drt_data_reloc, address_size);
221707dc1947SRichard Lowe         if (res != DW_DLV_OK) {
2218*4d9fdb46SRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res);
221907dc1947SRichard Lowe         }
2220*4d9fdb46SRobert Mustacchi         /*  Store the relocation information for the
2221*4d9fdb46SRobert Mustacchi             offset_into_exception_info field, if the offset is valid (0
2222*4d9fdb46SRobert Mustacchi             is a valid offset). */
222307dc1947SRichard Lowe         if (v0_augmentation &&
222407dc1947SRichard Lowe             curfde->fde_offset_into_exception_tables >= 0) {
222507dc1947SRichard Lowe 
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 +
2231*4d9fdb46SRobert Mustacchi                     afl_length,
2232*4d9fdb46SRobert Mustacchi                 curfde->fde_exception_table_symbol,
2233*4d9fdb46SRobert Mustacchi                 dwarf_drt_segment_rel,
2234*4d9fdb46SRobert Mustacchi                 DWARF_32BIT_SIZE);
223507dc1947SRichard Lowe             if (res != DW_DLV_OK) {
2236*4d9fdb46SRobert Mustacchi                 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res);
223707dc1947SRichard Lowe             }
223807dc1947SRichard Lowe         }
223907dc1947SRichard Lowe 
224007dc1947SRichard Lowe         /* adjust for padding */
2241*4d9fdb46SRobert Mustacchi         pad2 = (int) PADDING(fde_length, address_size);
2242*4d9fdb46SRobert Mustacchi         fde_length += pad2;
224307dc1947SRichard Lowe 
224407dc1947SRichard Lowe 
224507dc1947SRichard Lowe         /* write out fde */
2246*4d9fdb46SRobert Mustacchi         GET_CHUNK(dbg, elfsectno, data, fde_length +
2247*4d9fdb46SRobert Mustacchi             OFFSET_PLUS_EXTENSION_SIZE,
2248*4d9fdb46SRobert Mustacchi             error);
224907dc1947SRichard Lowe         du = fde_length;
225007dc1947SRichard Lowe         {
225107dc1947SRichard Lowe             if (extension_size) {
2252*4d9fdb46SRobert Mustacchi                 DISTINGUISHED_VALUE_ARRAY(v4);
225307dc1947SRichard Lowe 
225407dc1947SRichard Lowe                 WRITE_UNALIGNED(dbg, (void *) data,
2255*4d9fdb46SRobert Mustacchi                     (const void *) &v4[0],
2256*4d9fdb46SRobert Mustacchi                     SIZEOFT32, extension_size);
225707dc1947SRichard Lowe                 data += extension_size;
225807dc1947SRichard Lowe             }
225907dc1947SRichard Lowe             /* length */
226007dc1947SRichard Lowe             WRITE_UNALIGNED(dbg, (void *) data,
2261*4d9fdb46SRobert Mustacchi                 (const void *) &du,
2262*4d9fdb46SRobert Mustacchi                 sizeof(du), offset_size);
2263*4d9fdb46SRobert Mustacchi             data += offset_size;
226407dc1947SRichard Lowe 
226507dc1947SRichard Lowe             /* offset to cie */
226607dc1947SRichard Lowe             du = cie_offs[curfde->fde_cie - 1];
226707dc1947SRichard Lowe             WRITE_UNALIGNED(dbg, (void *) data,
2268*4d9fdb46SRobert Mustacchi                 (const void *) &du,
2269*4d9fdb46SRobert Mustacchi                 sizeof(du), offset_size);
2270*4d9fdb46SRobert Mustacchi             data += offset_size;
227107dc1947SRichard Lowe 
227207dc1947SRichard Lowe             du = curfde->fde_initloc;
227307dc1947SRichard Lowe             WRITE_UNALIGNED(dbg, (void *) data,
2274*4d9fdb46SRobert Mustacchi                 (const void *) &du,
2275*4d9fdb46SRobert Mustacchi                 sizeof(du), address_size);
2276*4d9fdb46SRobert Mustacchi             data += address_size;
227707dc1947SRichard Lowe 
2278*4d9fdb46SRobert Mustacchi             if (dbg->de_relocate_pair_by_symbol &&
227907dc1947SRichard Lowe                 curfde->fde_end_symbol != 0 &&
228007dc1947SRichard Lowe                 curfde->fde_addr_range == 0) {
2281*4d9fdb46SRobert Mustacchi                 /*  symbolic reloc, need reloc for length What if we
2282*4d9fdb46SRobert Mustacchi                     really know the length? If so, should use the other
2283*4d9fdb46SRobert Mustacchi                     part of 'if'. */
228407dc1947SRichard Lowe                 Dwarf_Unsigned val;
228507dc1947SRichard Lowe 
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,
2290*4d9fdb46SRobert Mustacchi                     curfde->fde_end_symbol,
2291*4d9fdb46SRobert Mustacchi                     dwarf_drt_first_of_length_pair,
2292*4d9fdb46SRobert Mustacchi                     address_size);
229307dc1947SRichard Lowe                 if (res != DW_DLV_OK) {
229407dc1947SRichard Lowe                     {
229507dc1947SRichard Lowe                         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
2296*4d9fdb46SRobert Mustacchi                         return DW_DLV_ERROR;
229707dc1947SRichard Lowe                     }
229807dc1947SRichard Lowe                 }
229907dc1947SRichard Lowe 
2300*4d9fdb46SRobert Mustacchi                 /*  arrange pre-calc so assem text can do .word end -
2301*4d9fdb46SRobert Mustacchi                     begin + val (gets val from stream) */
230207dc1947SRichard Lowe                 val = curfde->fde_end_symbol_offset -
230307dc1947SRichard Lowe                     curfde->fde_initloc;
230407dc1947SRichard Lowe                 WRITE_UNALIGNED(dbg, data,
2305*4d9fdb46SRobert Mustacchi                     (const void *) &val,
2306*4d9fdb46SRobert Mustacchi                     sizeof(val), address_size);
2307*4d9fdb46SRobert Mustacchi                 data += address_size;
230807dc1947SRichard Lowe             } else {
230907dc1947SRichard Lowe                 du = curfde->fde_addr_range;
231007dc1947SRichard Lowe                 WRITE_UNALIGNED(dbg, (void *) data,
2311*4d9fdb46SRobert Mustacchi                     (const void *) &du,
2312*4d9fdb46SRobert Mustacchi                     sizeof(du), address_size);
2313*4d9fdb46SRobert Mustacchi                 data += address_size;
231407dc1947SRichard Lowe             }
231507dc1947SRichard Lowe         }
231607dc1947SRichard Lowe 
231707dc1947SRichard Lowe         if (v0_augmentation) {
2318*4d9fdb46SRobert Mustacchi             /* IRIX only. */
231907dc1947SRichard Lowe             /* write the encoded augmented field length. */
2320*4d9fdb46SRobert Mustacchi             Dwarf_Signed dsw = 0;
2321*4d9fdb46SRobert Mustacchi 
232207dc1947SRichard Lowe             memcpy((void *) data, (const void *) afl_buff, afl_length);
232307dc1947SRichard Lowe             data += afl_length;
232407dc1947SRichard Lowe             /* 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;
233007dc1947SRichard Lowe         }
233107dc1947SRichard Lowe 
233207dc1947SRichard Lowe         curinst = curfde->fde_inst;
2333*4d9fdb46SRobert Mustacchi         if (curfde->fde_block) {
233407dc1947SRichard Lowe             unsigned long size = curfde->fde_inst_block_size;
233507dc1947SRichard Lowe             memcpy((void *) data, (const void *) curfde->fde_block, size);
233607dc1947SRichard Lowe             data += size;
233707dc1947SRichard Lowe         } else {
233807dc1947SRichard Lowe             while (curinst) {
233907dc1947SRichard Lowe                 db = curinst->dfp_opcode;
234007dc1947SRichard Lowe                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2341*4d9fdb46SRobert Mustacchi                     sizeof(db), sizeof(Dwarf_Ubyte));
234207dc1947SRichard Lowe                 data += sizeof(Dwarf_Ubyte);
234307dc1947SRichard Lowe                 memcpy((void *) data,
2344*4d9fdb46SRobert Mustacchi                     (const void *) curinst->dfp_args,
2345*4d9fdb46SRobert Mustacchi                     curinst->dfp_nbytes);
234607dc1947SRichard Lowe                 data += curinst->dfp_nbytes;
234707dc1947SRichard Lowe                 curinst = curinst->dfp_next;
234807dc1947SRichard Lowe             }
234907dc1947SRichard Lowe         }
235007dc1947SRichard Lowe         /* padding */
2351*4d9fdb46SRobert Mustacchi         for (i = 0; i < pad2; i++) {
235207dc1947SRichard Lowe             *data = DW_CFA_nop;
235307dc1947SRichard Lowe             data++;
235407dc1947SRichard Lowe         }
2355*4d9fdb46SRobert Mustacchi         cur_off += fde_length + offset_size;
235607dc1947SRichard Lowe         curfde = curfde->fde_next;
235749d3bc91SRichard Lowe     }
235849d3bc91SRichard Lowe 
235949d3bc91SRichard Lowe 
2360*4d9fdb46SRobert Mustacchi     *nbufs =  dbg->de_n_debug_sect;
2361*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
236249d3bc91SRichard Lowe }
236349d3bc91SRichard Lowe 
236407dc1947SRichard Lowe /*
236507dc1947SRichard Lowe   These functions remember all the markers we see along
236607dc1947SRichard Lowe   with the right offset in the .debug_info section so that
236707dc1947SRichard Lowe   we can dump them all back to the user with the section info.
236807dc1947SRichard Lowe */
236907dc1947SRichard Lowe 
237007dc1947SRichard Lowe static int
marker_init(Dwarf_P_Debug dbg,unsigned count)237107dc1947SRichard Lowe marker_init(Dwarf_P_Debug dbg,
2372*4d9fdb46SRobert Mustacchi     unsigned count)
237307dc1947SRichard Lowe {
237407dc1947SRichard Lowe     dbg->de_marker_n_alloc = count;
237507dc1947SRichard Lowe     dbg->de_markers = NULL;
237607dc1947SRichard Lowe     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);
237907dc1947SRichard Lowe         if (dbg->de_markers == NULL) {
238007dc1947SRichard Lowe             dbg->de_marker_n_alloc = 0;
2381*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
238207dc1947SRichard Lowe         }
238307dc1947SRichard Lowe     }
2384*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
238507dc1947SRichard Lowe }
238607dc1947SRichard Lowe 
238707dc1947SRichard Lowe static int
marker_add(Dwarf_P_Debug dbg,Dwarf_Unsigned offset,Dwarf_Unsigned marker)238807dc1947SRichard Lowe marker_add(Dwarf_P_Debug dbg,
2389*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
2390*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned marker)
239107dc1947SRichard Lowe {
239207dc1947SRichard Lowe     if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) {
239307dc1947SRichard Lowe         unsigned n = dbg->de_marker_n_used++;
239407dc1947SRichard Lowe         dbg->de_markers[n].ma_offset = offset;
239507dc1947SRichard Lowe         dbg->de_markers[n].ma_marker = marker;
2396*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
239707dc1947SRichard Lowe     }
2398*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
239907dc1947SRichard Lowe }
240007dc1947SRichard Lowe 
240107dc1947SRichard Lowe Dwarf_Signed
dwarf_get_die_markers(Dwarf_P_Debug dbg,Dwarf_P_Marker * marker_list,Dwarf_Unsigned * marker_count,Dwarf_Error * error)240207dc1947SRichard Lowe dwarf_get_die_markers(Dwarf_P_Debug dbg,
2403*4d9fdb46SRobert Mustacchi     Dwarf_P_Marker * marker_list, /* pointer to a pointer */
2404*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * marker_count,
2405*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
2406*4d9fdb46SRobert 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)
242207dc1947SRichard Lowe {
242307dc1947SRichard Lowe     if (marker_list == NULL || marker_count == NULL) {
2424*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR);
242507dc1947SRichard Lowe     }
242607dc1947SRichard Lowe     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);
2428*4d9fdb46SRobert Mustacchi     }
2429*4d9fdb46SRobert Mustacchi 
2430*4d9fdb46SRobert Mustacchi     *marker_list = dbg->de_markers;
2431*4d9fdb46SRobert Mustacchi     *marker_count = dbg->de_marker_n_used;
2432*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
2433*4d9fdb46SRobert Mustacchi }
2434*4d9fdb46SRobert Mustacchi 
2435*4d9fdb46SRobert Mustacchi /*  These functions provide the offsets of DW_FORM_string
2436*4d9fdb46SRobert Mustacchi     attributes in the section section_index. These information
2437*4d9fdb46SRobert Mustacchi     will enable a producer app that is generating assembly
2438*4d9fdb46SRobert Mustacchi     text output to easily emit those attributes in ascii form
2439*4d9fdb46SRobert Mustacchi     without having to decode the byte stream.  */
2440*4d9fdb46SRobert Mustacchi static int
string_attr_init(Dwarf_P_Debug dbg,Dwarf_Signed section_index,unsigned count)2441*4d9fdb46SRobert Mustacchi string_attr_init (Dwarf_P_Debug dbg,
2442*4d9fdb46SRobert Mustacchi     Dwarf_Signed section_index,
2443*4d9fdb46SRobert Mustacchi     unsigned count)
2444*4d9fdb46SRobert Mustacchi {
2445*4d9fdb46SRobert Mustacchi     Dwarf_P_Per_Sect_String_Attrs sect_sa =
2446*4d9fdb46SRobert Mustacchi         &dbg->de_sect_string_attr[section_index];
2447*4d9fdb46SRobert Mustacchi 
2448*4d9fdb46SRobert Mustacchi     sect_sa->sect_sa_n_alloc = count;
2449*4d9fdb46SRobert Mustacchi     sect_sa->sect_sa_list = NULL;
2450*4d9fdb46SRobert Mustacchi     if (count > 0) {
2451*4d9fdb46SRobert Mustacchi         sect_sa->sect_sa_section_number = section_index;
2452*4d9fdb46SRobert 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);
2454*4d9fdb46SRobert Mustacchi         if (sect_sa->sect_sa_list == NULL) {
2455*4d9fdb46SRobert Mustacchi             sect_sa->sect_sa_n_alloc = 0;
2456*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
2457*4d9fdb46SRobert Mustacchi         }
2458*4d9fdb46SRobert Mustacchi     }
2459*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
2460*4d9fdb46SRobert Mustacchi }
2461*4d9fdb46SRobert Mustacchi 
2462*4d9fdb46SRobert Mustacchi static int
string_attr_add(Dwarf_P_Debug dbg,Dwarf_Signed section_index,Dwarf_Unsigned offset,Dwarf_P_Attribute attr)2463*4d9fdb46SRobert Mustacchi string_attr_add (Dwarf_P_Debug dbg,
2464*4d9fdb46SRobert Mustacchi     Dwarf_Signed section_index,
2465*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
2466*4d9fdb46SRobert Mustacchi     Dwarf_P_Attribute attr)
2467*4d9fdb46SRobert Mustacchi {
2468*4d9fdb46SRobert Mustacchi     Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
2469*4d9fdb46SRobert Mustacchi     if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) {
2470*4d9fdb46SRobert Mustacchi         unsigned n = sect_sa->sect_sa_n_used++;
2471*4d9fdb46SRobert Mustacchi         sect_sa->sect_sa_list[n].sa_offset = offset;
2472*4d9fdb46SRobert Mustacchi         sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes;
2473*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
2474*4d9fdb46SRobert Mustacchi     }
2475*4d9fdb46SRobert Mustacchi 
2476*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
2477*4d9fdb46SRobert Mustacchi }
2478*4d9fdb46SRobert Mustacchi 
2479*4d9fdb46SRobert 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)2480*4d9fdb46SRobert Mustacchi dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,
2481*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *
2482*4d9fdb46SRobert Mustacchi     count_of_sa_sections,
2483*4d9fdb46SRobert Mustacchi     int *drd_buffer_version,
2484*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Error *error)
2485*4d9fdb46SRobert Mustacchi {
2486*4d9fdb46SRobert Mustacchi     int i = 0;
2487*4d9fdb46SRobert Mustacchi     unsigned int count = 0;
2488*4d9fdb46SRobert Mustacchi 
2489*4d9fdb46SRobert Mustacchi     for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
2490*4d9fdb46SRobert Mustacchi         if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) {
2491*4d9fdb46SRobert Mustacchi             ++count;
2492*4d9fdb46SRobert Mustacchi         }
2493*4d9fdb46SRobert Mustacchi     }
2494*4d9fdb46SRobert Mustacchi     *count_of_sa_sections = (Dwarf_Unsigned) count;
2495*4d9fdb46SRobert Mustacchi     *drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
2496*4d9fdb46SRobert Mustacchi 
2497*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
2498*4d9fdb46SRobert Mustacchi }
2499*4d9fdb46SRobert Mustacchi 
2500*4d9fdb46SRobert 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)2501*4d9fdb46SRobert Mustacchi dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,
2502*4d9fdb46SRobert Mustacchi     Dwarf_Signed *elf_section_index,
2503*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *sect_sa_buffer_count,
2504*4d9fdb46SRobert Mustacchi     Dwarf_P_String_Attr *sect_sa_buffer,
2505*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Error *error)
2506*4d9fdb46SRobert Mustacchi {
2507*4d9fdb46SRobert Mustacchi     int i = 0;
2508*4d9fdb46SRobert Mustacchi     int next = dbg->de_sect_sa_next_to_return;
2509*4d9fdb46SRobert Mustacchi 
2510*4d9fdb46SRobert Mustacchi     for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
2511*4d9fdb46SRobert Mustacchi         Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i];
2512*4d9fdb46SRobert Mustacchi         if (sect_sa->sect_sa_n_used > 0) {
2513*4d9fdb46SRobert Mustacchi             dbg->de_sect_sa_next_to_return = i + 1;
2514*4d9fdb46SRobert Mustacchi             *elf_section_index = sect_sa->sect_sa_section_number;
2515*4d9fdb46SRobert Mustacchi             *sect_sa_buffer_count = sect_sa->sect_sa_n_used;
2516*4d9fdb46SRobert Mustacchi             *sect_sa_buffer = sect_sa->sect_sa_list;
2517*4d9fdb46SRobert Mustacchi             return DW_DLV_OK;
2518*4d9fdb46SRobert Mustacchi         }
2519*4d9fdb46SRobert Mustacchi     }
2520*4d9fdb46SRobert Mustacchi     return DW_DLV_NO_ENTRY;
2521*4d9fdb46SRobert Mustacchi }
2522*4d9fdb46SRobert Mustacchi 
2523*4d9fdb46SRobert Mustacchi 
2524*4d9fdb46SRobert 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;
298307dc1947SRichard Lowe     }
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;
298707dc1947SRichard Lowe     return DW_DLV_OK;
298807dc1947SRichard Lowe }
298907dc1947SRichard Lowe 
299007dc1947SRichard Lowe 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)
299307dc1947SRichard Lowe {
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;
300207dc1947SRichard Lowe 
3003*4d9fdb46SRobert Mustacchi     int k = 0;
300407dc1947SRichard Lowe 
3005*4d9fdb46SRobert Mustacchi     if (attrcount < 2) {
3006*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
300707dc1947SRichard Lowe     }
300807dc1947SRichard Lowe 
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;
303807dc1947SRichard Lowe         }
3039*4d9fdb46SRobert Mustacchi         sorted_tail->ar_next  = localptr;
3040*4d9fdb46SRobert Mustacchi         sorted_tail = localptr;
3041*4d9fdb46SRobert Mustacchi         localptr->ar_next = 0;
304207dc1947SRichard Lowe     }
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;
304807dc1947SRichard Lowe }
304907dc1947SRichard Lowe 
305049d3bc91SRichard Lowe 
305149d3bc91SRichard Lowe 
305249d3bc91SRichard Lowe 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)
305649d3bc91SRichard Lowe {
305707dc1947SRichard Lowe     int elfsectno_of_debug_info = 0;
305807dc1947SRichard Lowe     unsigned char *data = 0;
305907dc1947SRichard Lowe     int cu_header_size = 0;
306007dc1947SRichard Lowe     Dwarf_P_Abbrev curabbrev = 0;
306107dc1947SRichard Lowe     Dwarf_P_Abbrev abbrev_head = 0;
306207dc1947SRichard Lowe     Dwarf_P_Abbrev abbrev_tail = 0;
306307dc1947SRichard Lowe     Dwarf_P_Die curdie = 0;
306407dc1947SRichard Lowe     Dwarf_P_Die first_child = 0;
3065*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned dw = 0;
306607dc1947SRichard Lowe     Dwarf_Unsigned du = 0;
306707dc1947SRichard Lowe     Dwarf_Half dh = 0;
306807dc1947SRichard Lowe     Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */
306907dc1947SRichard Lowe     int n_abbrevs = 0;
3070*4d9fdb46SRobert Mustacchi     unsigned  abbrev_offset = 0;
307107dc1947SRichard Lowe     int res = 0;
307207dc1947SRichard Lowe     unsigned marker_count = 0;
307307dc1947SRichard Lowe     unsigned string_attr_count = 0;
307407dc1947SRichard Lowe     unsigned string_attr_offset = 0;
3075*4d9fdb46SRobert Mustacchi     Dwarf_Small *abbr_off_ptr = 0;
3076*4d9fdb46SRobert 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;
308549d3bc91SRichard Lowe     int extension_size = dbg->de_64bit_extension ? 4 : 0;
308649d3bc91SRichard Lowe 
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;
309049d3bc91SRichard Lowe 
3091*4d9fdb46SRobert 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,
3100*4d9fdb46SRobert Mustacchi             error);
3101*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
3102*4d9fdb46SRobert Mustacchi             return res;
3103*4d9fdb46SRobert 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);
311849d3bc91SRichard Lowe     }
311949d3bc91SRichard Lowe 
312049d3bc91SRichard Lowe     curdie = dbg->de_dies;
312149d3bc91SRichard Lowe 
3122*4d9fdb46SRobert Mustacchi     /*  Create AT_macro_info if appropriate */
3123*4d9fdb46SRobert Mustacchi     if( version < 5) {
3124*4d9fdb46SRobert 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
313549d3bc91SRichard Lowe     }
313649d3bc91SRichard Lowe 
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     }
314449d3bc91SRichard Lowe     die_off = cu_header_size;
314549d3bc91SRichard Lowe 
3146*4d9fdb46SRobert Mustacchi     /*  Relocation for abbrev offset in cu header store relocation
3147*4d9fdb46SRobert 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 */,
3151*4d9fdb46SRobert Mustacchi         dbg->de_sect_name_idx[DEBUG_ABBREV],
3152*4d9fdb46SRobert Mustacchi         dwarf_drt_data_reloc, offset_size);
315349d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
3154*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
315549d3bc91SRichard Lowe     }
315649d3bc91SRichard Lowe 
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. */
316049d3bc91SRichard Lowe     first_child = curdie->di_child;
316149d3bc91SRichard Lowe     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)) {
3164*4d9fdb46SRobert Mustacchi                 dwarf_add_AT_reference(dbg,
3165*4d9fdb46SRobert Mustacchi                     first_child,
3166*4d9fdb46SRobert Mustacchi                     DW_AT_sibling,
3167*4d9fdb46SRobert Mustacchi                     first_child->di_right, error);
3168*4d9fdb46SRobert Mustacchi             }
3169*4d9fdb46SRobert Mustacchi         }
317007dc1947SRichard Lowe         first_child = first_child->di_right;
317149d3bc91SRichard Lowe     }
317249d3bc91SRichard Lowe 
3173*4d9fdb46SRobert Mustacchi     /* Pass 1: create abbrev info, get die offsets, calc relocations */
3174*4d9fdb46SRobert Mustacchi     abbrev_head = abbrev_tail = NULL;
317507dc1947SRichard Lowe     marker_count = 0;
317607dc1947SRichard Lowe     string_attr_count = 0;
317749d3bc91SRichard Lowe     while (curdie != NULL) {
317807dc1947SRichard Lowe         int nbytes = 0;
3179*4d9fdb46SRobert Mustacchi         Dwarf_P_Attribute curattr = 0;
318007dc1947SRichard Lowe         char *space = 0;
3181*4d9fdb46SRobert Mustacchi         int cres = 0;
318207dc1947SRichard Lowe         char buff1[ENCODE_SPACE_NEEDED];
318307dc1947SRichard Lowe 
318407dc1947SRichard Lowe         curdie->di_offset = die_off;
318507dc1947SRichard Lowe 
3186*4d9fdb46SRobert Mustacchi         if (curdie->di_marker != 0) {
318707dc1947SRichard Lowe             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;
320007dc1947SRichard Lowe         }
320107dc1947SRichard Lowe         if (abbrev_head == NULL) {
320207dc1947SRichard Lowe             n_abbrevs = 1;
320307dc1947SRichard Lowe             curabbrev->abb_idx = n_abbrevs;
320407dc1947SRichard Lowe             abbrev_tail = abbrev_head = curabbrev;
320507dc1947SRichard Lowe         } else {
3206*4d9fdb46SRobert Mustacchi             /* Check if it is a new abbreviation, if yes, add to tail */
320707dc1947SRichard Lowe             if (curabbrev->abb_idx == 0) {
320807dc1947SRichard Lowe                 n_abbrevs++;
320907dc1947SRichard Lowe                 curabbrev->abb_idx = n_abbrevs;
321007dc1947SRichard Lowe                 abbrev_tail->abb_next = curabbrev;
321107dc1947SRichard Lowe                 abbrev_tail = curabbrev;
321207dc1947SRichard Lowe             }
321307dc1947SRichard Lowe         }
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,
3219*4d9fdb46SRobert Mustacchi             &nbytes,
3220*4d9fdb46SRobert 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);
322307dc1947SRichard Lowe         }
322407dc1947SRichard Lowe         space = _dwarf_p_get_alloc(dbg, nbytes);
322507dc1947SRichard Lowe         if (space == NULL) {
3226*4d9fdb46SRobert Mustacchi             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
322707dc1947SRichard Lowe         }
322807dc1947SRichard Lowe         memcpy(space, buff1, nbytes);
322907dc1947SRichard Lowe         curdie->di_abbrev = space;
323007dc1947SRichard Lowe         curdie->di_abbrev_nbytes = nbytes;
323107dc1947SRichard Lowe         die_off += nbytes;
323207dc1947SRichard Lowe 
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.  */
323607dc1947SRichard Lowe 
3237*4d9fdb46SRobert Mustacchi         /*  Now we attach the attributes list to the die. */
323807dc1947SRichard Lowe         curattr = curdie->di_attrs;
3239*4d9fdb46SRobert Mustacchi 
324007dc1947SRichard Lowe         while (curattr) {
324107dc1947SRichard Lowe             if (curattr->ar_rel_type != R_MIPS_NONE) {
3242*4d9fdb46SRobert Mustacchi                 int rres=0;
324307dc1947SRichard Lowe                 switch (curattr->ar_attribute) {
324407dc1947SRichard Lowe                 case DW_AT_stmt_list:
324507dc1947SRichard Lowe                     curattr->ar_rel_symidx =
324607dc1947SRichard Lowe                         dbg->de_sect_name_idx[DEBUG_LINE];
324707dc1947SRichard Lowe                     break;
324807dc1947SRichard Lowe                 case DW_AT_MIPS_fde:
324907dc1947SRichard Lowe                     curattr->ar_rel_symidx =
325007dc1947SRichard Lowe                         dbg->de_sect_name_idx[DEBUG_FRAME];
325107dc1947SRichard Lowe                     break;
325207dc1947SRichard Lowe                 case DW_AT_macro_info:
325307dc1947SRichard Lowe                     curattr->ar_rel_symidx =
325407dc1947SRichard Lowe                         dbg->de_sect_name_idx[DEBUG_MACINFO];
325507dc1947SRichard Lowe                     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;
327607dc1947SRichard Lowe                 default:
327707dc1947SRichard Lowe                     break;
327807dc1947SRichard Lowe                 }
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 */
3282*4d9fdb46SRobert Mustacchi                     curattr->ar_rel_symidx,
3283*4d9fdb46SRobert Mustacchi                     dwarf_drt_data_reloc,
3284*4d9fdb46SRobert Mustacchi                     curattr->ar_reloc_len);
328507dc1947SRichard Lowe 
3286*4d9fdb46SRobert Mustacchi                 if (rres != DW_DLV_OK) {
3287*4d9fdb46SRobert Mustacchi                     DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
328807dc1947SRichard Lowe                 }
328907dc1947SRichard Lowe             }
329007dc1947SRichard Lowe             if (curattr->ar_attribute_form == DW_FORM_string) {
329107dc1947SRichard Lowe                 string_attr_count++;
329207dc1947SRichard Lowe             }
329307dc1947SRichard Lowe             die_off += curattr->ar_nbytes;
329407dc1947SRichard Lowe             curattr = curattr->ar_next;
329507dc1947SRichard Lowe         }
3296*4d9fdb46SRobert Mustacchi         /* Depth first access to all the DIEs. */
3297*4d9fdb46SRobert Mustacchi         if (curdie->di_child) {
329807dc1947SRichard Lowe             curdie = curdie->di_child;
3299*4d9fdb46SRobert Mustacchi         } else {
330007dc1947SRichard Lowe             while (curdie != NULL && curdie->di_right == NULL) {
330107dc1947SRichard Lowe                 curdie = curdie->di_parent;
3302*4d9fdb46SRobert Mustacchi                 /* See -nonrootsibling- below */
3303*4d9fdb46SRobert Mustacchi                 if (curdie != NULL) {
3304*4d9fdb46SRobert Mustacchi                     die_off++;
3305*4d9fdb46SRobert Mustacchi                 }
330607dc1947SRichard Lowe             }
3307*4d9fdb46SRobert Mustacchi             if (curdie != NULL) {
330807dc1947SRichard Lowe                 curdie = curdie->di_right;
3309*4d9fdb46SRobert Mustacchi             }
331007dc1947SRichard Lowe         }
3311*4d9fdb46SRobert Mustacchi 
3312*4d9fdb46SRobert Mustacchi     } /* end while (curdie != NULL), the per-die loop */
331307dc1947SRichard Lowe 
331407dc1947SRichard Lowe     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);
331749d3bc91SRichard Lowe     }
331807dc1947SRichard Lowe     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);
3321*4d9fdb46SRobert Mustacchi     }
3322*4d9fdb46SRobert Mustacchi 
3323*4d9fdb46SRobert Mustacchi     /*  Pass 2: Write out the die information Here 'data' is a
3324*4d9fdb46SRobert Mustacchi         temporary, one block for each GET_CHUNK.  'data' is overused. */
332549d3bc91SRichard Lowe     curdie = dbg->de_dies;
332649d3bc91SRichard Lowe     while (curdie != NULL) {
332707dc1947SRichard Lowe         Dwarf_P_Attribute curattr;
332807dc1947SRichard Lowe 
332907dc1947SRichard Lowe         if (curdie->di_marker != 0) {
333007dc1947SRichard Lowe             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);
333307dc1947SRichard Lowe             }
333407dc1947SRichard Lowe         }
333507dc1947SRichard Lowe 
3336*4d9fdb46SRobert Mustacchi         /* Index to abbreviation table */
3337*4d9fdb46SRobert Mustacchi         GET_CHUNK_ERR(dbg, elfsectno_of_debug_info,
3338*4d9fdb46SRobert Mustacchi             data, curdie->di_abbrev_nbytes, error);
333907dc1947SRichard Lowe         memcpy((void *) data,
3340*4d9fdb46SRobert Mustacchi             (const void *) curdie->di_abbrev,
3341*4d9fdb46SRobert Mustacchi             curdie->di_abbrev_nbytes);
334207dc1947SRichard Lowe 
334307dc1947SRichard Lowe         /* Attribute values - need to fill in all form attributes */
334407dc1947SRichard Lowe         curattr = curdie->di_attrs;
3345*4d9fdb46SRobert Mustacchi         string_attr_offset = curdie->di_offset +
3346*4d9fdb46SRobert Mustacchi             curdie->di_abbrev_nbytes;
334707dc1947SRichard Lowe         while (curattr) {
3348*4d9fdb46SRobert Mustacchi             GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data,
3349*4d9fdb46SRobert Mustacchi                 (unsigned long) curattr->ar_nbytes, error);
335007dc1947SRichard Lowe             switch (curattr->ar_attribute_form) {
335107dc1947SRichard Lowe             case DW_FORM_ref1:
335207dc1947SRichard Lowe                 {
3353*4d9fdb46SRobert Mustacchi                     Dwarf_Ubyte db = 0;
335407dc1947SRichard Lowe                     if (curattr->ar_ref_die->di_offset >
335507dc1947SRichard Lowe                         (unsigned) 0xff) {
3356*4d9fdb46SRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR);
335707dc1947SRichard Lowe                     }
335807dc1947SRichard Lowe                     db = curattr->ar_ref_die->di_offset;
335907dc1947SRichard Lowe                     WRITE_UNALIGNED(dbg, (void *) data,
3360*4d9fdb46SRobert Mustacchi                         (const void *) &db,
3361*4d9fdb46SRobert Mustacchi                         sizeof(db), sizeof(Dwarf_Ubyte));
336207dc1947SRichard Lowe                     break;
336307dc1947SRichard Lowe                 }
336407dc1947SRichard Lowe             case DW_FORM_ref2:
336507dc1947SRichard Lowe                 {
336607dc1947SRichard Lowe                     if (curattr->ar_ref_die->di_offset >
336707dc1947SRichard Lowe                         (unsigned) 0xffff) {
3368*4d9fdb46SRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR);
336907dc1947SRichard Lowe                     }
337007dc1947SRichard Lowe                     dh = curattr->ar_ref_die->di_offset;
337107dc1947SRichard Lowe                     WRITE_UNALIGNED(dbg, (void *) data,
3372*4d9fdb46SRobert Mustacchi                         (const void *) &dh,
3373*4d9fdb46SRobert Mustacchi                         sizeof(dh), DWARF_HALF_SIZE);
337407dc1947SRichard Lowe                     break;
337507dc1947SRichard Lowe                 }
337607dc1947SRichard Lowe             case DW_FORM_ref_addr:
337707dc1947SRichard Lowe                 {
3378*4d9fdb46SRobert 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.  */
338507dc1947SRichard Lowe                     break;
338607dc1947SRichard Lowe 
338707dc1947SRichard Lowe                 }
338807dc1947SRichard Lowe             case DW_FORM_ref4:
338907dc1947SRichard Lowe                 {
339007dc1947SRichard Lowe                     if (curattr->ar_ref_die->di_offset >
339107dc1947SRichard Lowe                         (unsigned) 0xffffffff) {
3392*4d9fdb46SRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW,
3393*4d9fdb46SRobert Mustacchi                             DW_DLV_ERROR);
339407dc1947SRichard Lowe                     }
3395*4d9fdb46SRobert Mustacchi                     dw = (Dwarf_Unsigned) curattr->ar_ref_die->di_offset;
339607dc1947SRichard Lowe                     WRITE_UNALIGNED(dbg, (void *) data,
3397*4d9fdb46SRobert Mustacchi                         (const void *) &dw,
3398*4d9fdb46SRobert Mustacchi                         sizeof(dw), DWARF_32BIT_SIZE);
339907dc1947SRichard Lowe                     break;
340007dc1947SRichard Lowe                 }
340107dc1947SRichard Lowe             case DW_FORM_ref8:
340207dc1947SRichard Lowe                 du = curattr->ar_ref_die->di_offset;
340307dc1947SRichard Lowe                 WRITE_UNALIGNED(dbg, (void *) data,
3404*4d9fdb46SRobert Mustacchi                     (const void *) &du,
3405*4d9fdb46SRobert Mustacchi                     sizeof(du), DWARF_64BIT_SIZE);
340607dc1947SRichard Lowe                 break;
340707dc1947SRichard Lowe             case DW_FORM_ref_udata:
3408*4d9fdb46SRobert Mustacchi                 {   /* unsigned leb128 offset */
340907dc1947SRichard Lowe 
3410*4d9fdb46SRobert Mustacchi                     int nbytesx;
341107dc1947SRichard Lowe                     char buff1[ENCODE_SPACE_NEEDED];
341207dc1947SRichard Lowe 
341307dc1947SRichard Lowe                     res =
341407dc1947SRichard Lowe                         _dwarf_pro_encode_leb128_nm(curattr->
3415*4d9fdb46SRobert Mustacchi                             ar_ref_die->
3416*4d9fdb46SRobert Mustacchi                             di_offset, &nbytesx,
3417*4d9fdb46SRobert Mustacchi                             buff1,
3418*4d9fdb46SRobert Mustacchi                             sizeof(buff1));
341907dc1947SRichard Lowe                     if (res != DW_DLV_OK) {
3420*4d9fdb46SRobert Mustacchi                         DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC,
3421*4d9fdb46SRobert Mustacchi                             DW_DLV_ERROR);
342207dc1947SRichard Lowe                     }
3423*4d9fdb46SRobert Mustacchi                     memcpy(data, buff1, nbytesx);
342407dc1947SRichard Lowe                     break;
342507dc1947SRichard Lowe                 }
342607dc1947SRichard Lowe             default:
3427*4d9fdb46SRobert Mustacchi                 if(curattr->ar_nbytes) {
3428*4d9fdb46SRobert Mustacchi                     memcpy((void *) data,
3429*4d9fdb46SRobert Mustacchi                         (const void *) curattr->ar_data,
3430*4d9fdb46SRobert Mustacchi                         curattr->ar_nbytes);
3431*4d9fdb46SRobert Mustacchi                 }
343207dc1947SRichard Lowe                 break;
343307dc1947SRichard Lowe             }
343407dc1947SRichard Lowe             if (curattr->ar_attribute_form == DW_FORM_string) {
343507dc1947SRichard Lowe                 string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr);
343607dc1947SRichard Lowe             }
343707dc1947SRichard Lowe             string_attr_offset += curattr->ar_nbytes;
343807dc1947SRichard Lowe             curattr = curattr->ar_next;
343907dc1947SRichard Lowe         }
344007dc1947SRichard Lowe 
344107dc1947SRichard Lowe         /* depth first search */
3442*4d9fdb46SRobert Mustacchi         if (curdie->di_child) {
344307dc1947SRichard Lowe             curdie = curdie->di_child;
3444*4d9fdb46SRobert Mustacchi         } else {
344507dc1947SRichard Lowe             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);
345807dc1947SRichard Lowe                 *data = '\0';
345907dc1947SRichard Lowe                 curdie = curdie->di_parent;
346007dc1947SRichard Lowe             }
346107dc1947SRichard Lowe             if (curdie != NULL)
346207dc1947SRichard Lowe                 curdie = curdie->di_right;
346307dc1947SRichard Lowe         }
346407dc1947SRichard Lowe     } /* end while (curdir != NULL) */
346549d3bc91SRichard Lowe 
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);
347249d3bc91SRichard Lowe 
347349d3bc91SRichard Lowe 
347407dc1947SRichard Lowe     data = 0;                   /* Emphasise not usable now */
347549d3bc91SRichard Lowe 
3476*4d9fdb46SRobert Mustacchi     res = write_out_debug_abbrev(dbg,
3477*4d9fdb46SRobert Mustacchi         abbrev_head, error);
3478*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
3479*4d9fdb46SRobert Mustacchi         return res;
3480*4d9fdb46SRobert Mustacchi     }
348107dc1947SRichard Lowe 
3482*4d9fdb46SRobert Mustacchi     *nbufs =  dbg->de_n_debug_sect;
3483*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
3484*4d9fdb46SRobert Mustacchi }
348507dc1947SRichard Lowe 
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;
349507dc1947SRichard Lowe 
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 }
350449d3bc91SRichard Lowe 
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;
351207dc1947SRichard Lowe 
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;
352749d3bc91SRichard Lowe 
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;
353649d3bc91SRichard Lowe }
353749d3bc91SRichard Lowe 
353849d3bc91SRichard Lowe 
3539*4d9fdb46SRobert Mustacchi /*  Get a buffer of section data.
3540*4d9fdb46SRobert Mustacchi     section_idx is the elf-section number that this data applies to.
3541*4d9fdb46SRobert Mustacchi     length shows length of returned data
3542*4d9fdb46SRobert Mustacchi     This is the original format. Hard to check for error. */
3543*4d9fdb46SRobert Mustacchi 
3544*4d9fdb46SRobert Mustacchi /*ARGSUSED*/                   /* pretend all args used */
3545*4d9fdb46SRobert 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)354649d3bc91SRichard Lowe dwarf_get_section_bytes(Dwarf_P_Debug dbg,
3547*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Signed dwarf_section,
3548*4d9fdb46SRobert Mustacchi     Dwarf_Signed * section_idx,
3549*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * length, Dwarf_Error * error)
355049d3bc91SRichard Lowe {
3551*4d9fdb46SRobert Mustacchi     Dwarf_Ptr s_bytes = 0;
3552*4d9fdb46SRobert Mustacchi     int res = 0;
355349d3bc91SRichard Lowe 
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;
356249d3bc91SRichard Lowe     }
3563*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_NO_ENTRY) {
3564*4d9fdb46SRobert Mustacchi         return NULL;
3565*4d9fdb46SRobert Mustacchi     }
3566*4d9fdb46SRobert Mustacchi     return s_bytes;
3567*4d9fdb46SRobert Mustacchi }
3568*4d9fdb46SRobert 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;
358249d3bc91SRichard Lowe 
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;
358849d3bc91SRichard Lowe     if (dbg->de_debug_sects == 0) {
358907dc1947SRichard Lowe         /* no more data !! */
3590*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
359149d3bc91SRichard Lowe     }
359249d3bc91SRichard Lowe     if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
359307dc1947SRichard Lowe         /* no data ever entered !! */
3594*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
359549d3bc91SRichard Lowe     }
359649d3bc91SRichard Lowe     *section_idx = dbg->de_debug_sects->ds_elf_sect_no;
359749d3bc91SRichard Lowe     *length = dbg->de_debug_sects->ds_nbytes;
359849d3bc91SRichard Lowe 
359949d3bc91SRichard Lowe     buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data;
360049d3bc91SRichard Lowe 
3601*4d9fdb46SRobert Mustacchi     /*  Here is the iterator so the next call gets
3602*4d9fdb46SRobert Mustacchi         the next section. */
360349d3bc91SRichard Lowe     dbg->de_debug_sects = dbg->de_debug_sects->ds_next;
360449d3bc91SRichard Lowe 
3605*4d9fdb46SRobert Mustacchi     /*  We may want to call the section stuff more than once: see
3606*4d9fdb46SRobert Mustacchi         dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */
360749d3bc91SRichard Lowe 
3608*4d9fdb46SRobert Mustacchi     *section_bytes = buf;
3609*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
361049d3bc91SRichard Lowe }
361149d3bc91SRichard Lowe 
3612*4d9fdb46SRobert Mustacchi /* No errors possible.  */
361349d3bc91SRichard Lowe void
dwarf_reset_section_bytes(Dwarf_P_Debug dbg)361449d3bc91SRichard Lowe dwarf_reset_section_bytes(Dwarf_P_Debug dbg)
361549d3bc91SRichard Lowe {
361649d3bc91SRichard Lowe     dbg->de_debug_sects = dbg->de_first_debug_sect;
3617*4d9fdb46SRobert Mustacchi     /*  No need to reset; commented out decrement. dbg->de_n_debug_sect
3618*4d9fdb46SRobert Mustacchi         = ???; */
361949d3bc91SRichard Lowe     dbg->de_reloc_next_to_return = 0;
362007dc1947SRichard Lowe     dbg->de_sect_sa_next_to_return = 0;
362149d3bc91SRichard Lowe }
362249d3bc91SRichard Lowe 
3623*4d9fdb46SRobert Mustacchi /*  Storage handler. Gets either a new chunk of memory, or
362449d3bc91SRichard Lowe     a pointer in existing memory, from the linked list attached
362549d3bc91SRichard Lowe     to dbg at de_debug_sects, depending on size of nbytes
362649d3bc91SRichard Lowe 
3627*4d9fdb46SRobert Mustacchi     Assume dbg not null, checked in top level routine
362849d3bc91SRichard Lowe 
362949d3bc91SRichard Lowe     Returns a pointer to the allocated buffer space for the
363049d3bc91SRichard Lowe     lib to fill in,  predincrements next-to-use count so the
3631*4d9fdb46SRobert Mustacchi     space requested is already counted 'used'
363249d3bc91SRichard Lowe     when this returns (ie, reserved).
363349d3bc91SRichard Lowe 
363449d3bc91SRichard Lowe */
363549d3bc91SRichard Lowe Dwarf_Small *
_dwarf_pro_buffer(Dwarf_P_Debug dbg,int elfsectno,unsigned long nbytes)363649d3bc91SRichard Lowe _dwarf_pro_buffer(Dwarf_P_Debug dbg,
3637*4d9fdb46SRobert Mustacchi     int elfsectno, unsigned long nbytes)
363849d3bc91SRichard Lowe {
3639*4d9fdb46SRobert Mustacchi     Dwarf_P_Section_Data cursect = 0;
364049d3bc91SRichard Lowe 
364149d3bc91SRichard Lowe     cursect = dbg->de_current_active_section;
3642*4d9fdb46SRobert Mustacchi     /*  By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must
3643*4d9fdb46SRobert Mustacchi         not match any legit section number. test to have just two
3644*4d9fdb46SRobert Mustacchi         clauses (no NULL pointer test) See dwarf_producer_init(). */
364549d3bc91SRichard Lowe     if ((cursect->ds_elf_sect_no != elfsectno) ||
364607dc1947SRichard Lowe         ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc)
364707dc1947SRichard Lowe         ) {
364807dc1947SRichard Lowe 
3649*4d9fdb46SRobert Mustacchi         /*  Either the elf section has changed or there is not enough
3650*4d9fdb46SRobert Mustacchi             space in the current section.
365107dc1947SRichard Lowe 
3652*4d9fdb46SRobert Mustacchi             Create a new Dwarf_P_Section_Data_s for the chunk. and have
3653*4d9fdb46SRobert Mustacchi             space 'on the end' for the buffer itself so we just do one
3654*4d9fdb46SRobert Mustacchi             malloc (not two).  */
365507dc1947SRichard Lowe         unsigned long space = nbytes;
365607dc1947SRichard Lowe 
365707dc1947SRichard Lowe         if (nbytes < CHUNK_SIZE)
365807dc1947SRichard Lowe             space = CHUNK_SIZE;
365907dc1947SRichard Lowe 
366007dc1947SRichard Lowe         cursect = (Dwarf_P_Section_Data)
366107dc1947SRichard Lowe             _dwarf_p_get_alloc(dbg,
3662*4d9fdb46SRobert Mustacchi                 sizeof(struct Dwarf_P_Section_Data_s)
3663*4d9fdb46SRobert Mustacchi                 + space);
3664*4d9fdb46SRobert Mustacchi         if (cursect == NULL) {
366507dc1947SRichard Lowe             return (NULL);
3666*4d9fdb46SRobert Mustacchi         }
366707dc1947SRichard Lowe 
366807dc1947SRichard Lowe         /* _dwarf_p_get_alloc zeroes the space... */
366907dc1947SRichard Lowe 
367007dc1947SRichard Lowe         cursect->ds_data = (char *) cursect +
367107dc1947SRichard Lowe             sizeof(struct Dwarf_P_Section_Data_s);
367207dc1947SRichard Lowe         cursect->ds_orig_alloc = space;
367307dc1947SRichard Lowe         cursect->ds_elf_sect_no = elfsectno;
3674*4d9fdb46SRobert Mustacchi         cursect->ds_nbytes = nbytes;    /* reserve this number of bytes
3675*4d9fdb46SRobert Mustacchi             of space for caller to fill in */
3676*4d9fdb46SRobert Mustacchi         /*  Now link on the end of the list, and mark this one as the
3677*4d9fdb46SRobert Mustacchi             current one */
367807dc1947SRichard Lowe 
367907dc1947SRichard Lowe         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
3681*4d9fdb46SRobert Mustacchi                 delete that phony one while adding this initial real
3682*4d9fdb46SRobert Mustacchi                 one. */
368307dc1947SRichard Lowe             dbg->de_debug_sects = cursect;
368407dc1947SRichard Lowe             dbg->de_current_active_section = cursect;
368507dc1947SRichard Lowe             dbg->de_first_debug_sect = cursect;
368607dc1947SRichard Lowe         } else {
368707dc1947SRichard Lowe             dbg->de_current_active_section->ds_next = cursect;
368807dc1947SRichard Lowe             dbg->de_current_active_section = cursect;
368907dc1947SRichard Lowe         }
369007dc1947SRichard Lowe         dbg->de_n_debug_sect++;
369107dc1947SRichard Lowe 
369207dc1947SRichard Lowe         return ((Dwarf_Small *) cursect->ds_data);
369349d3bc91SRichard Lowe     }
369449d3bc91SRichard Lowe 
369549d3bc91SRichard Lowe     /* There is enough space in the current buffer */
369649d3bc91SRichard Lowe     {
369707dc1947SRichard Lowe         Dwarf_Small *space_for_caller = (Dwarf_Small *)
369807dc1947SRichard Lowe             (cursect->ds_data + cursect->ds_nbytes);
369949d3bc91SRichard Lowe 
370007dc1947SRichard Lowe         cursect->ds_nbytes += nbytes;
370107dc1947SRichard Lowe         return space_for_caller;
370249d3bc91SRichard Lowe     }
370349d3bc91SRichard Lowe }
3704