2 /*--------------------------------------------------------------------*/
3 /*--- Format-neutral storage of and querying of info acquired from ---*/
4 /*--- ELF/XCOFF stabs/dwarf1/dwarf2/dwarf3 debug info. ---*/
6 /*--------------------------------------------------------------------*/
9 This file is part of Valgrind, a dynamic binary instrumentation
12 Copyright (C) 2000-2017 Julian Seward
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
30 The GNU General Public License is contained in the file COPYING.
33 /* This file manages the data structures built by the debuginfo
34 system. These are: the top level SegInfo list. For each SegInfo,
35 there are tables for address-to-symbol mappings,
36 address-to-src-file/line mappings, and address-to-CFI-info
40 #include "pub_core_basics.h"
41 #include "pub_core_options.h" /* VG_(clo_verbosity) */
42 #include "pub_core_debuginfo.h"
43 #include "pub_core_debuglog.h"
44 #include "pub_core_libcassert.h"
45 #include "pub_core_libcbase.h"
46 #include "pub_core_libcprint.h"
47 #include "pub_core_xarray.h"
48 #include "pub_core_oset.h"
49 #include "pub_core_deduppoolalloc.h"
51 #include "priv_misc.h" /* dinfo_zalloc/free/strdup */
52 #include "priv_image.h"
53 #include "priv_d3basics.h" /* ML_(pp_GX) */
54 #include "priv_tytypes.h"
55 #include "priv_storage.h" /* self */
58 /*------------------------------------------------------------*/
59 /*--- Misc (printing, errors) ---*/
60 /*------------------------------------------------------------*/
62 /* Show a non-fatal debug info reading error. Use VG_(core_panic) for
63 fatal errors. 'serious' errors are shown regardless of the
65 void ML_(symerr
) ( const DebugInfo
* di
, Bool serious
, const HChar
* msg
)
67 /* XML mode hides everything :-( */
73 VG_(message
)(Vg_DebugMsg
, "WARNING: Serious error when "
74 "reading debug info\n");
75 if (True
|| VG_(clo_verbosity
) < 2) {
76 /* Need to show what the file name is, at verbosity levels 2
77 or below, since that won't already have been shown */
78 VG_(message
)(Vg_DebugMsg
,
79 "When reading debug info from %s:\n",
80 (di
&& di
->fsm
.filename
) ? di
->fsm
.filename
83 VG_(message
)(Vg_DebugMsg
, "%s\n", msg
);
85 } else { /* !serious */
87 if (VG_(clo_verbosity
) >= 2)
88 VG_(message
)(Vg_DebugMsg
, "%s\n", msg
);
95 void ML_(ppSym
) ( Int idx
, const DiSym
* sym
)
97 const HChar
** sec_names
= sym
->sec_names
;
98 vg_assert(sym
->pri_name
);
100 vg_assert(sec_names
);
101 VG_(printf
)( "%5d: %c%c%c %#8lx .. %#8lx (%u) %s%s",
103 sym
->isText
? 'T' : '-',
104 sym
->isIFunc
? 'I' : '-',
105 sym
->isGlobal
? 'G' : '-',
107 sym
->avmas
.main
+ sym
->size
- 1, sym
->size
,
108 sym
->pri_name
, sec_names
? " " : "" );
111 VG_(printf
)("%s%s", *sec_names
, *(sec_names
+1) ? " " : "");
118 /* Print a call-frame-info summary. */
119 void ML_(ppDiCfSI
) ( const XArray
* /* of CfiExpr */ exprs
,
121 const DiCfSI_m
* si_m
)
123 # define SHOW_HOW(_how, _off) \
125 if (_how == CFIR_UNKNOWN) { \
126 VG_(printf)("Unknown"); \
128 if (_how == CFIR_SAME) { \
129 VG_(printf)("Same"); \
131 if (_how == CFIR_CFAREL) { \
132 VG_(printf)("cfa+%d", _off); \
134 if (_how == CFIR_MEMCFAREL) { \
135 VG_(printf)("*(cfa+%d)", _off); \
137 if (_how == CFIR_EXPR) { \
139 ML_(ppCfiExpr)(exprs, _off); \
146 if (base
!= 0 || len
!= 0)
147 VG_(printf
)("[%#lx .. %#lx]: ", base
, base
+ len
- 1);
151 switch (si_m
->cfa_how
) {
153 VG_(printf
)("let cfa=oldSP+%d", si_m
->cfa_off
);
156 VG_(printf
)("let cfa=oldBP+%d", si_m
->cfa_off
);
158 case CFIC_ARM_R13REL
:
159 VG_(printf
)("let cfa=oldR13+%d", si_m
->cfa_off
);
161 case CFIC_ARM_R12REL
:
162 VG_(printf
)("let cfa=oldR12+%d", si_m
->cfa_off
);
164 case CFIC_ARM_R11REL
:
165 VG_(printf
)("let cfa=oldR11+%d", si_m
->cfa_off
);
168 VG_(printf
)("let cfa=Same");
171 VG_(printf
)("let cfa=oldR7+%d", si_m
->cfa_off
);
173 case CFIC_ARM64_SPREL
:
174 VG_(printf
)("let cfa=oldSP+%d", si_m
->cfa_off
);
176 case CFIC_ARM64_X29REL
:
177 VG_(printf
)("let cfa=oldX29+%d", si_m
->cfa_off
);
180 VG_(printf
)("let cfa={");
181 ML_(ppCfiExpr
)(exprs
, si_m
->cfa_off
);
188 VG_(printf
)(" in RA=");
189 SHOW_HOW(si_m
->ra_how
, si_m
->ra_off
);
190 # if defined(VGA_x86) || defined(VGA_amd64)
192 SHOW_HOW(si_m
->sp_how
, si_m
->sp_off
);
194 SHOW_HOW(si_m
->bp_how
, si_m
->bp_off
);
195 # elif defined(VGA_arm)
196 VG_(printf
)(" R14=");
197 SHOW_HOW(si_m
->r14_how
, si_m
->r14_off
);
198 VG_(printf
)(" R13=");
199 SHOW_HOW(si_m
->r13_how
, si_m
->r13_off
);
200 VG_(printf
)(" R12=");
201 SHOW_HOW(si_m
->r12_how
, si_m
->r12_off
);
202 VG_(printf
)(" R11=");
203 SHOW_HOW(si_m
->r11_how
, si_m
->r11_off
);
205 SHOW_HOW(si_m
->r7_how
, si_m
->r7_off
);
206 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
207 # elif defined(VGA_s390x) || defined(VGA_mips32) || defined(VGA_mips64)
209 SHOW_HOW(si_m
->sp_how
, si_m
->sp_off
);
211 SHOW_HOW(si_m
->fp_how
, si_m
->fp_off
);
212 # elif defined(VGA_arm64)
214 SHOW_HOW(si_m
->sp_how
, si_m
->sp_off
);
215 VG_(printf
)(" X30=");
216 SHOW_HOW(si_m
->x30_how
, si_m
->x30_off
);
217 VG_(printf
)(" X29=");
218 SHOW_HOW(si_m
->x29_how
, si_m
->x29_off
);
220 # error "Unknown arch"
227 /*------------------------------------------------------------*/
228 /*--- Adding stuff ---*/
229 /*------------------------------------------------------------*/
231 /* If not yet in strpool, add a str to the string pool including terminating
233 Return the pointer to the string in strpool.
235 const HChar
* ML_(addStr
) ( DebugInfo
* di
, const HChar
* str
, Int len
)
238 len
= VG_(strlen
)(str
);
242 if (UNLIKELY(di
->strpool
== NULL
))
243 di
->strpool
= VG_(newDedupPA
)(SEGINFO_STRPOOLSIZE
,
246 "di.storage.addStr.1",
248 return VG_(allocEltDedupPA
) (di
->strpool
, len
+1, str
);
251 UInt
ML_(addFnDn
) (struct _DebugInfo
* di
,
252 const HChar
* filename
,
253 const HChar
* dirname
)
258 if (UNLIKELY(di
->fndnpool
== NULL
))
259 di
->fndnpool
= VG_(newDedupPA
)(500,
262 "di.storage.addFnDn.1",
264 fndn
.filename
= ML_(addStr
)(di
, filename
, -1);
265 fndn
.dirname
= dirname
? ML_(addStr
)(di
, dirname
, -1) : NULL
;
266 fndn_ix
= VG_(allocFixedEltDedupPA
) (di
->fndnpool
, sizeof(FnDn
), &fndn
);
270 const HChar
* ML_(fndn_ix2filename
) (const DebugInfo
* di
,
277 fndn
= VG_(indexEltNumber
) (di
->fndnpool
, fndn_ix
);
278 return fndn
->filename
;
282 const HChar
* ML_(fndn_ix2dirname
) (const DebugInfo
* di
,
289 fndn
= VG_(indexEltNumber
) (di
->fndnpool
, fndn_ix
);
291 return fndn
->dirname
;
297 /* Add a string to the string table of a DebugInfo, by copying the
298 string from the given DiCursor. Measures the length of the string
300 const HChar
* ML_(addStrFromCursor
)( DebugInfo
* di
, DiCursor c
)
302 /* This is a less-than-stellar implementation, but it should
304 vg_assert(ML_(cur_is_valid
)(c
));
305 HChar
* str
= ML_(cur_read_strdup
)(c
, "di.addStrFromCursor.1");
306 const HChar
* res
= ML_(addStr
)(di
, str
, -1);
307 ML_(dinfo_free
)(str
);
312 /* Add a symbol to the symbol table, by copying *sym. 'sym' may only
313 have one name, so there's no complexities to do with deep vs
314 shallow copying of the sec_name array. This is checked.
316 void ML_(addSym
) ( struct _DebugInfo
* di
, DiSym
* sym
)
321 vg_assert(sym
->pri_name
!= NULL
);
322 vg_assert(sym
->sec_names
== NULL
);
324 /* Ignore zero-sized syms. */
325 if (sym
->size
== 0) return;
327 if (di
->symtab_used
== di
->symtab_size
) {
328 new_sz
= 2 * di
->symtab_size
;
329 if (new_sz
== 0) new_sz
= 500;
330 new_tab
= ML_(dinfo_zalloc
)( "di.storage.addSym.1",
331 new_sz
* sizeof(DiSym
) );
332 if (di
->symtab
!= NULL
) {
333 for (i
= 0; i
< di
->symtab_used
; i
++)
334 new_tab
[i
] = di
->symtab
[i
];
335 ML_(dinfo_free
)(di
->symtab
);
337 di
->symtab
= new_tab
;
338 di
->symtab_size
= new_sz
;
341 di
->symtab
[di
->symtab_used
++] = *sym
;
342 vg_assert(di
->symtab_used
<= di
->symtab_size
);
345 UInt
ML_(fndn_ix
) (const DebugInfo
* di
, Word locno
)
349 switch(di
->sizeof_fndn_ix
) {
350 case 1: fndn_ix
= ((UChar
*) di
->loctab_fndn_ix
)[locno
]; break;
351 case 2: fndn_ix
= ((UShort
*) di
->loctab_fndn_ix
)[locno
]; break;
352 case 4: fndn_ix
= ((UInt
*) di
->loctab_fndn_ix
)[locno
]; break;
353 default: vg_assert(0);
358 static inline void set_fndn_ix (struct _DebugInfo
* di
, Word locno
, UInt fndn_ix
)
362 switch(di
->sizeof_fndn_ix
) {
364 if (LIKELY (fndn_ix
<= 255)) {
365 ((UChar
*) di
->loctab_fndn_ix
)[locno
] = fndn_ix
;
369 UChar
* old
= (UChar
*) di
->loctab_fndn_ix
;
370 UShort
* new = ML_(dinfo_zalloc
)( "di.storage.sfix.1",
371 di
->loctab_size
* 2 );
372 for (i
= 0; i
< di
->loctab_used
; i
++)
374 ML_(dinfo_free
)(old
);
375 di
->sizeof_fndn_ix
= 2;
376 di
->loctab_fndn_ix
= new;
381 if (LIKELY (fndn_ix
<= 65535)) {
382 ((UShort
*) di
->loctab_fndn_ix
)[locno
] = fndn_ix
;
386 UShort
* old
= (UShort
*) di
->loctab_fndn_ix
;
387 UInt
* new = ML_(dinfo_zalloc
)( "di.storage.sfix.2",
388 di
->loctab_size
* 4 );
389 for (i
= 0; i
< di
->loctab_used
; i
++)
391 ML_(dinfo_free
)(old
);
392 di
->sizeof_fndn_ix
= 4;
393 di
->loctab_fndn_ix
= new;
398 ((UInt
*) di
->loctab_fndn_ix
)[locno
] = fndn_ix
;
401 default: vg_assert(0);
406 // Comment the below line to trace LOCTAB merging/canonicalising
407 #define TRACE_LOCTAB_CANON(msg,prev_loc,cur_loc)
408 #ifndef TRACE_LOCTAB_CANON
409 #define TRACE_LOCTAB_CANON(msg,prev_loc,cur_loc) \
410 VG_(printf)("%s previous: addr %#lx, size %d, line %d, " \
411 " current: addr %#lx, size %d, line %d.\n", \
413 (prev_loc)->addr, (prev_loc)->size, (prev_loc)->lineno, \
414 (cur_loc)->addr, (cur_loc)->size, (cur_loc)->lineno);
417 /* Add a location to the location table.
419 static void addLoc ( struct _DebugInfo
* di
, DiLoc
* loc
, UInt fndn_ix
)
421 /* Zero-sized locs should have been ignored earlier */
422 vg_assert(loc
->size
> 0);
424 /* Check if the last entry has adjacent range for the same line. */
425 if (di
->loctab_used
> 0) {
426 DiLoc
*previous
= &di
->loctab
[di
->loctab_used
- 1];
427 if ((previous
->lineno
== loc
->lineno
)
428 && (previous
->addr
+ previous
->size
== loc
->addr
)) {
429 if (previous
->size
+ loc
->size
<= MAX_LOC_SIZE
) {
430 TRACE_LOCTAB_CANON ("addLoc merging", previous
, loc
);
431 previous
->size
+= loc
->size
;
434 TRACE_LOCTAB_CANON ("addLoc merging not done (maxsize)",
440 if (di
->loctab_used
== di
->loctab_size
) {
443 void* new_loctab_fndn_ix
;
445 new_sz
= 2 * di
->loctab_size
;
446 if (new_sz
== 0) new_sz
= 500;
447 new_loctab
= ML_(dinfo_zalloc
)( "di.storage.addLoc.1",
448 new_sz
* sizeof(DiLoc
) );
449 if (di
->sizeof_fndn_ix
== 0)
450 di
->sizeof_fndn_ix
= 1; // To start with.
451 new_loctab_fndn_ix
= ML_(dinfo_zalloc
)( "di.storage.addLoc.2",
452 new_sz
* di
->sizeof_fndn_ix
);
453 if (di
->loctab
!= NULL
) {
454 VG_(memcpy
)(new_loctab
, di
->loctab
,
455 di
->loctab_used
* sizeof(DiLoc
));
456 VG_(memcpy
)(new_loctab_fndn_ix
, di
->loctab_fndn_ix
,
457 di
->loctab_used
* di
->sizeof_fndn_ix
);
458 ML_(dinfo_free
)(di
->loctab
);
459 ML_(dinfo_free
)(di
->loctab_fndn_ix
);
461 di
->loctab
= new_loctab
;
462 di
->loctab_fndn_ix
= new_loctab_fndn_ix
;
463 di
->loctab_size
= new_sz
;
466 di
->loctab
[di
->loctab_used
] = *loc
;
467 set_fndn_ix (di
, di
->loctab_used
, fndn_ix
);
469 vg_assert(di
->loctab_used
<= di
->loctab_size
);
473 /* Resize the LocTab (line number table) to save memory, by removing
474 (and, potentially, allowing m_mallocfree to unmap) any unused space
475 at the end of the table. */
476 static void shrinkLocTab ( struct _DebugInfo
* di
)
478 UWord new_sz
= di
->loctab_used
;
479 if (new_sz
== di
->loctab_size
) return;
480 vg_assert(new_sz
< di
->loctab_size
);
481 ML_(dinfo_shrink_block
)( di
->loctab
, new_sz
* sizeof(DiLoc
));
482 ML_(dinfo_shrink_block
)( di
->loctab_fndn_ix
, new_sz
* di
->sizeof_fndn_ix
);
483 di
->loctab_size
= new_sz
;
486 #define COMPLAIN_ONCE(what, limit, limit_op) \
488 static Bool complained = False; \
491 VG_(message)(Vg_UserMsg, \
492 "warning: Can't handle " what " with " \
493 "line number %d " limit_op " than %d\n", \
495 VG_(message)(Vg_UserMsg, \
496 "(Nb: this message is only shown once)\n"); \
501 /* Top-level place to call to add a source-location mapping entry.
503 void ML_(addLineInfo
) ( struct _DebugInfo
* di
,
508 Int entry
/* only needed for debug printing */
511 static const Bool debug
= False
;
513 UWord size
= next
- this;
515 /* Ignore zero-sized locs */
516 if (this == next
) return;
519 FnDn
*fndn
= VG_(indexEltNumber
) (di
->fndnpool
, fndn_ix
);
520 VG_(printf
)( " src ix %u %s %s line %d %#lx-%#lx\n",
522 fndn
->dirname
? fndn
->dirname
: "(unknown)",
523 fndn
->filename
, lineno
, this, next
);
526 /* Maximum sanity checking. Some versions of GNU as do a shabby
527 * job with stabs entries; if anything looks suspicious, revert to
528 * a size of 1. This should catch the instruction of interest
529 * (since if using asm-level debug info, one instruction will
530 * correspond to one line, unlike with C-level debug info where
531 * multiple instructions can map to the one line), but avoid
532 * catching any other instructions bogusly. */
534 if (VG_(clo_verbosity
) > 2) {
535 VG_(message
)(Vg_DebugMsg
,
536 "warning: line info addresses out of order "
537 "at entry %d: 0x%lx 0x%lx\n", entry
, this, next
);
542 if (size
> MAX_LOC_SIZE
) {
544 VG_(message
)(Vg_DebugMsg
,
545 "warning: line info address range too large "
546 "at entry %d: %lu\n", entry
, size
);
550 /* At this point, we know that the original value for |size|, viz
551 |next - this|, will only still be used in the case where
552 |this| <u |next|, so it can't have underflowed. Considering
553 that and the three checks that follow it, the following must
555 vg_assert(size
>= 1);
556 vg_assert(size
<= MAX_LOC_SIZE
);
558 /* Rule out ones which are completely outside the r-x mapped area.
559 See "Comment_Regarding_Text_Range_Checks" elsewhere in this file
560 for background and rationale. */
561 vg_assert(di
->fsm
.have_rx_map
&& di
->fsm
.have_rw_map
);
562 if (ML_(find_rx_mapping
)(di
, this, this + size
- 1) == NULL
) {
564 VG_(message
)(Vg_DebugMsg
,
565 "warning: ignoring line info entry falling "
566 "outside current DebugInfo: %#lx %#lx %#lx %#lx\n",
568 di
->text_avma
+ di
->text_size
,
569 this, this + size
- 1);
574 COMPLAIN_ONCE("line info entry", 0, "smaller");
577 if (lineno
> MAX_LINENO
) {
578 COMPLAIN_ONCE("line info entry", MAX_LINENO
, "greater");
583 loc
.size
= (UShort
)size
;
586 if (0) VG_(message
)(Vg_DebugMsg
,
587 "addLoc: addr %#lx, size %lu, line %d, fndn_ix %u\n",
588 this,size
,lineno
,fndn_ix
);
590 addLoc ( di
, &loc
, fndn_ix
);
593 /* Add an inlined call info to the inlined call table.
595 static void addInl ( struct _DebugInfo
* di
, DiInlLoc
* inl
)
600 /* empty inl should have been ignored earlier */
601 vg_assert(inl
->addr_lo
< inl
->addr_hi
);
603 if (di
->inltab_used
== di
->inltab_size
) {
604 new_sz
= 2 * di
->inltab_size
;
605 if (new_sz
== 0) new_sz
= 500;
606 new_tab
= ML_(dinfo_zalloc
)( "di.storage.addInl.1",
607 new_sz
* sizeof(DiInlLoc
) );
608 if (di
->inltab
!= NULL
) {
609 for (i
= 0; i
< di
->inltab_used
; i
++)
610 new_tab
[i
] = di
->inltab
[i
];
611 ML_(dinfo_free
)(di
->inltab
);
613 di
->inltab
= new_tab
;
614 di
->inltab_size
= new_sz
;
617 di
->inltab
[di
->inltab_used
] = *inl
;
618 if (inl
->addr_hi
- inl
->addr_lo
> di
->maxinl_codesz
)
619 di
->maxinl_codesz
= inl
->addr_hi
- inl
->addr_lo
;
621 vg_assert(di
->inltab_used
<= di
->inltab_size
);
625 /* Resize the InlTab (inlined call table) to save memory, by removing
626 (and, potentially, allowing m_mallocfree to unmap) any unused space
627 at the end of the table. */
628 static void shrinkInlTab ( struct _DebugInfo
* di
)
630 UWord new_sz
= di
->inltab_used
;
631 if (new_sz
== di
->inltab_size
) return;
632 vg_assert(new_sz
< di
->inltab_size
);
633 ML_(dinfo_shrink_block
)( di
->inltab
, new_sz
* sizeof(DiInlLoc
));
634 di
->inltab_size
= new_sz
;
637 /* Top-level place to call to add a addr-to-inlined fn info. */
638 void ML_(addInlInfo
) ( struct _DebugInfo
* di
,
639 Addr addr_lo
, Addr addr_hi
,
640 const HChar
* inlinedfn
,
642 Int lineno
, UShort level
)
646 /* Similar paranoia as in ML_(addLineInfo). Unclear if needed. */
647 if (addr_lo
>= addr_hi
) {
648 if (VG_(clo_verbosity
) > 2) {
649 VG_(message
)(Vg_DebugMsg
,
650 "warning: inlined info addresses out of order "
651 "at: 0x%lx 0x%lx\n", addr_lo
, addr_hi
);
653 addr_hi
= addr_lo
+ 1;
657 COMPLAIN_ONCE ("inlined call info entry", 0, "smaller");
660 if (lineno
> MAX_LINENO
) {
661 COMPLAIN_ONCE ("inlined call info entry", MAX_LINENO
, "greater");
665 // code resulting from inlining of inlinedfn:
666 inl
.addr_lo
= addr_lo
;
667 inl
.addr_hi
= addr_hi
;
668 inl
.inlinedfn
= inlinedfn
;
670 inl
.fndn_ix
= fndn_ix
;
676 "addInlInfo: fn %s inlined as addr_lo %#lx,addr_hi %#lx,"
677 "caller fndn_ix %u %s:%d\n",
678 inlinedfn
, addr_lo
, addr_hi
, fndn_ix
,
679 ML_(fndn_ix2filename
) (di
, fndn_ix
), lineno
);
684 DiCfSI_m
* ML_(get_cfsi_m
) (const DebugInfo
* di
, UInt pos
)
688 vg_assert(pos
>= 0 && pos
< di
->cfsi_used
);
689 switch (di
->sizeof_cfsi_m_ix
) {
690 case 1: cfsi_m_ix
= ((UChar
*) di
->cfsi_m_ix
)[pos
]; break;
691 case 2: cfsi_m_ix
= ((UShort
*) di
->cfsi_m_ix
)[pos
]; break;
692 case 4: cfsi_m_ix
= ((UInt
*) di
->cfsi_m_ix
)[pos
]; break;
693 default: vg_assert(0);
696 return NULL
; // cfi hole
698 return VG_(indexEltNumber
) (di
->cfsi_m_pool
, cfsi_m_ix
);
701 /* Top-level place to call to add a CFI summary record. The supplied
702 DiCfSI_m is copied. */
703 void ML_(addDiCfSI
) ( struct _DebugInfo
* di
,
704 Addr base
, UInt len
, DiCfSI_m
* cfsi_m
)
706 static const Bool debug
= False
;
710 DebugInfoMapping
* map
;
711 DebugInfoMapping
* map2
;
714 VG_(printf
)("adding DiCfSI: ");
715 ML_(ppDiCfSI
)(di
->cfsi_exprs
, base
, len
, cfsi_m
);
720 /* Issue a warning if LEN is unexpectedly large (exceeds 5 million).
721 The implication is you have a single procedure
722 with more than 5 million bytes of code. Which is pretty
723 unlikely. Either that, or the debuginfo reader is somehow
724 broken. 5 million is of course arbitrary; but it's big enough
725 to be bigger than the size of any plausible piece of code that
726 would fall within a single procedure. But occasionally it does
727 happen (c.f. BZ #339542). */
729 VG_(message
)(Vg_DebugMsg
,
730 "warning: DiCfSI %#lx .. %#lx is huge; length = %u (%s)\n",
731 base
, base
+ len
- 1, len
, di
->soname
);
733 vg_assert(di
->fsm
.have_rx_map
&& di
->fsm
.have_rw_map
);
734 /* Find mapping where at least one end of the CFSI falls into. */
735 map
= ML_(find_rx_mapping
)(di
, base
, base
);
736 map2
= ML_(find_rx_mapping
)(di
, base
+ len
- 1,
740 else if (map2
== NULL
)
743 /* Rule out ones which are completely outside the r-x mapped area
744 (or which span across different areas).
745 See "Comment_Regarding_Text_Range_Checks" elsewhere in this file
746 for background and rationale. */
747 if (map
== NULL
|| map
!= map2
) {
748 static Int complaints
= 10;
749 if (VG_(clo_trace_cfi
) || complaints
> 0) {
751 if (VG_(clo_verbosity
) > 1) {
754 "warning: DiCfSI %#lx .. %#lx outside mapped rx segments (%s)\n",
760 if (VG_(clo_trace_cfi
))
761 ML_(ppDiCfSI
)(di
->cfsi_exprs
, base
, len
, cfsi_m
);
766 /* Now we know the range is at least partially inside the r-x
767 mapped area. That implies that at least one of the ends of the
768 range falls inside the area. If necessary, clip it so it is
769 completely within the area. If we don't do this,
770 check_CFSI_related_invariants() in debuginfo.c (invariant #2)
772 "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in
773 priv_storage.h for background. */
774 if (base
< map
->avma
) {
775 /* Lower end is outside the mapped area. Hence upper end must
777 if (0) VG_(printf
)("XXX truncate lower\n");
778 vg_assert(base
+ len
- 1 >= map
->avma
);
779 delta
= (SSizeT
)(map
->avma
- base
);
780 vg_assert(delta
> 0);
781 vg_assert(delta
< (SSizeT
)len
);
786 if (base
+ len
- 1 > map
->avma
+ map
->size
- 1) {
787 /* Upper end is outside the mapped area. Hence lower end must be
789 if (0) VG_(printf
)("XXX truncate upper\n");
790 vg_assert(base
<= map
->avma
+ map
->size
- 1);
791 delta
= (SSizeT
)( (base
+ len
- 1)
792 - (map
->avma
+ map
->size
- 1) );
793 vg_assert(delta
> 0);
794 vg_assert(delta
< (SSizeT
)len
);
800 /* Because: either cfsi was entirely inside the range, in which
801 case we asserted that len > 0 at the start, OR it fell partially
802 inside the range, in which case we reduced it by some size
803 (delta) which is < its original size. */
806 /* Similar logic applies for the next two assertions. */
807 vg_assert(base
>= map
->avma
);
808 vg_assert(base
+ len
- 1
809 <= map
->avma
+ map
->size
- 1);
811 if (di
->cfsi_used
== di
->cfsi_size
) {
812 new_sz
= 2 * di
->cfsi_size
;
813 if (new_sz
== 0) new_sz
= 20;
814 new_tab
= ML_(dinfo_zalloc
)( "di.storage.addDiCfSI.1",
815 new_sz
* sizeof(DiCfSI
) );
816 if (di
->cfsi_rd
!= NULL
) {
817 VG_(memcpy
)(new_tab
, di
->cfsi_rd
,
818 di
->cfsi_used
* sizeof(DiCfSI
));
819 ML_(dinfo_free
)(di
->cfsi_rd
);
821 di
->cfsi_rd
= new_tab
;
822 di
->cfsi_size
= new_sz
;
823 if (di
->cfsi_m_pool
== NULL
)
824 di
->cfsi_m_pool
= VG_(newDedupPA
)(1000 * sizeof(DiCfSI_m
),
825 vg_alignof(DiCfSI_m
),
827 "di.storage.DiCfSI_m_pool",
831 di
->cfsi_rd
[di
->cfsi_used
].base
= base
;
832 di
->cfsi_rd
[di
->cfsi_used
].len
= len
;
833 di
->cfsi_rd
[di
->cfsi_used
].cfsi_m_ix
834 = VG_(allocFixedEltDedupPA
)(di
->cfsi_m_pool
,
838 vg_assert(di
->cfsi_used
<= di
->cfsi_size
);
842 Int
ML_(CfiExpr_Undef
)( XArray
* dst
)
845 VG_(memset
)( &e
, 0, sizeof(e
) );
847 return (Int
)VG_(addToXA
)( dst
, &e
);
849 Int
ML_(CfiExpr_Deref
)( XArray
* dst
, Int ixAddr
)
852 VG_(memset
)( &e
, 0, sizeof(e
) );
854 e
.Cex
.Deref
.ixAddr
= ixAddr
;
855 return (Int
)VG_(addToXA
)( dst
, &e
);
857 Int
ML_(CfiExpr_Const
)( XArray
* dst
, UWord con
)
860 VG_(memset
)( &e
, 0, sizeof(e
) );
862 e
.Cex
.Const
.con
= con
;
863 return (Int
)VG_(addToXA
)( dst
, &e
);
865 Int
ML_(CfiExpr_Unop
)( XArray
* dst
, CfiUnop op
, Int ix
)
868 VG_(memset
)( &e
, 0, sizeof(e
) );
872 return (Int
)VG_(addToXA
)( dst
, &e
);
874 Int
ML_(CfiExpr_Binop
)( XArray
* dst
, CfiBinop op
, Int ixL
, Int ixR
)
877 VG_(memset
)( &e
, 0, sizeof(e
) );
880 e
.Cex
.Binop
.ixL
= ixL
;
881 e
.Cex
.Binop
.ixR
= ixR
;
882 return (Int
)VG_(addToXA
)( dst
, &e
);
884 Int
ML_(CfiExpr_CfiReg
)( XArray
* dst
, CfiReg reg
)
887 VG_(memset
)( &e
, 0, sizeof(e
) );
889 e
.Cex
.CfiReg
.reg
= reg
;
890 return (Int
)VG_(addToXA
)( dst
, &e
);
892 Int
ML_(CfiExpr_DwReg
)( XArray
* dst
, Int reg
)
895 VG_(memset
)( &e
, 0, sizeof(e
) );
897 e
.Cex
.DwReg
.reg
= reg
;
898 return (Int
)VG_(addToXA
)( dst
, &e
);
901 static void ppCfiUnop ( CfiUnop op
)
904 case Cunop_Abs
: VG_(printf
)("abs"); break;
905 case Cunop_Neg
: VG_(printf
)("-"); break;
906 case Cunop_Not
: VG_(printf
)("~"); break;
907 default: vg_assert(0);
911 static void ppCfiBinop ( CfiBinop op
)
914 case Cbinop_Add
: VG_(printf
)("+"); break;
915 case Cbinop_Sub
: VG_(printf
)("-"); break;
916 case Cbinop_And
: VG_(printf
)("&"); break;
917 case Cbinop_Mul
: VG_(printf
)("*"); break;
918 case Cbinop_Shl
: VG_(printf
)("<<"); break;
919 case Cbinop_Shr
: VG_(printf
)(">>"); break;
920 case Cbinop_Eq
: VG_(printf
)("=="); break;
921 case Cbinop_Ge
: VG_(printf
)(">="); break;
922 case Cbinop_Gt
: VG_(printf
)(">"); break;
923 case Cbinop_Le
: VG_(printf
)("<="); break;
924 case Cbinop_Lt
: VG_(printf
)("<"); break;
925 case Cbinop_Ne
: VG_(printf
)("!="); break;
926 default: vg_assert(0);
930 static void ppCfiReg ( CfiReg reg
)
933 case Creg_INVALID
: VG_(printf
)("Creg_INVALID"); break;
934 case Creg_IA_SP
: VG_(printf
)("xSP"); break;
935 case Creg_IA_BP
: VG_(printf
)("xBP"); break;
936 case Creg_IA_IP
: VG_(printf
)("xIP"); break;
937 case Creg_ARM_R13
: VG_(printf
)("R13"); break;
938 case Creg_ARM_R12
: VG_(printf
)("R12"); break;
939 case Creg_ARM_R15
: VG_(printf
)("R15"); break;
940 case Creg_ARM_R14
: VG_(printf
)("R14"); break;
941 case Creg_ARM_R7
: VG_(printf
)("R7"); break;
942 case Creg_ARM64_X30
: VG_(printf
)("X30"); break;
943 case Creg_MIPS_RA
: VG_(printf
)("RA"); break;
944 case Creg_S390_IA
: VG_(printf
)("IA"); break;
945 case Creg_S390_SP
: VG_(printf
)("SP"); break;
946 case Creg_S390_FP
: VG_(printf
)("FP"); break;
947 case Creg_S390_LR
: VG_(printf
)("LR"); break;
948 default: vg_assert(0);
952 void ML_(ppCfiExpr
)( const XArray
* src
, Int ix
)
954 /* VG_(indexXA) checks for invalid src/ix values, so we can
955 use it indiscriminately. */
956 const CfiExpr
* e
= VG_(indexXA
)( src
, ix
);
959 VG_(printf
)("Undef");
963 ML_(ppCfiExpr
)(src
, e
->Cex
.Deref
.ixAddr
);
967 VG_(printf
)("0x%lx", e
->Cex
.Const
.con
);
970 ppCfiUnop(e
->Cex
.Unop
.op
);
972 ML_(ppCfiExpr
)(src
, e
->Cex
.Unop
.ix
);
977 ML_(ppCfiExpr
)(src
, e
->Cex
.Binop
.ixL
);
979 ppCfiBinop(e
->Cex
.Binop
.op
);
981 ML_(ppCfiExpr
)(src
, e
->Cex
.Binop
.ixR
);
985 ppCfiReg(e
->Cex
.CfiReg
.reg
);
988 VG_(printf
)("dwr%d", e
->Cex
.DwReg
.reg
);
991 VG_(core_panic
)("ML_(ppCfiExpr)");
998 Word
ML_(cmp_for_DiAddrRange_range
) ( const void* keyV
,
999 const void* elemV
) {
1000 const Addr
* key
= (const Addr
*)keyV
;
1001 const DiAddrRange
* elem
= (const DiAddrRange
*)elemV
;
1003 VG_(printf
)("cmp_for_DiAddrRange_range: %#lx vs %#lx\n",
1005 if ((*key
) < elem
->aMin
) return -1;
1006 if ((*key
) > elem
->aMax
) return 1;
1011 void show_scope ( OSet
* /* of DiAddrRange */ scope
, const HChar
* who
)
1014 VG_(printf
)("Scope \"%s\" = {\n", who
);
1015 VG_(OSetGen_ResetIter
)( scope
);
1017 range
= VG_(OSetGen_Next
)( scope
);
1019 VG_(printf
)(" %#lx .. %#lx: %ld vars\n", range
->aMin
, range
->aMax
,
1020 range
->vars
? VG_(sizeXA
)(range
->vars
) : 0);
1025 /* Add the variable 'var' to 'scope' for the address range [aMin,aMax]
1026 (inclusive of aMin and aMax). Split existing ranges as required if
1027 aMin or aMax or both don't match existing range boundaries, and add
1028 'var' to all required ranges. Take great care to preserve the
1029 invariant that the ranges in 'scope' cover the entire address range
1030 exactly once, with no overlaps and no holes. */
1031 static void add_var_to_arange (
1032 /*MOD*/OSet
* /* of DiAddrRange */ scope
,
1038 DiAddrRange
*first
, *last
, *range
;
1039 /* These xx variables are for assertion checking only; they don't
1040 contribute anything to the actual work of this function. */
1041 DiAddrRange
*xxRangep
, *xxFirst
, *xxLast
;
1044 vg_assert(aMin
<= aMax
);
1046 if (0) VG_(printf
)("add_var_to_arange: %#lx .. %#lx\n", aMin
, aMax
);
1047 if (0) show_scope( scope
, "add_var_to_arange(1)" );
1049 /* See if the lower end of the range (aMin) falls exactly on an
1050 existing range boundary. If not, find the range it does fall
1051 into, and split it (copying the variables in the process), so
1052 that aMin does exactly fall on a range boundary. */
1053 first
= VG_(OSetGen_Lookup
)( scope
, &aMin
);
1054 /* It must be present, since the presented OSet must cover
1055 the entire address range. */
1057 vg_assert(first
->aMin
<= first
->aMax
);
1058 vg_assert(first
->aMin
<= aMin
&& aMin
<= first
->aMax
);
1060 /* Fast track common case, which is that the range specified for
1061 the variable exactly coincides with one already-existing
1063 if (first
->aMin
== aMin
&& first
->aMax
== aMax
) {
1064 vg_assert(first
->vars
);
1065 VG_(addToXA
)( first
->vars
, var
);
1069 /* We have to get into splitting ranges, which is complex
1071 if (first
->aMin
< aMin
) {
1073 /* Ok. We'll have to split 'first'. */
1074 /* truncate the upper end of 'first' */
1075 Addr tmp
= first
->aMax
;
1076 first
->aMax
= aMin
-1;
1077 vg_assert(first
->aMin
<= first
->aMax
);
1078 /* create a new range */
1079 nyu
= VG_(OSetGen_AllocNode
)( scope
, sizeof(DiAddrRange
) );
1082 vg_assert(nyu
->aMin
<= nyu
->aMax
);
1083 /* copy vars into it */
1084 vg_assert(first
->vars
);
1085 nyu
->vars
= VG_(cloneXA
)( "di.storage.avta.1", first
->vars
);
1086 VG_(OSetGen_Insert
)( scope
, nyu
);
1090 vg_assert(first
->aMin
== aMin
);
1092 /* Now do exactly the same for the upper end (aMax): if it doesn't
1093 fall on a boundary, cause it to do so by splitting the range it
1094 does currently fall into. */
1095 last
= VG_(OSetGen_Lookup
)( scope
, &aMax
);
1096 vg_assert(last
->aMin
<= last
->aMax
);
1097 vg_assert(last
->aMin
<= aMax
&& aMax
<= last
->aMax
);
1099 if (aMax
< last
->aMax
) {
1101 /* We have to split 'last'. */
1102 /* truncate the lower end of 'last' */
1103 Addr tmp
= last
->aMin
;
1104 last
->aMin
= aMax
+1;
1105 vg_assert(last
->aMin
<= last
->aMax
);
1106 /* create a new range */
1107 nyu
= VG_(OSetGen_AllocNode
)( scope
, sizeof(DiAddrRange
) );
1110 vg_assert(nyu
->aMin
<= nyu
->aMax
);
1111 /* copy vars into it */
1112 vg_assert(last
->vars
);
1113 nyu
->vars
= VG_(cloneXA
)( "di.storage.avta.2", last
->vars
);
1114 VG_(OSetGen_Insert
)( scope
, nyu
);
1118 vg_assert(aMax
== last
->aMax
);
1120 xxFirst
= (DiAddrRange
*)VG_(OSetGen_Lookup
)(scope
, &aMin
);
1121 xxLast
= (DiAddrRange
*)VG_(OSetGen_Lookup
)(scope
, &aMax
);
1124 vg_assert(xxFirst
->aMin
== aMin
);
1125 vg_assert(xxLast
->aMax
== aMax
);
1126 if (xxFirst
!= xxLast
)
1127 vg_assert(xxFirst
->aMax
< xxLast
->aMin
);
1129 /* Great. Now we merely need to iterate over the segments from
1130 'first' to 'last' inclusive, and add 'var' to the variable set
1133 static UWord ctr
= 0;
1135 VG_(printf
)("ctr = %lu\n", ctr
);
1136 if (ctr
>= 33263) show_scope( scope
, "add_var_to_arange(2)" );
1140 range
= xxRangep
= NULL
;
1141 VG_(OSetGen_ResetIterAt
)( scope
, &aMin
);
1144 range
= VG_(OSetGen_Next
)( scope
);
1146 if (range
->aMin
> aMax
) break;
1148 if (0) VG_(printf
)("have range %#lx %#lx\n",
1149 range
->aMin
, range
->aMax
);
1153 /* This is the first in the range */
1154 vg_assert(range
->aMin
== aMin
);
1156 vg_assert(xxRangep
->aMax
+ 1 == range
->aMin
);
1159 vg_assert(range
->vars
);
1160 VG_(addToXA
)( range
->vars
, var
);
1162 /* Done. We should have seen at least one range. */
1163 vg_assert(xxIters
>= 1);
1164 if (xxIters
== 1) vg_assert(xxFirst
== xxLast
);
1165 if (xxFirst
== xxLast
) vg_assert(xxIters
== 1);
1166 vg_assert(xxRangep
);
1167 vg_assert(xxRangep
->aMax
== aMax
);
1168 vg_assert(xxRangep
== xxLast
);
1172 /* Top-level place to call to add a variable description (as extracted
1173 from a DWARF3 .debug_info section. */
1174 void ML_(addVar
)( struct _DebugInfo
* di
,
1178 const HChar
* name
, /* in di's .strpool */
1179 UWord typeR
, /* a cuOff */
1182 UInt fndn_ix
, /* where decl'd - may be zero.
1183 index in in di's .fndnpool */
1184 Int lineNo
, /* where decl'd - may be zero */
1187 OSet
* /* of DiAddrRange */ scope
;
1192 const HChar
* badness
;
1194 vg_assert(di
&& di
->admin_tyents
);
1197 VG_(printf
)(" ML_(addVar): level %d %#lx-%#lx %s :: ",
1198 level
, aMin
, aMax
, name
);
1199 ML_(pp_TyEnt_C_ishly
)( di
->admin_tyents
, typeR
);
1200 VG_(printf
)("\n Var=");
1204 VG_(printf
)(" FrB=");
1208 VG_(printf
)(" FrB=none\n");
1213 vg_assert(level
>= 0);
1214 vg_assert(aMin
<= aMax
);
1218 ent
= ML_(TyEnts__index_by_cuOff
)( di
->admin_tyents
, NULL
, typeR
);
1220 vg_assert(ML_(TyEnt__is_type
)(ent
));
1222 /* "Comment_Regarding_Text_Range_Checks" (is referred to elsewhere)
1223 ----------------------------------------------------------------
1224 Ignore any variables whose aMin .. aMax (that is, range of text
1225 addresses for which they actually exist) falls outside the text
1226 segment. Is this indicative of a bug in the reader? Maybe.
1227 (LATER): instead of restricting strictly to the .text segment,
1228 be a bit more relaxed, and accept any variable whose text range
1229 falls inside the r-x mapped area. This is useful because .text
1230 is not always the only instruction-carrying segment: others are:
1231 .init .plt __libc_freeres_fn and .fini. This implicitly assumes
1232 that those extra sections have the same bias as .text, but that
1233 seems a reasonable assumption to me. */
1234 /* This is assured us by top level steering logic in debuginfo.c,
1235 and it is re-checked at the start of
1236 ML_(read_elf_debug_info). */
1237 vg_assert(di
->fsm
.have_rx_map
&& di
->fsm
.have_rw_map
);
1238 if (level
> 0 && ML_(find_rx_mapping
)(di
, aMin
, aMax
) == NULL
) {
1239 if (VG_(clo_verbosity
) >= 0) {
1240 VG_(message
)(Vg_DebugMsg
,
1241 "warning: addVar: in range %#lx .. %#lx outside "
1242 "all rx mapped areas (%s)\n",
1249 /* If the type's size is zero (which can mean unknown size), ignore
1250 it. We will never be able to actually relate a data address to
1251 a data object with zero size, so there's no point in storing
1252 info on it. On 32-bit platforms, also reject types whose size
1253 is 2^32 bytes or large. (It's amazing what junk shows up ..) */
1254 mul
= ML_(sizeOfType
)(di
->admin_tyents
, typeR
);
1258 badness
= "unknown size";
1259 else if (mul
.ul
== 0)
1260 badness
= "zero size ";
1261 else if (sizeof(void*) == 4 && mul
.ul
>= (1ULL<<32))
1262 badness
= "implausibly large";
1265 static Int complaints
= 10;
1266 if (VG_(clo_verbosity
) >= 2 && complaints
> 0) {
1267 VG_(message
)(Vg_DebugMsg
, "warning: addVar: %s (%s)\n",
1275 di
->varinfo
= VG_(newXA
)( ML_(dinfo_zalloc
),
1276 "di.storage.addVar.1",
1281 vg_assert(level
< 256); /* arbitrary; stay sane */
1282 /* Expand the top level array enough to map this level */
1283 while ( VG_(sizeXA
)(di
->varinfo
) <= level
) {
1285 scope
= VG_(OSetGen_Create
)( offsetof(DiAddrRange
,aMin
),
1286 ML_(cmp_for_DiAddrRange_range
),
1287 ML_(dinfo_zalloc
), "di.storage.addVar.2",
1289 if (0) VG_(printf
)("create: scope = %p, adding at %ld\n",
1290 scope
, VG_(sizeXA
)(di
->varinfo
));
1291 VG_(addToXA
)( di
->varinfo
, &scope
);
1292 /* Add a single range covering the entire address space. At
1293 level 0 we require this doesn't get split. At levels above 0
1294 we require that any additions to it cause it to get split.
1295 All of these invariants get checked both add_var_to_arange
1296 and after reading is complete, in canonicaliseVarInfo. */
1297 nyu
= VG_(OSetGen_AllocNode
)( scope
, sizeof(DiAddrRange
) );
1298 nyu
->aMin
= (Addr
)0;
1299 nyu
->aMax
= ~(Addr
)0;
1300 nyu
->vars
= VG_(newXA
)( ML_(dinfo_zalloc
), "di.storage.addVar.3",
1302 sizeof(DiVariable
) );
1303 VG_(OSetGen_Insert
)( scope
, nyu
);
1306 vg_assert( VG_(sizeXA
)(di
->varinfo
) > level
);
1307 scope
= *(OSet
**)VG_(indexXA
)( di
->varinfo
, level
);
1314 var
.fndn_ix
= fndn_ix
;
1315 var
.lineNo
= lineNo
;
1317 all
= aMin
== (Addr
)0 && aMax
== ~(Addr
)0;
1318 vg_assert(level
== 0 ? all
: !all
);
1320 add_var_to_arange( /*MOD*/scope
, aMin
, aMax
, &var
);
1324 /* This really just checks the constructed data structure, as there is
1325 no canonicalisation to do. */
1326 static void canonicaliseVarInfo ( struct _DebugInfo
* di
)
1328 Word i
, nInThisScope
;
1333 for (i
= 0; i
< VG_(sizeXA
)(di
->varinfo
); i
++) {
1335 DiAddrRange
*range
, *rangep
;
1336 OSet
* scope
= *(OSet
**)VG_(indexXA
)(di
->varinfo
, i
);
1337 if (!scope
) continue;
1339 /* Deal with the global-scope case. */
1342 vg_assert(VG_(OSetGen_Size
)( scope
) == 1);
1343 range
= VG_(OSetGen_Lookup
)( scope
, &zero
);
1345 vg_assert(range
->aMin
== (Addr
)0);
1346 vg_assert(range
->aMax
== ~(Addr
)0);
1350 /* All the rest of this is for the local-scope case. */
1351 /* iterate over all entries in 'scope' */
1354 VG_(OSetGen_ResetIter
)(scope
);
1356 range
= VG_(OSetGen_Next
)(scope
);
1358 /* We just saw the last one. There must have been at
1359 least one entry in the range. */
1361 vg_assert(rangep
->aMax
== ~(Addr
)0);
1365 vg_assert(range
->aMin
<= range
->aMax
);
1366 vg_assert(range
->vars
);
1369 /* This is the first entry in the range. */
1370 vg_assert(range
->aMin
== 0);
1372 vg_assert(rangep
->aMax
+ 1 == range
->aMin
);
1377 } /* iterating over ranges in a given scope */
1379 /* If there's only one entry in this (local) scope, it must
1380 cover the entire address space (obviously), but it must not
1381 contain any vars. */
1383 vg_assert(nInThisScope
> 0);
1384 if (nInThisScope
== 1) {
1386 vg_assert(VG_(OSetGen_Size
)( scope
) == 1);
1387 range
= VG_(OSetGen_Lookup
)( scope
, &zero
);
1389 vg_assert(range
->aMin
== (Addr
)0);
1390 vg_assert(range
->aMax
== ~(Addr
)0);
1391 vg_assert(range
->vars
);
1392 vg_assert(VG_(sizeXA
)(range
->vars
) == 0);
1395 } /* iterate over scopes */
1399 /*------------------------------------------------------------*/
1400 /*--- Canonicalisers ---*/
1401 /*------------------------------------------------------------*/
1403 /* Sort the symtab by starting address, and emit warnings if any
1404 symbols have overlapping address ranges. We use that old chestnut,
1405 shellsort. Mash the table around so as to establish the property
1406 that addresses are in order and the ranges to not overlap. This
1407 facilitates using binary search to map addresses to symbols when we
1408 come to query the table.
1410 static Int
compare_DiSym ( const void* va
, const void* vb
)
1412 const DiSym
* a
= va
;
1413 const DiSym
* b
= vb
;
1414 if (a
->avmas
.main
< b
->avmas
.main
) return -1;
1415 if (a
->avmas
.main
> b
->avmas
.main
) return 1;
1420 /* An address is associated with more than one name. Which do we
1421 prefer as the "display" name (that we show the user in stack
1424 - Prefer "PMPI_<foo>" over "MPI_<foo>".
1426 - Else, prefer a non-empty name over an empty one.
1428 - Else, prefer a non-whitespace name over an all-whitespace name.
1430 - Else, prefer the shorter symbol name. If the symbol contains a
1431 version symbol ('@' on Linux, other platforms may differ), which means it
1432 is versioned, then the length up to the version symbol is used for length
1433 comparison purposes (so "foo@GLIBC_2.4.2" is considered shorter than
1436 - Else, if two symbols have the same length, prefer a versioned symbol over
1437 a non-versioned symbol.
1439 - Else, use alphabetical ordering.
1441 - Otherwise, they must be the same; use the name with the lower address.
1443 Very occasionally this goes wrong (eg. 'memcmp' and 'bcmp' are
1444 aliases in glibc, we choose the 'bcmp' symbol because it's shorter,
1445 so we can misdescribe memcmp() as bcmp()). This is hard to avoid.
1446 It's mentioned in the FAQ file.
1448 Returned value is True if a_name is preferred, False if b_name is
1452 Bool
preferName ( const DebugInfo
* di
,
1453 const HChar
* a_name
, const HChar
* b_name
,
1454 Addr sym_avma
/*exposition only*/ )
1457 Word vlena
, vlenb
; /* length without version */
1458 const HChar
*vpa
, *vpb
;
1460 Bool preferA
= False
;
1461 Bool preferB
= False
;
1465 // vg_assert(a_name != b_name);
1466 // ???? now the pointers can be equal but is that
1467 // ???? not the indication of a latent bug ????
1469 vlena
= VG_(strlen
)(a_name
);
1470 vlenb
= VG_(strlen
)(b_name
);
1472 # if defined(VGO_linux) || defined(VGO_solaris)
1473 # define VERSION_CHAR '@'
1474 # elif defined(VGO_darwin)
1475 # define VERSION_CHAR '$'
1480 vpa
= VG_(strchr
)(a_name
, VERSION_CHAR
);
1481 vpb
= VG_(strchr
)(b_name
, VERSION_CHAR
);
1483 # undef VERSION_CHAR
1486 vlena
= vpa
- a_name
;
1488 vlenb
= vpb
- b_name
;
1490 /* MPI hack: prefer PMPI_Foo over MPI_Foo */
1491 if (0==VG_(strncmp
)(a_name
, "MPI_", 4)
1492 && 0==VG_(strncmp
)(b_name
, "PMPI_", 5)
1493 && 0==VG_(strcmp
)(a_name
, 1+b_name
)) {
1494 preferB
= True
; goto out
;
1496 if (0==VG_(strncmp
)(b_name
, "MPI_", 4)
1497 && 0==VG_(strncmp
)(a_name
, "PMPI_", 5)
1498 && 0==VG_(strcmp
)(b_name
, 1+a_name
)) {
1499 preferA
= True
; goto out
;
1502 /* Prefer non-empty name. */
1503 if (vlena
&& !vlenb
) {
1504 preferA
= True
; goto out
;
1506 if (vlenb
&& !vlena
) {
1507 preferB
= True
; goto out
;
1510 /* Prefer non-whitespace name. */
1517 if (!VG_(isspace
)(*s
++)) {
1524 if (!VG_(isspace
)(*s
++)) {
1530 if (!blankA
&& blankB
) {
1531 preferA
= True
; goto out
;
1533 if (!blankB
&& blankA
) {
1534 preferB
= True
; goto out
;
1538 /* Select the shortest unversioned name */
1539 if (vlena
< vlenb
) {
1540 preferA
= True
; goto out
;
1542 if (vlenb
< vlena
) {
1543 preferB
= True
; goto out
;
1546 /* Equal lengths; select the versioned name */
1548 preferA
= True
; goto out
;
1551 preferB
= True
; goto out
;
1554 /* Either both versioned or neither is versioned; select them
1556 cmp
= VG_(strcmp
)(a_name
, b_name
);
1558 preferA
= True
; goto out
;
1561 preferB
= True
; goto out
;
1564 /* If we get here, they are the same name. */
1566 /* In this case we could choose either (arbitrarily), but might as
1567 well choose the one with the lowest DiSym* address, so as to try
1568 and make the comparison mechanism more stable (a la sorting
1569 parlance). Also, skip the diagnostic printing in this case. */
1570 return a_name
<= b_name
? True
: False
;
1575 if (preferA
&& !preferB
) {
1576 TRACE_SYMTAB("sym at %#lx: prefer '%s' to '%s'\n",
1577 sym_avma
, a_name
, b_name
);
1580 if (preferB
&& !preferA
) {
1581 TRACE_SYMTAB("sym at %#lx: prefer '%s' to '%s'\n",
1582 sym_avma
, b_name
, a_name
);
1590 /* Add the names in FROM to the names in TO. */
1592 void add_DiSym_names_to_from ( const DebugInfo
* di
, DiSym
* to
,
1595 vg_assert(to
->pri_name
);
1596 vg_assert(from
->pri_name
);
1597 /* Figure out how many names there will be in the new combined
1598 secondary vector. */
1599 const HChar
** to_sec
= to
->sec_names
;
1600 const HChar
** from_sec
= from
->sec_names
;
1615 TRACE_SYMTAB("merge: -> %ld\n", n_new_sec
);
1616 /* Create the new sec and copy stuff into it, putting the new
1617 entries at the end. */
1618 const HChar
** new_sec
= ML_(dinfo_zalloc
)( "di.storage.aDntf.1",
1619 (n_new_sec
+1) * sizeof(HChar
*) );
1620 from_sec
= from
->sec_names
;
1621 to_sec
= to
->sec_names
;
1625 new_sec
[i
++] = *to_sec
;
1629 new_sec
[i
++] = from
->pri_name
;
1632 new_sec
[i
++] = *from_sec
;
1636 vg_assert(i
== n_new_sec
);
1637 vg_assert(new_sec
[i
] == NULL
);
1638 /* If we're replacing an existing secondary vector, free it. */
1639 if (to
->sec_names
) {
1640 ML_(dinfo_free
)(to
->sec_names
);
1642 to
->sec_names
= new_sec
;
1646 static void canonicaliseSymtab ( struct _DebugInfo
* di
)
1648 Word i
, j
, n_truncated
;
1649 Addr sta1
, sta2
, end1
, end2
, toc1
, toc2
;
1650 const HChar
*pri1
, *pri2
, **sec1
, **sec2
;
1651 Bool ist1
, ist2
, isf1
, isf2
, isg1
, isg2
;
1653 # define SWAP(ty,aa,bb) \
1654 do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0)
1656 if (di
->symtab_used
== 0)
1659 /* Check initial invariants */
1660 for (i
= 0; i
< di
->symtab_used
; i
++) {
1661 DiSym
* sym
= &di
->symtab
[i
];
1662 vg_assert(sym
->pri_name
);
1663 vg_assert(!sym
->sec_names
);
1666 /* Sort by address. */
1667 VG_(ssort
)(di
->symtab
, di
->symtab_used
,
1668 sizeof(*di
->symtab
), compare_DiSym
);
1672 /* BEGIN Detect and "fix" identical address ranges. */
1674 Word r
, w
, n_merged
;
1677 /* A pass merging entries together in the case where they agree
1678 on .isText -- that is, either: both are .isText or both are
1679 not .isText. They are merged into a single entry, but both
1680 sets of names are preserved, so we end up knowing all the
1681 names for that particular address range.*/
1682 for (r
= 1; r
< di
->symtab_used
; r
++) {
1684 if ( di
->symtab
[w
].avmas
.main
== di
->symtab
[r
].avmas
.main
1685 && di
->symtab
[w
].size
== di
->symtab
[r
].size
1686 && !!di
->symtab
[w
].isText
== !!di
->symtab
[r
].isText
) {
1687 /* merge the two into one */
1689 /* Add r names to w if r has secondary names
1690 or r and w primary names differ. */
1691 if (di
->symtab
[r
].sec_names
1692 || (0 != VG_(strcmp
)(di
->symtab
[r
].pri_name
,
1693 di
->symtab
[w
].pri_name
))) {
1694 add_DiSym_names_to_from(di
, &di
->symtab
[w
], &di
->symtab
[r
]);
1696 /* mark w as an IFunc if either w or r are */
1697 di
->symtab
[w
].isIFunc
= di
->symtab
[w
].isIFunc
|| di
->symtab
[r
].isIFunc
;
1698 /* likewise for global symbols */
1699 di
->symtab
[w
].isGlobal
= di
->symtab
[w
].isGlobal
|| di
->symtab
[r
].isGlobal
;
1700 /* and use ::pri_names to indicate this slot is no longer in use */
1701 di
->symtab
[r
].pri_name
= NULL
;
1702 if (di
->symtab
[r
].sec_names
) {
1703 ML_(dinfo_free
)(di
->symtab
[r
].sec_names
);
1704 di
->symtab
[r
].sec_names
= NULL
;
1706 /* Completely zap the entry -- paranoia to make it more
1707 likely we'll notice if we inadvertently use it
1709 VG_(memset
)(&di
->symtab
[r
], 0, sizeof(DiSym
));
1715 /* A second pass merging entries together where one .isText but
1716 the other isn't. In such cases, just ignore the non-.isText
1717 one (a heuristic hack.) */
1718 for (r
= 1; r
< di
->symtab_used
; r
++) {
1719 /* Either of the symbols might already have been zapped by
1720 the previous pass, so we first have to check that. */
1721 if (di
->symtab
[r
-1].pri_name
== NULL
) continue;
1722 if (di
->symtab
[r
-0].pri_name
== NULL
) continue;
1723 /* ok, they are both still valid. Identical address ranges? */
1724 if (di
->symtab
[r
-1].avmas
.main
!= di
->symtab
[r
-0].avmas
.main
) continue;
1725 if (di
->symtab
[r
-1].size
!= di
->symtab
[r
-0].size
) continue;
1726 /* Identical address ranges. They must disagree on .isText
1727 since if they agreed, the previous pass would have merged
1729 if (di
->symtab
[r
-1].isText
&& di
->symtab
[r
-0].isText
) vg_assert(0);
1730 if (!di
->symtab
[r
-1].isText
&& !di
->symtab
[r
-0].isText
) vg_assert(0);
1731 Word to_zap
= di
->symtab
[r
-1].isText
? (r
-0) : (r
-1);
1732 Word to_keep
= di
->symtab
[r
-1].isText
? (r
-1) : (r
-0);
1733 vg_assert(!di
->symtab
[to_zap
].isText
);
1734 vg_assert(di
->symtab
[to_keep
].isText
);
1735 /* Add to_zap's names to to_keep if to_zap has secondary names
1736 or to_zap's and to_keep's primary names differ. */
1737 if (di
->symtab
[to_zap
].sec_names
1738 || (0 != VG_(strcmp
)(di
->symtab
[to_zap
].pri_name
,
1739 di
->symtab
[to_keep
].pri_name
))) {
1740 add_DiSym_names_to_from(di
, &di
->symtab
[to_keep
],
1741 &di
->symtab
[to_zap
]);
1743 /* Mark to_zap as not-in use in the same way as in the
1745 di
->symtab
[to_zap
].pri_name
= NULL
;
1746 if (di
->symtab
[to_zap
].sec_names
) {
1747 ML_(dinfo_free
)(di
->symtab
[to_zap
].sec_names
);
1748 di
->symtab
[to_zap
].sec_names
= NULL
;
1750 VG_(memset
)(&di
->symtab
[to_zap
], 0, sizeof(DiSym
));
1754 TRACE_SYMTAB( "canonicaliseSymtab: %ld symbols merged\n", n_merged
);
1757 /* Now a pass to squeeze out any unused ones */
1759 for (r
= 0; r
< di
->symtab_used
; r
++) {
1761 if (di
->symtab
[r
].pri_name
== NULL
)
1764 di
->symtab
[w
] = di
->symtab
[r
];
1768 vg_assert(w
+ n_merged
== di
->symtab_used
);
1769 di
->symtab_used
= w
;
1771 /* END Detect and "fix" identical address ranges. */
1773 /* BEGIN Detect and "fix" overlapping address ranges. */
1776 for (i
= 0; i
< ((Word
)di
->symtab_used
) -1; i
++) {
1778 vg_assert(di
->symtab
[i
].avmas
.main
<= di
->symtab
[i
+1].avmas
.main
);
1780 /* Check for common (no overlap) case. */
1781 if (di
->symtab
[i
].avmas
.main
+ di
->symtab
[i
].size
1782 <= di
->symtab
[i
+1].avmas
.main
)
1785 /* There's an overlap. Truncate one or the other. */
1786 if (di
->trace_symtab
) {
1787 VG_(printf
)("overlapping address ranges in symbol table\n\t");
1788 ML_(ppSym
)( i
, &di
->symtab
[i
] );
1790 ML_(ppSym
)( i
+1, &di
->symtab
[i
+1] );
1794 /* Truncate one or the other. */
1795 sta1
= di
->symtab
[i
].avmas
.main
;
1796 end1
= sta1
+ di
->symtab
[i
].size
- 1;
1797 toc1
= GET_TOCPTR_AVMA(di
->symtab
[i
].avmas
);
1798 // aren't we missing local_ep here ????
1799 pri1
= di
->symtab
[i
].pri_name
;
1800 sec1
= di
->symtab
[i
].sec_names
;
1801 ist1
= di
->symtab
[i
].isText
;
1802 isf1
= di
->symtab
[i
].isIFunc
;
1803 isg1
= di
->symtab
[i
].isGlobal
;
1805 sta2
= di
->symtab
[i
+1].avmas
.main
;
1806 end2
= sta2
+ di
->symtab
[i
+1].size
- 1;
1807 toc2
= GET_TOCPTR_AVMA(di
->symtab
[i
+1].avmas
);
1808 // aren't we missing local_ep here ????
1809 pri2
= di
->symtab
[i
+1].pri_name
;
1810 sec2
= di
->symtab
[i
+1].sec_names
;
1811 ist2
= di
->symtab
[i
+1].isText
;
1812 isf2
= di
->symtab
[i
+1].isIFunc
;
1813 isg2
= di
->symtab
[i
+1].isGlobal
;
1818 vg_assert(sta1
== sta2
);
1821 SWAP(Addr
,sta1
,sta2
); SWAP(Addr
,end1
,end2
); SWAP(Addr
,toc1
,toc2
);
1822 SWAP(const HChar
*,pri1
,pri2
); SWAP(const HChar
**,sec1
,sec2
);
1823 SWAP(Bool
,ist1
,ist2
); SWAP(Bool
,isf1
,isf2
); SWAP(Bool
, isg1
, isg2
);
1828 /* end1 == end2. Identical addr ranges. We'll eventually wind
1829 up back at cleanup_more, which will take care of it. */
1832 di
->symtab
[i
].avmas
.main
= sta1
;
1833 di
->symtab
[i
].size
= end1
- sta1
+ 1;
1834 SET_TOCPTR_AVMA(di
->symtab
[i
].avmas
, toc1
);
1835 // missing local_ep ???
1836 di
->symtab
[i
].pri_name
= pri1
;
1837 di
->symtab
[i
].sec_names
= sec1
;
1838 di
->symtab
[i
].isText
= ist1
;
1839 di
->symtab
[i
].isIFunc
= isf1
;
1840 di
->symtab
[i
].isGlobal
= isg1
;
1842 di
->symtab
[i
+1].avmas
.main
= sta2
;
1843 di
->symtab
[i
+1].size
= end2
- sta2
+ 1;
1844 SET_TOCPTR_AVMA(di
->symtab
[i
+1].avmas
, toc2
);
1845 // missing local_ep ???
1846 di
->symtab
[i
+1].pri_name
= pri2
;
1847 di
->symtab
[i
+1].sec_names
= sec2
;
1848 di
->symtab
[i
+1].isText
= ist2
;
1849 di
->symtab
[i
+1].isIFunc
= isf2
;
1850 di
->symtab
[i
+1].isGlobal
= isg2
;
1852 vg_assert(sta1
<= sta2
);
1853 vg_assert(di
->symtab
[i
].size
> 0);
1854 vg_assert(di
->symtab
[i
+1].size
> 0);
1855 /* It may be that the i+1 entry now needs to be moved further
1856 along to maintain the address order requirement. */
1858 while (j
< ((Word
)di
->symtab_used
)-1
1859 && di
->symtab
[j
].avmas
.main
> di
->symtab
[j
+1].avmas
.main
) {
1860 SWAP(DiSym
,di
->symtab
[j
],di
->symtab
[j
+1]);
1865 /* END Detect and "fix" overlapping address ranges. */
1867 if (n_truncated
> 0) goto cleanup_more
;
1869 /* Ensure relevant postconditions hold. */
1870 for (i
= 0; i
< ((Word
)di
->symtab_used
)-1; i
++) {
1871 /* No zero-sized symbols. */
1872 vg_assert(di
->symtab
[i
].size
> 0);
1874 vg_assert(di
->symtab
[i
].avmas
.main
< di
->symtab
[i
+1].avmas
.main
);
1876 vg_assert(di
->symtab
[i
].avmas
.main
+ di
->symtab
[i
].size
- 1
1877 < di
->symtab
[i
+1].avmas
.main
);
1878 /* Names are sane(ish) */
1879 vg_assert(di
->symtab
[i
].pri_name
);
1880 if (di
->symtab
[i
].sec_names
) {
1881 vg_assert(di
->symtab
[i
].sec_names
[0]);
1885 /* For each symbol that has more than one name, use preferName to
1886 select the primary name. This is a complete kludge in that
1887 doing it properly requires making a total ordering on the
1888 candidate names, whilst what we have to work with is an ad-hoc
1889 binary relation (preferName) that certainly doesn't have the
1890 relevant transitivity etc properties that are needed to induce a
1891 legitimate total order. Doesn't matter though if it doesn't
1892 always work right since this is only used to generate names to
1894 for (i
= 0; i
< ((Word
)di
->symtab_used
)-1; i
++) {
1895 DiSym
* sym
= &di
->symtab
[i
];
1896 const HChar
** sec
= sym
->sec_names
;
1899 /* Slow but simple. Copy all the cands into a temp array,
1900 choose the primary name, and copy them all back again. */
1902 while (*sec
) { n_tmp
++; sec
++; }
1904 const HChar
** tmp
= ML_(dinfo_zalloc
)( "di.storage.cS.1",
1905 (n_tmp
+1) * sizeof(HChar
*) );
1906 tmp
[j
++] = sym
->pri_name
;
1907 sec
= sym
->sec_names
;
1908 while (*sec
) { tmp
[j
++] = *sec
; sec
++; }
1909 vg_assert(j
== n_tmp
);
1910 vg_assert(tmp
[n_tmp
] == NULL
); /* because of zalloc */
1911 /* Choose the most favoured. */
1913 for (j
= 1; j
< n_tmp
; j
++) {
1914 if (preferName(di
, tmp
[best
], tmp
[j
], di
->symtab
[i
].avmas
.main
)) {
1915 /* best is unchanged */
1920 vg_assert(best
>= 0 && best
< n_tmp
);
1922 sym
->pri_name
= tmp
[best
];
1923 const HChar
** cursor
= sym
->sec_names
;
1924 for (j
= 0; j
< n_tmp
; j
++) {
1930 vg_assert(*cursor
== NULL
);
1931 ML_(dinfo_free
)( tmp
);
1938 static DiLoc
* sorting_loctab
= NULL
;
1939 static Int
compare_DiLoc_via_ix ( const void* va
, const void* vb
)
1941 const DiLoc
* a
= &sorting_loctab
[*(const UInt
*)va
];
1942 const DiLoc
* b
= &sorting_loctab
[*(const UInt
*)vb
];
1943 if (a
->addr
< b
->addr
) return -1;
1944 if (a
->addr
> b
->addr
) return 1;
1947 static void sort_loctab_and_loctab_fndn_ix (struct _DebugInfo
* di
)
1949 /* We have to sort the array loctab by addr
1950 together with its "parallel" array loctab_fndn_ix.
1951 We first build sort_ix : an array of indexes in loctab,
1952 that we sort by loctab address. Then we can reorder both
1953 arrays according to sort_ix. */
1954 UInt
*sort_ix
= ML_(dinfo_zalloc
)("di.storage.six",
1955 di
->loctab_used
*sizeof(UInt
));
1958 for (i
= 0; i
< di
->loctab_used
; i
++) sort_ix
[i
] = i
;
1959 sorting_loctab
= di
->loctab
;
1960 VG_(ssort
)(sort_ix
, di
->loctab_used
,
1961 sizeof(*sort_ix
), compare_DiLoc_via_ix
);
1962 sorting_loctab
= NULL
;
1964 // Permute in place, using the sort_ix.
1965 for (i
=0; i
< di
->loctab_used
; i
++) {
1969 if (i
== sort_ix
[i
])
1970 continue; // i already at the good place
1972 tmp_diloc
= di
->loctab
[i
];
1973 tmp_fndn_ix
= ML_(fndn_ix
)(di
, i
);
1980 di
->loctab
[j
] = di
->loctab
[k
];
1981 set_fndn_ix (di
, j
, ML_(fndn_ix
)(di
, k
));
1984 di
->loctab
[j
] = tmp_diloc
;
1985 set_fndn_ix (di
, j
, tmp_fndn_ix
);
1987 ML_(dinfo_free
)(sort_ix
);
1990 /* Sort the location table by starting address. Mash the table around
1991 so as to establish the property that addresses are in order and the
1992 ranges do not overlap. This facilitates using binary search to map
1993 addresses to locations when we come to query the table.
1995 static void canonicaliseLoctab ( struct _DebugInfo
* di
)
1999 if (di
->loctab_used
== 0)
2002 /* sort loctab and loctab_fndn_ix by addr. */
2003 sort_loctab_and_loctab_fndn_ix (di
);
2005 for (i
= 0; i
< ((Word
)di
->loctab_used
)-1; i
++) {
2006 vg_assert(di
->loctab
[i
].size
< 10000);
2007 /* If two adjacent entries overlap, truncate the first. */
2008 if (di
->loctab
[i
].addr
+ di
->loctab
[i
].size
> di
->loctab
[i
+1].addr
) {
2009 /* Do this in signed int32 because the actual .size fields
2010 are only 12 bits. */
2011 Int new_size
= di
->loctab
[i
+1].addr
- di
->loctab
[i
].addr
;
2012 TRACE_LOCTAB_CANON ("Truncating",
2013 &(di
->loctab
[i
]), &(di
->loctab
[i
+1]));
2015 di
->loctab
[i
].size
= 0;
2017 if (new_size
> MAX_LOC_SIZE
) {
2018 di
->loctab
[i
].size
= MAX_LOC_SIZE
;
2020 di
->loctab
[i
].size
= (UShort
)new_size
;
2025 /* Zap any zero-sized entries resulting from the truncation
2028 for (i
= 0; i
< (Word
)di
->loctab_used
; i
++) {
2029 if (di
->loctab
[i
].size
> 0) {
2031 di
->loctab
[j
] = di
->loctab
[i
];
2032 set_fndn_ix(di
, j
, ML_(fndn_ix
)(di
, i
));
2037 di
->loctab_used
= j
;
2039 /* Ensure relevant postconditions hold. */
2040 for (i
= 0; i
< ((Word
)di
->loctab_used
)-1; i
++) {
2042 VG_(printf
)("%ld 0x%p lno:%d sz:%d fndn_ix:%u i+1 0x%p\n",
2044 (void*)di
->loctab
[i
].addr
,
2045 di
->loctab
[i
].lineno
,
2047 ML_(fndn_ix
)(di
, i
),
2048 (void*)di
->loctab
[i
+1].addr
);
2050 /* No zero-sized symbols. */
2051 vg_assert(di
->loctab
[i
].size
> 0);
2053 vg_assert(di
->loctab
[i
].addr
< di
->loctab
[i
+1].addr
);
2055 vg_assert(di
->loctab
[i
].addr
+ di
->loctab
[i
].size
- 1
2056 < di
->loctab
[i
+1].addr
);
2059 /* Free up unused space at the end of the table. */
2063 /* Sort the inlined call table by starting address. Mash the table around
2064 so as to establish the property that addresses are in order.
2065 This facilitates using binary search to map addresses to locations when
2066 we come to query the table.
2067 Note : ranges can overlap, multiple ranges can start at an address,
2068 multiple ranges can end at an address.
2070 static Int
compare_DiInlLoc ( const void* va
, const void* vb
)
2072 const DiInlLoc
* a
= va
;
2073 const DiInlLoc
* b
= vb
;
2074 if (a
->addr_lo
< b
->addr_lo
) return -1;
2075 if (a
->addr_lo
> b
->addr_lo
) return 1;
2079 static void canonicaliseInltab ( struct _DebugInfo
* di
)
2083 if (di
->inltab_used
== 0)
2086 /* Sort by start address. */
2087 VG_(ssort
)(di
->inltab
, di
->inltab_used
,
2088 sizeof(*di
->inltab
), compare_DiInlLoc
);
2090 /* Ensure relevant postconditions hold. */
2091 for (i
= 0; i
< ((Word
)di
->inltab_used
)-1; i
++) {
2092 /* No zero-sized inlined call. */
2093 vg_assert(di
->inltab
[i
].addr_lo
< di
->inltab
[i
].addr_hi
);
2094 /* In order, but we can have duplicates and overlapping ranges. */
2095 vg_assert(di
->inltab
[i
].addr_lo
<= di
->inltab
[i
+1].addr_lo
);
2098 /* Free up unused space at the end of the table. */
2103 /* Sort the call-frame-info cfsi_rd by starting address. Mash the table
2104 around so as to establish the property that addresses are in order
2105 and the ranges do not overlap. This facilitates using binary
2106 search to map addresses to locations when we come to query the
2109 Also, set cfisi_minaddr and cfisi_maxaddr to be the min and max of
2110 any of the address ranges contained in cfisi[0 .. cfisi_used-1], so
2111 as to facilitate rapidly skipping this SegInfo when looking for an
2112 address which falls outside that range.
2114 static Int
compare_DiCfSI ( const void* va
, const void* vb
)
2116 const DiCfSI
* a
= va
;
2117 const DiCfSI
* b
= vb
;
2118 if (a
->base
< b
->base
) return -1;
2119 if (a
->base
> b
->base
) return 1;
2123 static void get_cfsi_rd_stats ( const DebugInfo
* di
,
2124 UWord
*n_mergeables
, UWord
*n_holes
)
2131 vg_assert (di
->cfsi_used
== 0 || di
->cfsi_rd
);
2132 for (i
= 1; i
< (Word
)di
->cfsi_used
; i
++) {
2133 Addr here_min
= di
->cfsi_rd
[i
].base
;
2134 Addr prev_max
= di
->cfsi_rd
[i
-1].base
+ di
->cfsi_rd
[i
-1].len
- 1;
2135 Addr sep
= here_min
- prev_max
;
2138 if (sep
== 1 && di
->cfsi_rd
[i
-1].cfsi_m_ix
== di
->cfsi_rd
[i
].cfsi_m_ix
)
2143 void ML_(canonicaliseCFI
) ( struct _DebugInfo
* di
)
2146 const Addr minAvma
= 0;
2147 const Addr maxAvma
= ~minAvma
;
2149 /* Note: take care in here. di->cfsi can be NULL, in which
2150 case _used and _size fields will be zero. */
2151 if (di
->cfsi_rd
== NULL
) {
2152 vg_assert(di
->cfsi_used
== 0);
2153 vg_assert(di
->cfsi_size
== 0);
2154 vg_assert(di
->cfsi_m_pool
== NULL
);
2156 vg_assert(di
->cfsi_size
!= 0);
2157 vg_assert(di
->cfsi_m_pool
!= NULL
);
2160 /* Set cfsi_minavma and cfsi_maxavma to summarise the entire
2161 address range contained in cfsi_rd[0 .. cfsi_used-1]. */
2162 di
->cfsi_minavma
= maxAvma
;
2163 di
->cfsi_maxavma
= minAvma
;
2164 for (i
= 0; i
< (Word
)di
->cfsi_used
; i
++) {
2165 Addr here_min
= di
->cfsi_rd
[i
].base
;
2166 Addr here_max
= di
->cfsi_rd
[i
].base
+ di
->cfsi_rd
[i
].len
- 1;
2167 if (here_min
< di
->cfsi_minavma
)
2168 di
->cfsi_minavma
= here_min
;
2169 if (here_max
> di
->cfsi_maxavma
)
2170 di
->cfsi_maxavma
= here_max
;
2174 VG_(printf
)("canonicaliseCfiSI: %lu entries, %#lx .. %#lx\n",
2176 di
->cfsi_minavma
, di
->cfsi_maxavma
);
2178 /* Sort the cfsi_rd array by base address. */
2179 VG_(ssort
)(di
->cfsi_rd
, di
->cfsi_used
, sizeof(*di
->cfsi_rd
), compare_DiCfSI
);
2181 /* If two adjacent entries overlap, truncate the first. */
2182 for (i
= 0; i
< (Word
)di
->cfsi_used
-1; i
++) {
2183 if (di
->cfsi_rd
[i
].base
+ di
->cfsi_rd
[i
].len
> di
->cfsi_rd
[i
+1].base
) {
2184 Word new_len
= di
->cfsi_rd
[i
+1].base
- di
->cfsi_rd
[i
].base
;
2185 /* how could it be otherwise? The entries are sorted by the
2187 vg_assert(new_len
>= 0);
2188 vg_assert(new_len
<= di
->cfsi_rd
[i
].len
);
2189 di
->cfsi_rd
[i
].len
= new_len
;
2193 /* Zap any zero-sized entries resulting from the truncation
2196 for (i
= 0; i
< (Word
)di
->cfsi_used
; i
++) {
2197 if (di
->cfsi_rd
[i
].len
> 0) {
2199 di
->cfsi_rd
[j
] = di
->cfsi_rd
[i
];
2203 /* VG_(printf)("XXXXXXXXXXXXX %d %d\n", di->cfsi_used, j); */
2206 /* Ensure relevant postconditions hold. */
2207 for (i
= 0; i
< (Word
)di
->cfsi_used
; i
++) {
2208 /* No zero-length ranges. */
2209 vg_assert(di
->cfsi_rd
[i
].len
> 0);
2210 /* Makes sense w.r.t. summary address range */
2211 vg_assert(di
->cfsi_rd
[i
].base
>= di
->cfsi_minavma
);
2212 vg_assert(di
->cfsi_rd
[i
].base
+ di
->cfsi_rd
[i
].len
- 1
2213 <= di
->cfsi_maxavma
);
2215 if (i
< di
->cfsi_used
- 1) {
2217 if (!(di->cfsi[i].base < di->cfsi[i+1].base)) {
2218 VG_(printf)("\nOOO cfsis:\n");
2219 ML_(ppCfiSI)(&di->cfsi[i]);
2220 ML_(ppCfiSI)(&di->cfsi[i+1]);
2224 vg_assert(di
->cfsi_rd
[i
].base
< di
->cfsi_rd
[i
+1].base
);
2226 vg_assert(di
->cfsi_rd
[i
].base
+ di
->cfsi_rd
[i
].len
- 1
2227 < di
->cfsi_rd
[i
+1].base
);
2231 if (VG_(clo_stats
) && VG_(clo_verbosity
) >= 3) {
2232 UWord n_mergeables
, n_holes
;
2233 get_cfsi_rd_stats (di
, &n_mergeables
, &n_holes
);
2234 VG_(dmsg
)("CFSI total %lu mergeables %lu holes %lu uniq cfsi_m %u\n",
2235 di
->cfsi_used
, n_mergeables
, n_holes
,
2236 di
->cfsi_m_pool
? VG_(sizeDedupPA
) (di
->cfsi_m_pool
) : 0);
2240 void ML_(finish_CFSI_arrays
) ( struct _DebugInfo
* di
)
2242 UWord n_mergeables
, n_holes
;
2246 UWord f_mergeables
, f_holes
;
2247 UInt sz_cfsi_m_pool
;
2249 get_cfsi_rd_stats (di
, &n_mergeables
, &n_holes
);
2251 if (di
->cfsi_used
== 0) {
2252 vg_assert (di
->cfsi_rd
== NULL
);
2253 vg_assert (di
->cfsi_m_pool
== NULL
);
2254 vg_assert (n_mergeables
== 0);
2255 vg_assert (n_holes
== 0);
2259 vg_assert (di
->cfsi_used
> n_mergeables
);
2260 new_used
= di
->cfsi_used
- n_mergeables
+ n_holes
;
2262 sz_cfsi_m_pool
= VG_(sizeDedupPA
)(di
->cfsi_m_pool
);
2263 vg_assert (sz_cfsi_m_pool
> 0);
2264 if (sz_cfsi_m_pool
<= 255)
2265 di
->sizeof_cfsi_m_ix
= 1;
2266 else if (sz_cfsi_m_pool
<= 65535)
2267 di
->sizeof_cfsi_m_ix
= 2;
2269 di
->sizeof_cfsi_m_ix
= 4;
2271 di
->cfsi_base
= ML_(dinfo_zalloc
)( "di.storage.finCfSI.1",
2272 new_used
* sizeof(Addr
) );
2273 di
->cfsi_m_ix
= ML_(dinfo_zalloc
)( "di.storage.finCfSI.2",
2274 new_used
* sizeof(UChar
)*di
->sizeof_cfsi_m_ix
);
2279 for (i
= 0; i
< (Word
)di
->cfsi_used
; i
++) {
2281 Addr here_min
= di
->cfsi_rd
[i
].base
;
2282 Addr prev_max
= di
->cfsi_rd
[i
-1].base
+ di
->cfsi_rd
[i
-1].len
- 1;
2283 SizeT sep
= here_min
- prev_max
;
2285 // Skip a mergeable entry.
2287 if (di
->cfsi_rd
[i
-1].cfsi_m_ix
== di
->cfsi_rd
[i
].cfsi_m_ix
) {
2292 // Insert a hole if needed.
2295 di
->cfsi_base
[pos
] = prev_max
+ 1;
2296 switch (di
->sizeof_cfsi_m_ix
) {
2297 case 1: ((UChar
*) di
->cfsi_m_ix
)[pos
] = 0; break;
2298 case 2: ((UShort
*)di
->cfsi_m_ix
)[pos
] = 0; break;
2299 case 4: ((UInt
*) di
->cfsi_m_ix
)[pos
] = 0; break;
2300 default: vg_assert(0);
2306 // Insert the cfsi entry i.
2307 di
->cfsi_base
[pos
] = di
->cfsi_rd
[i
].base
;
2308 switch (di
->sizeof_cfsi_m_ix
) {
2309 case 1: ((UChar
*) di
->cfsi_m_ix
)[pos
] = di
->cfsi_rd
[i
].cfsi_m_ix
; break;
2310 case 2: ((UShort
*)di
->cfsi_m_ix
)[pos
] = di
->cfsi_rd
[i
].cfsi_m_ix
; break;
2311 case 4: ((UInt
*) di
->cfsi_m_ix
)[pos
] = di
->cfsi_rd
[i
].cfsi_m_ix
; break;
2312 default: vg_assert(0);
2317 vg_assert (f_mergeables
== n_mergeables
);
2318 vg_assert (f_holes
== n_holes
);
2319 vg_assert (pos
== new_used
);
2321 di
->cfsi_used
= new_used
;
2322 di
->cfsi_size
= new_used
;
2323 ML_(dinfo_free
) (di
->cfsi_rd
);
2328 /* Canonicalise the tables held by 'di', in preparation for use. Call
2329 this after finishing adding entries to these tables. */
2330 void ML_(canonicaliseTables
) ( struct _DebugInfo
* di
)
2332 canonicaliseSymtab ( di
);
2333 canonicaliseLoctab ( di
);
2334 canonicaliseInltab ( di
);
2335 ML_(canonicaliseCFI
) ( di
);
2336 if (di
->cfsi_m_pool
)
2337 VG_(freezeDedupPA
) (di
->cfsi_m_pool
, ML_(dinfo_shrink_block
));
2338 canonicaliseVarInfo ( di
);
2340 VG_(freezeDedupPA
) (di
->strpool
, ML_(dinfo_shrink_block
));
2342 VG_(freezeDedupPA
) (di
->fndnpool
, ML_(dinfo_shrink_block
));
2346 /*------------------------------------------------------------*/
2347 /*--- Searching the tables ---*/
2348 /*------------------------------------------------------------*/
2350 /* Find a symbol-table index containing the specified pointer, or -1
2351 if not found. Binary search. */
2353 Word
ML_(search_one_symtab
) ( const DebugInfo
* di
, Addr ptr
,
2356 Addr a_mid_lo
, a_mid_hi
;
2359 hi
= di
->symtab_used
-1;
2361 /* current unsearched space is from lo to hi, inclusive. */
2362 if (lo
> hi
) return -1; /* not found */
2363 mid
= (lo
+ hi
) / 2;
2364 a_mid_lo
= di
->symtab
[mid
].avmas
.main
;
2365 a_mid_hi
= ((Addr
)di
->symtab
[mid
].avmas
.main
) + di
->symtab
[mid
].size
- 1;
2367 if (ptr
< a_mid_lo
) { hi
= mid
-1; continue; }
2368 if (ptr
> a_mid_hi
) { lo
= mid
+1; continue; }
2369 vg_assert(ptr
>= a_mid_lo
&& ptr
<= a_mid_hi
);
2370 /* Found a symbol with the correct address range. But is it
2371 of the right kind (text vs data) ? */
2372 if ( findText
&& di
->symtab
[mid
].isText
) return mid
;
2373 if ( (!findText
) && (!di
->symtab
[mid
].isText
) ) return mid
;
2379 /* Find a location-table index containing the specified pointer, or -1
2380 if not found. Binary search. */
2382 Word
ML_(search_one_loctab
) ( const DebugInfo
* di
, Addr ptr
)
2384 Addr a_mid_lo
, a_mid_hi
;
2387 hi
= di
->loctab_used
-1;
2389 /* current unsearched space is from lo to hi, inclusive. */
2390 if (lo
> hi
) return -1; /* not found */
2391 mid
= (lo
+ hi
) / 2;
2392 a_mid_lo
= di
->loctab
[mid
].addr
;
2393 a_mid_hi
= ((Addr
)di
->loctab
[mid
].addr
) + di
->loctab
[mid
].size
- 1;
2395 if (ptr
< a_mid_lo
) { hi
= mid
-1; continue; }
2396 if (ptr
> a_mid_hi
) { lo
= mid
+1; continue; }
2397 vg_assert(ptr
>= a_mid_lo
&& ptr
<= a_mid_hi
);
2403 /* Find a CFI-table index containing the specified pointer, or -1
2404 if not found. Binary search. */
2406 Word
ML_(search_one_cfitab
) ( const DebugInfo
* di
, Addr ptr
)
2410 hi
= di
->cfsi_used
-1;
2413 /* Invariants : hi == cfsi_used-1 || ptr < cfsi_base[hi+1]
2414 lo == 0 || ptr > cfsi_base[lo-1]
2415 (the first part of the invariants is similar to considering
2416 that cfsi_base[-1] is 0 and cfsi_base[cfsi_used] is ~0) */
2417 mid
= (lo
+ hi
) / 2;
2418 if (ptr
< di
->cfsi_base
[mid
]) { hi
= mid
-1; continue; }
2419 if (ptr
> di
->cfsi_base
[mid
]) { lo
= mid
+1; continue; }
2424 for (mid
= 0; mid
<= di
->cfsi_used
-1; mid
++)
2425 if (ptr
< di
->cfsi_base
[mid
])
2427 vg_assert (lo
- 1 == mid
- 1);
2433 /* Find a FPO-table index containing the specified pointer, or -1
2434 if not found. Binary search. */
2436 Word
ML_(search_one_fpotab
) ( const DebugInfo
* di
, Addr ptr
)
2438 Addr
const addr
= ptr
- di
->fpo_base_avma
;
2439 Addr a_mid_lo
, a_mid_hi
;
2442 hi
= di
->fpo_size
-1;
2444 /* current unsearched space is from lo to hi, inclusive. */
2445 if (lo
> hi
) return -1; /* not found */
2446 mid
= (lo
+ hi
) / 2;
2447 a_mid_lo
= di
->fpo
[mid
].ulOffStart
;
2448 size
= di
->fpo
[mid
].cbProcSize
;
2449 a_mid_hi
= a_mid_lo
+ size
- 1;
2450 vg_assert(a_mid_hi
>= a_mid_lo
);
2451 if (addr
< a_mid_lo
) { hi
= mid
-1; continue; }
2452 if (addr
> a_mid_hi
) { lo
= mid
+1; continue; }
2453 vg_assert(addr
>= a_mid_lo
&& addr
<= a_mid_hi
);
2458 /*--------------------------------------------------------------------*/
2460 /*--------------------------------------------------------------------*/