tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_sort_line.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2   Copyright (C) 2000,2002,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
       
     3   Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
       
     4 
       
     5   This program is free software; you can redistribute it and/or modify it
       
     6   under the terms of version 2.1 of the GNU Lesser General Public License 
       
     7   as published by the Free Software Foundation.
       
     8 
       
     9   This program is distributed in the hope that it would be useful, but
       
    10   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
       
    12 
       
    13   Further, this software is distributed without any warranty that it is
       
    14   free of the rightful claim of any third person regarding infringement 
       
    15   or the like.  Any license provided herein, whether implied or 
       
    16   otherwise, applies only to this software file.  Patent licenses, if
       
    17   any, provided herein do not apply to combinations of this program with 
       
    18   other software, or any other product whatsoever.  
       
    19 
       
    20   You should have received a copy of the GNU Lesser General Public 
       
    21   License along with this program; if not, write the Free Software 
       
    22   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
       
    23   USA.
       
    24 
       
    25   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    26   Mountain View, CA 94043, or:
       
    27 
       
    28   http://www.sgi.com
       
    29 
       
    30   For further information regarding this notice, see:
       
    31 
       
    32   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    33 
       
    34 */
       
    35 /* The address of the Free Software Foundation is
       
    36    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
       
    37    Boston, MA 02110-1301, USA.
       
    38    SGI has moved from the Crittenden Lane address.
       
    39 */
       
    40 
       
    41 
       
    42 
       
    43 
       
    44 
       
    45 #include "config.h"
       
    46 #include "dwarf_incl.h"
       
    47 #include <stdio.h>
       
    48 #include <stdlib.h>
       
    49 #include "dwarf_line.h"
       
    50 #ifdef HAVE_ALLOCA_H
       
    51 #include <alloca.h>
       
    52 #endif
       
    53 #ifdef HAVE_STRING_H
       
    54 #include <string.h>
       
    55 #endif
       
    56 
       
    57 #define MINIMUM_POSSIBLE_PROLOG_LEN 10	/* 10 is based on */
       
    58 	/* the definition of the DWARF2/3 line table prolog. The value
       
    59 	   here should be >8 (accounting for a 64 bit read) and <= the
       
    60 	   length of a legal DWARF2/3 line prolog, which is at least 10 
       
    61 	   bytes long (but can be longer). What this constant helps
       
    62 	   avoid is reading past the end of a malloc'd buffer in
       
    63 	   _dwarf_update_line_sec(). */
       
    64 
       
    65 static int
       
    66   _dwarf_update_line_sec(Dwarf_Small * line_ptr,
       
    67 			 unsigned long remaining_bytes,
       
    68 			 int *any_change,
       
    69 			 int length_size,
       
    70 			 int *err_code, Dwarf_Small ** new_line_ptr);
       
    71 
       
    72 /* Used to construct
       
    73    a linked list of so we can sort and reorder the line info.
       
    74 */
       
    75 struct a_line_area {
       
    76     Dwarf_Addr ala_address;	/* from DW_LNE_set_address */
       
    77     Dwarf_Unsigned ala_offset;	/* byte offset in buffer */
       
    78     Dwarf_Unsigned ala_length;	/* byte length in buffer */
       
    79     long ala_entry_num;		/* to guarantee stable sort */
       
    80     struct a_line_area *ala_next;
       
    81 };
       
    82 
       
    83 
       
    84 /*
       
    85         Written to support the SGI IRIX static linker. 
       
    86         It helps SGI IRIX ld 
       
    87         rearrange lines in .debug_line in a .o created with a text
       
    88         section per function.   The SGI IRIX linker option is: 
       
    89                 -OPT:procedure_reorder=ON
       
    90         where ld-cord (cord(1)ing by ld, 
       
    91         not by cord(1)) may have changed the function order.
       
    92 
       
    93 	Returns
       
    94 	DW_DLV_OK if nothing went wrong.
       
    95 	DW_DLV_ERROR if could not do anything due to
       
    96 		error.  the original buffer is unchanged.
       
    97 
       
    98 	is_64_bit must be passed in by caller and tells
       
    99 	if this is a 32 or 64bit pointer object section
       
   100 	being processed.
       
   101 
       
   102 	err_code must be a non-null pointer to integer.
       
   103 	If DW_DLV_ERROR is returned that integer is set
       
   104 	to a dwarf error code so the caller may
       
   105 	print it for diagnostic purposes.
       
   106 
       
   107 	*any_change is set here 
       
   108 		set 0 if no sorting (movement) done.
       
   109 		set 1 if some sorting (movement) done.
       
   110 	on all returns. On error return sets to 0.
       
   111 	
       
   112         The _dwarf name form is now obsolete,
       
   113         the dwarf_ name for is preferred.
       
   114         Both names supported.
       
   115 
       
   116 */
       
   117 int
       
   118 _dwarf_ld_sort_lines(void *orig_buffer,
       
   119 		     unsigned long buffer_len,
       
   120 		     int is_64_bit, int *any_change, int *err_code)
       
   121 {
       
   122     return dwarf_ld_sort_lines(orig_buffer,buffer_len,
       
   123         is_64_bit,any_change,err_code);
       
   124 }
       
   125 int
       
   126 dwarf_ld_sort_lines(void *orig_buffer,
       
   127 		     unsigned long buffer_len,
       
   128 		     int is_64_bit, int *any_change, int *err_code)
       
   129 {
       
   130 
       
   131     int length_size = 4;
       
   132     Dwarf_Small *orig_line_ptr;	/* our local copy of the user's input
       
   133 				   buffer */
       
   134     Dwarf_Small *line_ptr;	/* starts at orig_line_ptr, gets
       
   135 				   incremented thru to end of our copy
       
   136 				   of the input buffer */
       
   137     Dwarf_Small *new_line_ptr;	/* output of _dwarf_update_line_sec(),
       
   138 				   used to update line_ptr as we pass
       
   139 				   thru compilation units in a .o
       
   140 				   .debug_line */
       
   141 
       
   142     unsigned long remaining_bytes = buffer_len;	/* total length of
       
   143 						   original area left
       
   144 						   to be processed.
       
   145 						   Changes as we pass
       
   146 						   thru compilation
       
   147 						   units in a .o
       
   148 						   .debug_line */
       
   149 
       
   150     int sec_res;
       
   151     int lany_change = 0;
       
   152     int did_change = 0;
       
   153 
       
   154     if (is_64_bit)
       
   155 	length_size = 8;
       
   156 
       
   157     *any_change = 0;
       
   158     line_ptr = malloc(buffer_len);
       
   159     if (!line_ptr) {
       
   160 	*err_code = DW_DLE_ALLOC_FAIL;
       
   161 	return DW_DLV_ERROR;
       
   162     }
       
   163     orig_line_ptr = line_ptr;
       
   164     memcpy(line_ptr, orig_buffer, buffer_len);
       
   165 
       
   166 
       
   167     /* 
       
   168        We must iterate thru each of a set of prologues and line data.
       
   169        We process each set in turn. If all pass, we update the
       
   170        passed-in buffer. */
       
   171     sec_res = DW_DLV_OK;
       
   172 
       
   173     for (sec_res = _dwarf_update_line_sec(line_ptr,
       
   174 					  remaining_bytes,
       
   175 					  &lany_change,
       
   176 					  length_size,
       
   177 					  err_code,
       
   178 					  &new_line_ptr);
       
   179 	 (sec_res == DW_DLV_OK) && (remaining_bytes > 0);
       
   180 	 sec_res = _dwarf_update_line_sec(line_ptr,
       
   181 					  remaining_bytes,
       
   182 					  &lany_change,
       
   183 					  length_size,
       
   184 					  err_code, &new_line_ptr)) {
       
   185 	long bytes_used = new_line_ptr - line_ptr;
       
   186 
       
   187 	line_ptr = new_line_ptr;
       
   188 	remaining_bytes -= bytes_used;
       
   189 	if (lany_change) {
       
   190 	    did_change = 1;
       
   191 	}
       
   192 	if (remaining_bytes > 0) {
       
   193 	    continue;
       
   194 	}
       
   195 	break;
       
   196     }
       
   197     if (sec_res == DW_DLV_ERROR) {
       
   198 	free(orig_line_ptr);
       
   199 	return sec_res;
       
   200     }
       
   201 
       
   202 
       
   203     /* all passed */
       
   204     if (did_change) {
       
   205 	/* So update the passed in buffer orig_buffer is caller's input 
       
   206 	   area. orig_line_ptr is our modified copy of input area. */
       
   207 	memcpy(orig_buffer, orig_line_ptr, buffer_len);
       
   208 	*any_change = 1;
       
   209     }
       
   210     free(orig_line_ptr);
       
   211 
       
   212     return sec_res;
       
   213 }
       
   214 
       
   215 
       
   216 /* By setting ala_entry_num we guarantee a stable sort,
       
   217 	no duplicates
       
   218    Sorting in address order.
       
   219 */
       
   220 static int
       
   221 cmpr(const void *lin, const void *rin)
       
   222 {
       
   223     const struct a_line_area *l = lin;
       
   224     const struct a_line_area *r = rin;
       
   225 
       
   226     if (l->ala_address < r->ala_address) {
       
   227 	return -1;
       
   228     }
       
   229     if (l->ala_address > r->ala_address) {
       
   230 	return 1;
       
   231     }
       
   232     if (l->ala_entry_num < r->ala_entry_num) {
       
   233 	return -1;
       
   234     }
       
   235     if (l->ala_entry_num > r->ala_entry_num) {
       
   236 	return 1;
       
   237     }
       
   238     return 0;			/* should never happen. */
       
   239 }
       
   240 
       
   241 
       
   242 /*
       
   243 	On entry:
       
   244 	  line_ptr must point to first
       
   245 	  byte of a line group for one (original) .o
       
   246 	  
       
   247 	  remaining_bytes is the size of the area pointed to
       
   248 	  by line_ptr: may be larger than the
       
   249 	  current original compilation unit .
       
   250 
       
   251 	  length size is 4 for 32bit pointers, 8 for 64bit pointers
       
   252 	  in the data pointed to.
       
   253 
       
   254 
       
   255 	On return:
       
   256 	  return DW_DLV_OK if all ok.  (ignore 
       
   257 		*err_code in this case)
       
   258 
       
   259 	  return DW_DLV_ERROR and set *err_code if an error.
       
   260 
       
   261 	  If some line data was moved around, set *any_change to 1.
       
   262 	  If error or no movement, set *any_change to 0;
       
   263 
       
   264 	  Set *new_line_ptr to one-byte-past the end of the
       
   265 	  current original compilation unit  (not necessary
       
   266 	  if returning DW_DLV_ERROR, but not harmful).
       
   267 
       
   268 
       
   269 	This copies the entire array to a malloc area, then
       
   270 	mallocs pieces of it (another malloc) for sorting a CU entries
       
   271 	and copying back.  Then at end  the whole new thing copied in.
       
   272 	The result is that on error, the input is not touched.
       
   273 
       
   274 	An alternative would be to just update a piece at a time
       
   275 	and on error stop updating but leave what was done, done.
       
   276 	This alternative would save some temporary malloc space.
       
   277 	
       
   278 	
       
   279 */
       
   280 static int
       
   281 _dwarf_update_line_sec(Dwarf_Small * line_ptr,
       
   282 		       unsigned long remaining_bytes,
       
   283 		       int *any_change,
       
   284 		       int length_size,
       
   285 		       int *err_code, Dwarf_Small ** new_line_ptr)
       
   286 {
       
   287 
       
   288 
       
   289     /* 
       
   290        This points to the last byte of the .debug_line portion for the
       
   291        current cu. */
       
   292     Dwarf_Small *line_ptr_end = 0;
       
   293 
       
   294     /* 
       
   295        This points to the end of the statement program prologue for the 
       
   296        current cu, and serves to check that the prologue was correctly
       
   297        decoded. */
       
   298 
       
   299     Dwarf_Small *orig_line_ptr = 0;
       
   300 
       
   301     /* These are the fields of the statement program header. */
       
   302     struct Dwarf_Debug_s dbg_data;
       
   303     Dwarf_Debug dbg = &dbg_data;
       
   304 
       
   305     /* These are the state machine state variables. */
       
   306     Dwarf_Addr address = 0;
       
   307     Dwarf_Word line = 1;
       
   308     Dwarf_Bool is_stmt = false;
       
   309 
       
   310     /* Dwarf_Bool prologue_end; Dwarf_Bool epilogue_begin; */
       
   311     Dwarf_Small isa = 0;
       
   312 
       
   313 
       
   314     struct a_line_area *area_base = 0;
       
   315     struct a_line_area *area_current = 0;
       
   316     long area_count = 0;
       
   317 
       
   318     Dwarf_Addr last_address = 0;
       
   319     int need_to_sort = 0;
       
   320 
       
   321     /* 
       
   322        This is the current opcode read from the statement program. */
       
   323     Dwarf_Small opcode = 0;
       
   324 
       
   325 
       
   326     /* 
       
   327        These variables are used to decode leb128 numbers. Leb128_num
       
   328        holds the decoded number, and leb128_length is its length in
       
   329        bytes. */
       
   330     Dwarf_Word leb128_num = 0;
       
   331     Dwarf_Sword advance_line = 0;
       
   332 
       
   333     /* 
       
   334        This is the operand of the latest fixed_advance_pc extended
       
   335        opcode. */
       
   336     Dwarf_Half fixed_advance_pc = 0;
       
   337 
       
   338     /* This is the length of an extended opcode instr.  */
       
   339     Dwarf_Word instr_length = 0;
       
   340     Dwarf_Small ext_opcode = 0;
       
   341     struct Line_Table_Prefix_s prefix;
       
   342 
       
   343 
       
   344 
       
   345     memset(dbg, 0, sizeof(struct Dwarf_Debug_s));
       
   346     dbg->de_copy_word = memcpy;
       
   347     /* 
       
   348        Following is a straightforward decoding of the statement program 
       
   349        prologue information. */
       
   350     *any_change = 0;
       
   351 
       
   352 
       
   353     orig_line_ptr = line_ptr;
       
   354     if (remaining_bytes < MINIMUM_POSSIBLE_PROLOG_LEN) {
       
   355 	/* We are at the end. Remaining should be zero bytes, padding.
       
   356 	   This is really just 'end of CU buffer' not an error. The is
       
   357 	   no 'entry' left so report there is none. We don't want to
       
   358 	   READ_UNALIGNED the total_length below and then belatedly
       
   359 	   discover that we read off the end already. */
       
   360 	return (DW_DLV_NO_ENTRY);
       
   361     }
       
   362 
       
   363     dwarf_init_line_table_prefix(&prefix);
       
   364     {
       
   365 	Dwarf_Small *line_ptr_out = 0;
       
   366 	Dwarf_Error error;
       
   367 	int dres = dwarf_read_line_table_prefix(dbg,
       
   368 						line_ptr,
       
   369 						remaining_bytes,
       
   370 						&line_ptr_out,
       
   371 						&prefix, &error);
       
   372 
       
   373 	if (dres == DW_DLV_ERROR) {
       
   374 	    dwarf_free_line_table_prefix(&prefix);
       
   375 	    *err_code = dwarf_errno(error);
       
   376 	    dwarf_dealloc(dbg, error, DW_DLA_ERROR);
       
   377 	    return dres;
       
   378 	}
       
   379 	if (dres == DW_DLV_NO_ENTRY) {
       
   380 	    dwarf_free_line_table_prefix(&prefix);
       
   381 	    return dres;
       
   382 	}
       
   383 	line_ptr_end = prefix.pf_line_ptr_end;
       
   384 
       
   385 	line_ptr = line_ptr_out;
       
   386     }
       
   387 
       
   388 
       
   389     /* Initialize the state machine.  */
       
   390     /* file = 1; */
       
   391     /* column = 0; */
       
   392     is_stmt = prefix.pf_default_is_stmt;
       
   393     /* basic_block = false; */
       
   394     /* end_sequence = false; */
       
   395     /* prologue_end = false; */
       
   396     /* epilogue_begin = false; */
       
   397     isa = 0;
       
   398 
       
   399 
       
   400     /* Start of statement program.  */
       
   401     while (line_ptr < line_ptr_end) {
       
   402 	int type;
       
   403 
       
   404 	Dwarf_Small *stmt_prog_entry_start = line_ptr;
       
   405 
       
   406 	opcode = *(Dwarf_Small *) line_ptr;
       
   407 	line_ptr++;
       
   408 	/* 'type' is the output */
       
   409 	WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
       
   410 		       prefix.pf_opcode_length_table, line_ptr,
       
   411 		       prefix.pf_std_op_count);
       
   412 
       
   413 	if (type == LOP_DISCARD) {
       
   414 	    int oc;
       
   415 	    int opcnt = prefix.pf_opcode_length_table[opcode];
       
   416 
       
   417 	    for (oc = 0; oc < opcnt; oc++) {
       
   418 		/* 
       
   419 		 ** Read and discard operands we don't
       
   420 		 ** understand.
       
   421 		 ** arbitrary choice of unsigned read.
       
   422 		 ** signed read would work as well.
       
   423 		 */
       
   424 		Dwarf_Unsigned utmp2;
       
   425 
       
   426 		DECODE_LEB128_UWORD(line_ptr, utmp2);
       
   427 	    }
       
   428 
       
   429 	} else if (type == LOP_SPECIAL) {
       
   430 	    opcode = opcode - prefix.pf_opcode_base;
       
   431 	    address = address + prefix.pf_minimum_instruction_length *
       
   432 		(opcode / prefix.pf_line_range);
       
   433 	    line =
       
   434 		line + prefix.pf_line_base +
       
   435 		opcode % prefix.pf_line_range;
       
   436 
       
   437 	    /* basic_block = false; */
       
   438 
       
   439 
       
   440 	} else if (type == LOP_STANDARD) {
       
   441 
       
   442 
       
   443 	    switch (opcode) {
       
   444 
       
   445 
       
   446 	    case DW_LNS_copy:{
       
   447 
       
   448 		    /* basic_block = false; */
       
   449 		    break;
       
   450 		}
       
   451 
       
   452 	    case DW_LNS_advance_pc:{
       
   453 		    Dwarf_Unsigned utmp2;
       
   454 
       
   455 
       
   456 		    DECODE_LEB128_UWORD(line_ptr, utmp2);
       
   457 		    leb128_num = (Dwarf_Word) utmp2;
       
   458 		    address =
       
   459 			address +
       
   460 			prefix.pf_minimum_instruction_length *
       
   461 			leb128_num;
       
   462 		    break;
       
   463 		}
       
   464 
       
   465 	    case DW_LNS_advance_line:{
       
   466 		    Dwarf_Signed stmp;
       
   467 
       
   468 
       
   469 		    DECODE_LEB128_SWORD(line_ptr, stmp);
       
   470 		    advance_line = (Dwarf_Sword) stmp;
       
   471 		    line = line + advance_line;
       
   472 		    break;
       
   473 		}
       
   474 
       
   475 	    case DW_LNS_set_file:{
       
   476 		    Dwarf_Unsigned utmp2;
       
   477 
       
   478 
       
   479 		    DECODE_LEB128_UWORD(line_ptr, utmp2);
       
   480 		    /* file = (Dwarf_Word)utmp2; */
       
   481 		    break;
       
   482 		}
       
   483 
       
   484 	    case DW_LNS_set_column:{
       
   485 		    Dwarf_Unsigned utmp2;
       
   486 
       
   487 
       
   488 		    DECODE_LEB128_UWORD(line_ptr, utmp2);
       
   489 		    /* column = (Dwarf_Word)utmp2; */
       
   490 		    break;
       
   491 		}
       
   492 
       
   493 	    case DW_LNS_negate_stmt:{
       
   494 
       
   495 		    is_stmt = !is_stmt;
       
   496 		    break;
       
   497 		}
       
   498 
       
   499 	    case DW_LNS_set_basic_block:{
       
   500 
       
   501 		    /* basic_block = true; */
       
   502 		    break;
       
   503 		}
       
   504 
       
   505 	    case DW_LNS_const_add_pc:{
       
   506 		    opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
       
   507 		    address =
       
   508 			address +
       
   509 			prefix.pf_minimum_instruction_length * (opcode /
       
   510 								prefix.
       
   511 								pf_line_range);
       
   512 
       
   513 		    break;
       
   514 		}
       
   515 
       
   516 	    case DW_LNS_fixed_advance_pc:{
       
   517 
       
   518 		    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
       
   519 				   line_ptr, sizeof(Dwarf_Half));
       
   520 		    line_ptr += sizeof(Dwarf_Half);
       
   521 		    address = address + fixed_advance_pc;
       
   522 		    break;
       
   523 		}
       
   524 		/* New in DWARF3 */
       
   525 	    case DW_LNS_set_prologue_end:{
       
   526 
       
   527 		    /* prologue_end = true; */
       
   528 		    break;
       
   529 
       
   530 
       
   531 		}
       
   532 		/* New in DWARF3 */
       
   533 	    case DW_LNS_set_epilogue_begin:{
       
   534 		    /* epilogue_begin = true; */
       
   535 		    break;
       
   536 		}
       
   537 
       
   538 		/* New in DWARF3 */
       
   539 	    case DW_LNS_set_isa:{
       
   540 		    Dwarf_Unsigned utmp2;
       
   541 
       
   542 		    DECODE_LEB128_UWORD(line_ptr, utmp2);
       
   543 		    isa = utmp2;
       
   544 		    if (isa != utmp2) {
       
   545 			/* The value of the isa did not fit in our
       
   546 			   local so we record it wrong. declare an
       
   547 			   error. */
       
   548 			dwarf_free_line_table_prefix(&prefix);
       
   549 
       
   550 			*err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
       
   551 			return (DW_DLV_ERROR);
       
   552 		    }
       
   553 		    break;
       
   554 		}
       
   555 
       
   556 	    }
       
   557 	} else if (type == LOP_EXTENDED) {
       
   558 
       
   559 
       
   560 	    Dwarf_Unsigned utmp3;
       
   561 
       
   562 	    DECODE_LEB128_UWORD(line_ptr, utmp3);
       
   563 	    instr_length = (Dwarf_Word) utmp3;
       
   564 	    ext_opcode = *(Dwarf_Small *) line_ptr;
       
   565 	    line_ptr++;
       
   566 	    switch (ext_opcode) {
       
   567 
       
   568 	    case DW_LNE_end_sequence:{
       
   569 		    /* end_sequence = true; */
       
   570 
       
   571 		    address = 0;
       
   572 		    /* file = 1; */
       
   573 		    line = 1;
       
   574 		    /* column = 0; */
       
   575 		    is_stmt = prefix.pf_default_is_stmt;
       
   576 		    /* basic_block = false; */
       
   577 		    /* end_sequence = false; */
       
   578 		    /* prologue_end = false; */
       
   579 		    /* epilogue_begin = false; */
       
   580 
       
   581 
       
   582 		    break;
       
   583 		}
       
   584 
       
   585 	    case DW_LNE_set_address:{
       
   586 		    if (instr_length - 1 == length_size) {
       
   587 			struct a_line_area *area;
       
   588 
       
   589 			READ_UNALIGNED(dbg, address, Dwarf_Addr,
       
   590 				       line_ptr, length_size);
       
   591 			/* Here we need to remember the offset into the 
       
   592 			   buffer and check to see if address went
       
   593 			   down. */
       
   594 			if (address < last_address) {
       
   595 			    need_to_sort = 1;
       
   596 			}
       
   597 			last_address = address;
       
   598 
       
   599 			area = alloca(sizeof(struct a_line_area));
       
   600 			area->ala_address = address;
       
   601 			area->ala_offset = stmt_prog_entry_start -
       
   602 			    orig_line_ptr;
       
   603 			area->ala_entry_num = area_count;
       
   604 			area->ala_next = 0;
       
   605 			area->ala_length = 0;
       
   606 			if (area_current) {
       
   607 			    area_current->ala_next = area;
       
   608 			    area_current->ala_length =
       
   609 				area->ala_offset -
       
   610 				area_current->ala_offset;
       
   611 			}
       
   612 			++area_count;
       
   613 			area_current = area;
       
   614 			if (area_base == 0) {
       
   615 			    area_base = area;
       
   616 			}
       
   617 
       
   618 			line_ptr += length_size;
       
   619 		    } else {
       
   620 			*err_code = DW_DLE_LINE_SET_ADDR_ERROR;
       
   621 			dwarf_free_line_table_prefix(&prefix);
       
   622 			return (DW_DLV_ERROR);
       
   623 		    }
       
   624 
       
   625 
       
   626 		    break;
       
   627 		}
       
   628 
       
   629 	    case DW_LNE_define_file:{
       
   630 
       
   631 		    break;
       
   632 		}
       
   633 
       
   634 	    default:{
       
   635 		    *err_code = DW_DLE_LINE_EXT_OPCODE_BAD;
       
   636 		    dwarf_free_line_table_prefix(&prefix);
       
   637 		    return (DW_DLV_ERROR);
       
   638 		}
       
   639 	    }
       
   640 
       
   641 	}
       
   642     }
       
   643 
       
   644 
       
   645     *new_line_ptr = line_ptr;
       
   646     if (!need_to_sort) {
       
   647 	dwarf_free_line_table_prefix(&prefix);
       
   648 	return (DW_DLV_OK);
       
   649     }
       
   650 
       
   651     /* so now we have something to sort. First, finish off the last
       
   652        area record: */
       
   653     area_current->ala_length = (line_ptr - orig_line_ptr)	/* final 
       
   654 								   offset 
       
   655 								 */
       
   656 	-area_current->ala_offset;
       
   657 
       
   658     /* Build and sort a simple array of sections. Forcing a stable sort 
       
   659        by comparing on sequence number. We will use the sorted list to
       
   660        move sections of this part of the line table. Each 'section'
       
   661        starting with a DW_LNE_set_address opcode, on the assumption
       
   662        that such only get out of order where there was an ld-cord
       
   663        function rearrangement and that it is meaningful to restart the
       
   664        line info there. */
       
   665     {
       
   666 	struct a_line_area *ala_array;
       
   667 	struct a_line_area *local;
       
   668 	long start_len;
       
   669 	Dwarf_Small *new_area;
       
   670 	long i;
       
   671 
       
   672 	ala_array = malloc(area_count * sizeof(struct a_line_area));
       
   673 	if (!ala_array) {
       
   674 	    dwarf_free_line_table_prefix(&prefix);
       
   675 	    *err_code = DW_DLE_ALLOC_FAIL;
       
   676 	    return DW_DLV_ERROR;
       
   677 	}
       
   678 
       
   679 	for (local = area_base, i = 0; local;
       
   680 	     local = local->ala_next, ++i) {
       
   681 
       
   682 	    ala_array[i] = *local;
       
   683 	}
       
   684 
       
   685 	qsort(ala_array, area_count, sizeof(struct a_line_area), cmpr);
       
   686 
       
   687 	/* Now we must rearrange the pieces of the line table. */
       
   688 
       
   689 	start_len =
       
   690 	    (prefix.pf_line_prologue_start +
       
   691 	     prefix.pf_prologue_length) - orig_line_ptr;
       
   692 	new_area = malloc(remaining_bytes);
       
   693 	if (!new_area) {
       
   694 	    free(ala_array);
       
   695 	    *err_code = DW_DLE_ALLOC_FAIL;
       
   696 	    dwarf_free_line_table_prefix(&prefix);
       
   697 	    return DW_DLV_ERROR;
       
   698 	}
       
   699 	memcpy(new_area, orig_line_ptr, start_len);
       
   700 	line_ptr = new_area + start_len;
       
   701 	for (i = 0; i < area_count; ++i) {
       
   702 	    memcpy(line_ptr, orig_line_ptr +
       
   703 		   ala_array[i].ala_offset, ala_array[i].ala_length);
       
   704 	    line_ptr += ala_array[i].ala_length;
       
   705 	}
       
   706 
       
   707 	memcpy(orig_line_ptr, new_area, remaining_bytes);
       
   708 
       
   709 	free(new_area);
       
   710 	free(ala_array);
       
   711 	ala_array = 0;
       
   712 	new_area = 0;
       
   713     }
       
   714 
       
   715     *any_change = 1;
       
   716     dwarf_free_line_table_prefix(&prefix);
       
   717     return (DW_DLV_OK);
       
   718 }