Ulrich Drepper | b08d5a8 | 2005-07-26 05:00:05 +0000 | [diff] [blame] | 1 | /* Interfaces for libdwfl. |
| 2 | Copyright (C) 2005 Red Hat, Inc. |
| 3 | |
| 4 | This program is Open Source software; you can redistribute it and/or |
| 5 | modify it under the terms of the Open Software License version 1.0 as |
| 6 | published by the Open Source Initiative. |
| 7 | |
| 8 | You should have received a copy of the Open Software License along |
| 9 | with this program; if not, you may obtain a copy of the Open Software |
| 10 | License version 1.0 from http://www.opensource.org/licenses/osl.php or |
| 11 | by writing the Open Source Initiative c/o Lawrence Rosen, Esq., |
| 12 | 3001 King Ranch Road, Ukiah, CA 95482. */ |
| 13 | |
| 14 | #ifndef _LIBDWFL_H |
| 15 | #define _LIBDWFL_H 1 |
| 16 | |
Roland McGrath | d89bbe4 | 2005-07-28 07:08:01 +0000 | [diff] [blame^] | 17 | #include "libdw.h" |
Ulrich Drepper | b08d5a8 | 2005-07-26 05:00:05 +0000 | [diff] [blame] | 18 | |
| 19 | /* Handle for a session using the library. */ |
| 20 | typedef struct Dwfl Dwfl; |
| 21 | |
| 22 | /* Handle for a module. */ |
| 23 | typedef struct Dwfl_Module Dwfl_Module; |
| 24 | |
| 25 | /* Handle describing a line record. */ |
| 26 | typedef struct Dwfl_Line Dwfl_Line; |
| 27 | |
| 28 | /* Callbacks. */ |
| 29 | typedef struct |
| 30 | { |
| 31 | int (*find_elf) (Dwfl_Module *mod, void **userdata, |
| 32 | const char *modname, Dwarf_Addr base, |
| 33 | char **file_name, Elf **elfp); |
| 34 | |
| 35 | int (*find_debuginfo) (Dwfl_Module *mod, void **userdata, |
| 36 | const char *modname, Dwarf_Addr base, |
| 37 | const char *file_name, |
| 38 | const char *debuglink_file, GElf_Word debuglink_crc, |
| 39 | char **debuginfo_file_name); |
| 40 | |
| 41 | /* Fill *ADDR with the loaded address of the |
| 42 | section called SECNAME in the given module. */ |
| 43 | int (*section_address) (Dwfl_Module *mod, void **userdata, |
| 44 | const char *modname, Dwarf_Addr base, |
| 45 | const char *secname, Dwarf_Addr *addr); |
| 46 | |
| 47 | char **debuginfo_path; /* See dwfl_standard_find_debuginfo. */ |
| 48 | } Dwfl_Callbacks; |
| 49 | |
| 50 | |
| 51 | /* Start a new session with the library. */ |
| 52 | Dwfl *dwfl_begin (const Dwfl_Callbacks *callbacks); |
| 53 | |
| 54 | /* End a session. */ |
| 55 | void dwfl_end (Dwfl *); |
| 56 | |
| 57 | /* Return error code of last failing function call. This value is kept |
| 58 | separately for each thread. */ |
| 59 | extern int dwfl_errno (void); |
| 60 | |
| 61 | /* Return error string for ERROR. If ERROR is zero, return error string |
| 62 | for most recent error or NULL if none occurred. If ERROR is -1 the |
| 63 | behaviour is similar to the last case except that not NULL but a legal |
| 64 | string is returned. */ |
| 65 | extern const char *dwfl_errmsg (int err); |
| 66 | |
| 67 | |
| 68 | /* Start reporting the current set of modules to the library. No calls but |
| 69 | dwfl_report_module can be made on DWFL until dwfl_report_end is called. */ |
| 70 | extern void dwfl_report_begin (Dwfl *dwfl); |
| 71 | |
| 72 | /* Report that a module called NAME spans addresses [START, END). |
| 73 | Returns the module handle, either existing or newly allocated, |
| 74 | or returns a null pointer for an allocation error. */ |
| 75 | extern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name, |
| 76 | Dwarf_Addr start, Dwarf_Addr end); |
| 77 | |
| 78 | /* Report a module with start and end addresses computed from the ELF |
| 79 | program headers in the given file, plus BASE. FD may be -1 to open |
| 80 | FILE_NAME. On success, FD is consumed by the library, and the |
| 81 | `find_elf' callback will not be used for this module. */ |
| 82 | extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name, |
| 83 | const char *file_name, int fd, |
| 84 | GElf_Addr base); |
| 85 | |
| 86 | /* Finish reporting the current set of modules to the library. |
| 87 | If REMOVED is not null, it's called for each module that |
| 88 | existed before but was not included in the current report. |
| 89 | Returns a nonzero return value from the callback. |
| 90 | The callback may call dwfl_report_module; doing so with the |
| 91 | details of the module being removed prevents its removal. |
| 92 | DWFL cannot be used until this function has returned zero. */ |
| 93 | extern int dwfl_report_end (Dwfl *dwfl, |
| 94 | int (*removed) (Dwfl_Module *, void *, |
| 95 | const char *, Dwarf_Addr, |
| 96 | void *arg), |
| 97 | void *arg); |
| 98 | |
| 99 | /* Return the name of the module, and for each non-null argument store |
| 100 | interesting details: *USERDATA is a location for storing your own |
| 101 | pointer, **USERDATA is initially null; *START and *END give the address |
| 102 | range covered by the module; *DWBIAS is the address bias for debugging |
| 103 | information, and *SYMBIAS for symbol table entries (either is -1 if not |
| 104 | yet accessed); *MAINFILE is the name of the ELF file, and *DEBUGFILE the |
| 105 | name of the debuginfo file (might be equal to *MAINFILE; either is null |
| 106 | if not yet accessed). */ |
| 107 | extern const char *dwfl_module_info (Dwfl_Module *mod, void ***userdata, |
| 108 | Dwarf_Addr *start, Dwarf_Addr *end, |
| 109 | Dwarf_Addr *dwbias, Dwarf_Addr *symbias, |
| 110 | const char **mainfile, |
| 111 | const char **debugfile); |
| 112 | |
| 113 | /* Iterate through the modules, starting the walk with OFFSET == 0. |
| 114 | Calls *CALLBACK for each module as long as it returns DWARF_CB_OK. |
| 115 | When *CALLBACK returns another value, the walk stops and the |
| 116 | return value can be passed as OFFSET to resume it. Returns 0 when |
| 117 | there are no more modules, or -1 for errors. */ |
| 118 | extern ptrdiff_t dwfl_getmodules (Dwfl *dwfl, |
| 119 | int (*callback) (Dwfl_Module *, void **, |
| 120 | const char *, Dwarf_Addr, |
| 121 | void *arg), |
| 122 | void *arg, |
| 123 | ptrdiff_t offset); |
| 124 | |
| 125 | |
| 126 | /*** Standard callbacks ***/ |
| 127 | |
| 128 | /* Standard find_debuginfo callback function. |
| 129 | This is controlled by a string specifying directories to look in. |
| 130 | If `debuginfo_path' is set in the Dwfl_Callbacks structure |
| 131 | and the char * it points to is not null, that supplies the string. |
| 132 | Otherwise a default path is used. |
| 133 | |
| 134 | If the first character of the string is + or - that says to check or to |
| 135 | ignore (respectively) the CRC32 checksum from the .gnu_debuglink |
| 136 | section. The default is to check it. The remainder of the string is |
| 137 | composed of elements separated by colons. Each element can start with + |
| 138 | or - to override the global checksum behavior. If the remainder of the |
| 139 | element is empty, the directory containing the main file is tried; if |
| 140 | it's an absolute path name, the absolute directory path containing the |
| 141 | main file is taken as a subdirectory of this path; a relative path name |
| 142 | is taken as a subdirectory of the directory containing the main file. |
| 143 | Hence for /bin/ls, string ":.debug:/usr/lib/debug" says to look in /bin, |
| 144 | then /bin/.debug, then /usr/lib/debug/bin, for the file name in the |
| 145 | .gnu_debuglink section (or "ls.debug" if none was found). */ |
| 146 | |
| 147 | extern int dwfl_standard_find_debuginfo (Dwfl_Module *, void **, |
| 148 | const char *, Dwarf_Addr, |
| 149 | const char *, const char *, |
| 150 | GElf_Word, char **); |
| 151 | |
| 152 | |
| 153 | /* Callbacks for working with kernel modules in the running Linux kernel. */ |
| 154 | extern int dwfl_linux_kernel_find_elf (Dwfl_Module *, void **, |
| 155 | const char *, Dwarf_Addr, |
| 156 | char **, Elf **); |
| 157 | extern int dwfl_linux_kernel_module_section_address (Dwfl_Module *, void **, |
| 158 | const char *, Dwarf_Addr, |
| 159 | const char *, |
| 160 | Dwarf_Addr *addr); |
| 161 | |
| 162 | /* Call dwfl_report_elf for the running Linux kernel. |
| 163 | Returns zero on success, -1 if dwfl_report_module failed, |
| 164 | or an errno code if opening the kernel binary failed. */ |
| 165 | extern int dwfl_linux_kernel_report_kernel (Dwfl *dwfl); |
| 166 | |
| 167 | /* Call dwfl_report_module for each kernel module in the running Linux kernel. |
| 168 | Returns zero on success, -1 if dwfl_report_module failed, |
| 169 | or an errno code if reading the list of modules failed. */ |
| 170 | extern int dwfl_linux_kernel_report_modules (Dwfl *dwfl); |
| 171 | |
| 172 | |
| 173 | /* Call dwfl_report_module for each file mapped into the address space of PID. |
| 174 | Returns zero on success, -1 if dwfl_report_module failed, |
| 175 | or an errno code if opening the kernel binary failed. */ |
| 176 | int dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid); |
| 177 | |
| 178 | /* Trivial find_elf callback for use with dwfl_linux_proc_report. |
| 179 | This uses the module name as a file name directly and tries to open it |
| 180 | if it begin with a slash, or handles the magic string "[vdso]". */ |
| 181 | int dwfl_linux_proc_find_elf (Dwfl_Module *mod, void **userdata, |
| 182 | const char *module_name, Dwarf_Addr base, |
| 183 | char **file_name, Elf **); |
| 184 | |
| 185 | /* Standard argument parsing for using a standard callback set. */ |
| 186 | struct argp; |
| 187 | extern const struct argp *dwfl_standard_argp (void) __attribute__ ((const)); |
| 188 | |
| 189 | |
| 190 | /*** Dwarf access functions ***/ |
| 191 | |
| 192 | /* Find the module containing the given address. */ |
| 193 | extern Dwfl_Module *dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address); |
| 194 | |
| 195 | /* Fetch the module main ELF file (where the allocated sections |
| 196 | are found) for use with libelf. If successful, fills in *BIAS |
| 197 | with the difference between addresses within the loaded module |
| 198 | and those in symbol tables or Dwarf information referring to it. */ |
| 199 | extern Elf *dwfl_module_getelf (Dwfl_Module *, GElf_Addr *bias); |
| 200 | |
| 201 | /* Fetch the module's debug information for use with libdw. |
| 202 | If successful, fills in *BIAS with the difference between |
| 203 | addresses within the loaded module and those to use with libdw. */ |
| 204 | extern Dwarf *dwfl_module_getdwarf (Dwfl_Module *, Dwarf_Addr *bias) |
| 205 | __nonnull_attribute__ (2); |
| 206 | |
| 207 | /* Get the libdw handle for each module. */ |
| 208 | extern ptrdiff_t dwfl_getdwarf (Dwfl *, |
| 209 | int (*callback) (Dwfl_Module *, void **, |
| 210 | const char *, Dwarf_Addr, |
| 211 | Dwarf *, Dwarf_Addr, void *), |
| 212 | void *arg, ptrdiff_t offset); |
| 213 | |
| 214 | /* Look up the module containing ADDR and return its debugging information, |
| 215 | loading it if necessary. */ |
| 216 | extern Dwarf *dwfl_addrdwarf (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias) |
| 217 | __nonnull_attribute__ (3); |
| 218 | |
| 219 | |
| 220 | /* Find the CU containing ADDR and return its DIE. */ |
| 221 | extern Dwarf_Die *dwfl_addrdie (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias) |
| 222 | __nonnull_attribute__ (3); |
| 223 | extern Dwarf_Die *dwfl_module_addrdie (Dwfl_Module *mod, |
| 224 | Dwarf_Addr addr, Dwarf_Addr *bias) |
| 225 | __nonnull_attribute__ (3); |
| 226 | |
| 227 | /* Iterate through the CUs, start with null for LASTCU. */ |
| 228 | extern Dwarf_Die *dwfl_nextcu (Dwfl *dwfl, Dwarf_Die *lastcu, Dwarf_Addr *bias) |
| 229 | __nonnull_attribute__ (3); |
| 230 | extern Dwarf_Die *dwfl_module_nextcu (Dwfl_Module *mod, |
| 231 | Dwarf_Die *lastcu, Dwarf_Addr *bias) |
| 232 | __nonnull_attribute__ (3); |
| 233 | |
| 234 | /* Return the module containing the CU DIE. */ |
| 235 | extern Dwfl_Module *dwfl_cumodule (Dwarf_Die *cudie); |
| 236 | |
| 237 | |
| 238 | /* Get source for address. */ |
| 239 | extern Dwfl_Line *dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr); |
| 240 | extern Dwfl_Line *dwfl_getsrc (Dwfl *dwfl, Dwarf_Addr addr); |
| 241 | |
| 242 | /* Get address for source. */ |
| 243 | extern int dwfl_module_getsrc_file (Dwfl_Module *mod, |
| 244 | const char *fname, int lineno, int column, |
| 245 | Dwfl_Line ***srcsp, size_t *nsrcs); |
| 246 | |
| 247 | /* Return the module containing this line record. */ |
| 248 | extern Dwfl_Module *dwfl_linemodule (Dwfl_Line *line); |
| 249 | |
| 250 | /* Return the source file name and fill in other information. |
| 251 | Arguments may be null for unneeded fields. */ |
| 252 | extern const char *dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr, |
| 253 | int *linep, int *colp, |
| 254 | Dwarf_Word *mtime, Dwarf_Word *length); |
| 255 | |
| 256 | |
| 257 | /* Find the symbol that ADDRESS lies inside, and return its name. */ |
| 258 | const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address); |
| 259 | |
| 260 | |
| 261 | |
| 262 | #endif /* libdwfl.h */ |