|
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 } |