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