philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 1 | |
| 2 | /*--------------------------------------------------------------------*/ |
| 3 | /*--- Obtaining information about an address. pub_tool_addrinfo.h ---*/ |
| 4 | /*--------------------------------------------------------------------*/ |
| 5 | |
| 6 | /* |
| 7 | This file is part of Valgrind, a dynamic binary instrumentation |
| 8 | framework. |
| 9 | |
Elliott Hughes | ed39800 | 2017-06-21 14:41:24 -0700 | [diff] [blame] | 10 | Copyright (C) 2000-2017 Julian Seward |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 11 | jseward@acm.org |
| 12 | |
| 13 | This program is free software; you can redistribute it and/or |
| 14 | modify it under the terms of the GNU General Public License as |
| 15 | published by the Free Software Foundation; either version 2 of the |
| 16 | License, or (at your option) any later version. |
| 17 | |
| 18 | This program is distributed in the hope that it will be useful, but |
| 19 | WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 21 | General Public License for more details. |
| 22 | |
| 23 | You should have received a copy of the GNU General Public License |
| 24 | along with this program; if not, write to the Free Software |
| 25 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 26 | 02111-1307, USA. |
| 27 | |
| 28 | The GNU General Public License is contained in the file COPYING. |
| 29 | */ |
| 30 | |
| 31 | #ifndef __PUB_TOOL_ADDRINFO_H |
| 32 | #define __PUB_TOOL_ADDRINFO_H |
| 33 | |
| 34 | #include "pub_tool_basics.h" // VG_ macro |
florian | 7463e49 | 2015-02-26 17:48:07 +0000 | [diff] [blame] | 35 | #include "pub_tool_aspacemgr.h" // SegKind |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 36 | |
| 37 | /*====================================================================*/ |
| 38 | /*=== Obtaining information about an address ===*/ |
| 39 | /*====================================================================*/ |
| 40 | |
| 41 | // Different kinds of blocks. |
| 42 | // Block_Mallocd is used by tools that maintain detailed information about |
| 43 | // Client allocated heap blocks. |
| 44 | // Block_Freed is used by tools such as memcheck that maintain a 'quarantine' |
| 45 | // list of blocks freed by the Client but not yet physically freed. |
| 46 | // Block_MempoolChunk and Block_UserG are used for mempool or user defined heap |
| 47 | // blocks. |
| 48 | // Block_ClientArenaMallocd and Block_ClientArenaFree are used when the tool |
| 49 | // replaces the malloc/free/... functions but does not maintain detailed |
| 50 | // information about Client allocated heap blocks. |
philippe | fed894d | 2014-05-14 21:53:48 +0000 | [diff] [blame] | 51 | // Block_ValgrindArenaMallocd and Block_ValgrindArenaFree are used for heap |
| 52 | // blocks of Valgrind internal heap. |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 53 | typedef enum { |
| 54 | Block_Mallocd = 111, |
| 55 | Block_Freed, |
| 56 | Block_MempoolChunk, |
| 57 | Block_UserG, |
| 58 | Block_ClientArenaMallocd, |
| 59 | Block_ClientArenaFree, |
| 60 | Block_ValgrindArenaMallocd, |
| 61 | Block_ValgrindArenaFree, |
| 62 | } BlockKind; |
| 63 | |
| 64 | /* ------------------ Addresses -------------------- */ |
| 65 | |
| 66 | /* The classification of a faulting address. */ |
| 67 | typedef |
| 68 | enum { |
| 69 | Addr_Undescribed, // as-yet unclassified |
| 70 | Addr_Unknown, // classification yielded nothing useful |
| 71 | Addr_Block, // in malloc'd/free'd block |
| 72 | Addr_Stack, // on a thread's stack |
| 73 | Addr_DataSym, // in a global data sym |
| 74 | Addr_Variable, // variable described by the debug info |
philippe | f7ec77f | 2014-11-24 17:46:41 +0000 | [diff] [blame] | 75 | Addr_SectKind, // Section from a mmap-ed object file |
philippe | d0da968 | 2014-12-28 17:30:22 +0000 | [diff] [blame] | 76 | Addr_BrkSegment, // address in brk data segment |
philippe | f7ec77f | 2014-11-24 17:46:41 +0000 | [diff] [blame] | 77 | Addr_SegmentKind // Client segment (mapped memory) |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 78 | } |
| 79 | AddrTag; |
| 80 | |
philippe | 7e3b3f2 | 2014-08-31 22:27:19 +0000 | [diff] [blame] | 81 | /* For an address in a stack, gives the address position in this stack. */ |
| 82 | typedef |
| 83 | enum { |
| 84 | StackPos_stacked, // Addressable and 'active' stack zone. |
| 85 | StackPos_below_stack_ptr, // Below stack ptr |
| 86 | StackPos_guard_page // In the guard page |
| 87 | } |
| 88 | StackPos; |
| 89 | |
| 90 | |
philippe | 0c9ac8d | 2014-07-18 00:03:58 +0000 | [diff] [blame] | 91 | /* Note about ThreadInfo tid and tnr in various parts of _Addrinfo: |
| 92 | A tid is an index in the VG_(threads)[] array. The entries |
| 93 | in VG_(threads) array are re-used, so the tid in an 'old' _Addrinfo |
| 94 | might be misleading: if the thread that was using tid has been terminated |
| 95 | and the tid was re-used by another thread, the tid will very probably |
| 96 | be wrongly interpreted by the user. |
| 97 | So, such an _Addrinfo should be printed just after it has been produced, |
| 98 | before the tid could possibly be re-used by another thread. |
| 99 | |
| 100 | A tool such as helgrind is uniquely/unambiguously identifying each thread |
| 101 | by a number. If the tool sets tnr between the call to |
| 102 | VG_(describe_addr) and the call to VG_(pp_addrinfo), then VG_(pp_addrinfo) |
| 103 | will by preference print tnr instead of tid. |
| 104 | Visually, a tid will be printed as thread %d |
| 105 | while a tnr will be printed as thread #%d |
| 106 | */ |
| 107 | |
| 108 | typedef |
| 109 | struct _ThreadInfo { |
| 110 | ThreadId tid; // 0 means thread not known. |
| 111 | UInt tnr; // 0 means no tool specific thread nr, or not known. |
| 112 | } ThreadInfo; |
| 113 | |
| 114 | /* Zeroes/clear all the fields of *tinfo. */ |
| 115 | extern void VG_(initThreadInfo) (ThreadInfo *tinfo); |
| 116 | |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 117 | typedef |
| 118 | struct _AddrInfo |
| 119 | AddrInfo; |
philippe | 0c9ac8d | 2014-07-18 00:03:58 +0000 | [diff] [blame] | 120 | |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 121 | struct _AddrInfo { |
| 122 | AddrTag tag; |
| 123 | union { |
| 124 | // As-yet unclassified. |
| 125 | struct { } Undescribed; |
| 126 | |
philippe | 0c9ac8d | 2014-07-18 00:03:58 +0000 | [diff] [blame] | 127 | // On a stack. tinfo indicates which thread's stack? |
philippe | 18d6f4e | 2014-05-22 23:48:24 +0000 | [diff] [blame] | 128 | // IP is the address of an instruction of the function where the |
| 129 | // stack address was. 0 if not found. |
| 130 | // frameNo is the frame nr of the call where the stack address was. |
| 131 | // -1 if not found. |
philippe | 7e3b3f2 | 2014-08-31 22:27:19 +0000 | [diff] [blame] | 132 | // stackPos describes the address 'position' in the stack. |
| 133 | // If stackPos is StackPos_below_stack_ptr or StackPos_guard_page, |
| 134 | // spoffset gives the offset from the thread stack pointer. |
| 135 | // (spoffset will be negative, as stacks are assumed growing down). |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 136 | struct { |
philippe | 0c9ac8d | 2014-07-18 00:03:58 +0000 | [diff] [blame] | 137 | ThreadInfo tinfo; |
philippe | 18d6f4e | 2014-05-22 23:48:24 +0000 | [diff] [blame] | 138 | Addr IP; |
| 139 | Int frameNo; |
philippe | 7e3b3f2 | 2014-08-31 22:27:19 +0000 | [diff] [blame] | 140 | StackPos stackPos; |
| 141 | PtrdiffT spoffset; |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 142 | } Stack; |
| 143 | |
philippe | fed894d | 2014-05-14 21:53:48 +0000 | [diff] [blame] | 144 | // This covers heap blocks (normal and from mempools), user-defined |
| 145 | // blocks and Arena blocks. |
philippe | 0c9ac8d | 2014-07-18 00:03:58 +0000 | [diff] [blame] | 146 | // alloc_tinfo identifies the thread that has allocated the block. |
| 147 | // This is used by tools such as helgrind that maintain |
Elliott Hughes | ed39800 | 2017-06-21 14:41:24 -0700 | [diff] [blame] | 148 | // more detailed information about client blocks. |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 149 | struct { |
| 150 | BlockKind block_kind; |
philippe | fed894d | 2014-05-14 21:53:48 +0000 | [diff] [blame] | 151 | const HChar* block_desc; // "block","mempool","user-defined",arena |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 152 | SizeT block_szB; |
| 153 | PtrdiffT rwoffset; |
| 154 | ExeContext* allocated_at; // might be null_ExeContext. |
philippe | 0c9ac8d | 2014-07-18 00:03:58 +0000 | [diff] [blame] | 155 | ThreadInfo alloc_tinfo; // which thread did alloc this block. |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 156 | ExeContext* freed_at; // might be null_ExeContext. |
| 157 | } Block; |
| 158 | |
florian | 46cc045 | 2014-10-25 19:20:38 +0000 | [diff] [blame] | 159 | // In a global .data symbol. This holds |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 160 | // the variable's name (zero terminated), plus a (memory) offset. |
| 161 | struct { |
florian | 46cc045 | 2014-10-25 19:20:38 +0000 | [diff] [blame] | 162 | HChar *name; |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 163 | PtrdiffT offset; |
| 164 | } DataSym; |
| 165 | |
| 166 | // Is described by Dwarf debug info. XArray*s of HChar. |
| 167 | struct { |
| 168 | XArray* /* of HChar */ descr1; |
| 169 | XArray* /* of HChar */ descr2; |
| 170 | } Variable; |
| 171 | |
| 172 | // Could only narrow it down to be the PLT/GOT/etc of a given |
| 173 | // object. Better than nothing, perhaps. |
| 174 | struct { |
florian | e08950b | 2014-11-13 21:41:28 +0000 | [diff] [blame] | 175 | HChar *objname; |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 176 | VgSectKind kind; |
| 177 | } SectKind; |
| 178 | |
philippe | d0da968 | 2014-12-28 17:30:22 +0000 | [diff] [blame] | 179 | // Described address is or was in the brk data segment. |
| 180 | // brk_limit is the limit that was in force |
| 181 | // at the time address was described. |
| 182 | // If address is >= brk_limit, it means address is in a zone |
| 183 | // of the data segment that was shrinked. |
| 184 | struct { |
| 185 | Addr brk_limit; // limit in force when address was described. |
| 186 | } BrkSegment; |
| 187 | |
philippe | f7ec77f | 2014-11-24 17:46:41 +0000 | [diff] [blame] | 188 | struct { |
| 189 | SegKind segkind; // SkAnonC, SkFileC or SkShmC. |
| 190 | HChar *filename; // NULL if segkind != SkFileC |
| 191 | Bool hasR; |
| 192 | Bool hasW; |
| 193 | Bool hasX; |
| 194 | } SegmentKind; |
| 195 | |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 196 | // Classification yielded nothing useful. |
| 197 | struct { } Unknown; |
| 198 | |
| 199 | } Addr; |
| 200 | }; |
| 201 | |
| 202 | |
| 203 | /* Describe an address as best you can, putting the result in ai. |
| 204 | On entry, ai->tag must be equal to Addr_Undescribed. |
| 205 | This might allocate some memory, that can be cleared with |
| 206 | VG_(clear_addrinfo). */ |
| 207 | extern void VG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai ); |
| 208 | |
| 209 | extern void VG_(clear_addrinfo) ( AddrInfo* ai); |
| 210 | |
philippe | 0af05d4 | 2014-09-19 18:58:18 +0000 | [diff] [blame] | 211 | /* Prints the AddrInfo ai describing a. |
| 212 | Note that an ai with tag Addr_Undescribed will cause an assert.*/ |
florian | 518850b | 2014-10-22 22:25:30 +0000 | [diff] [blame] | 213 | extern void VG_(pp_addrinfo) ( Addr a, const AddrInfo* ai ); |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 214 | |
| 215 | /* Same as VG_(pp_addrinfo) but provides some memcheck specific behaviour: |
| 216 | * maybe_gcc indicates Addr a was just below the stack ptr when the error |
| 217 | with a was encountered. |
| 218 | * the message for Unknown tag is slightly different, as memcheck |
| 219 | has a recently freed list. */ |
florian | 518850b | 2014-10-22 22:25:30 +0000 | [diff] [blame] | 220 | extern void VG_(pp_addrinfo_mc) ( Addr a, const AddrInfo* ai, Bool maybe_gcc ); |
philippe | 07c0852 | 2014-05-14 20:39:27 +0000 | [diff] [blame] | 221 | |
| 222 | #endif // __PUB_TOOL_ADDRINFO_H |
| 223 | |
| 224 | /*--------------------------------------------------------------------*/ |
| 225 | /*--- end ---*/ |
| 226 | /*--------------------------------------------------------------------*/ |