1 /* Copyright (C) 2007-2010 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 13 /* 14 * Contains declaration of types, strctures, routines, etc. that encapsulte 15 * an API for parsing an ELF file containing debugging information in DWARF 16 * format. 17 */ 18 19 #ifndef ELFF_API_H_ 20 #define ELFF_API_H_ 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 #include <stdint.h> 27 28 /* Defines type for a handle used in ELFF API. */ 29 typedef void* ELFF_HANDLE; 30 31 /* Defines an entry for 'inline_stack' array in Elf_AddressInfo structure. 32 * Each entry in the array represents a routine, where routine represented 33 * with the previous array entry has been inlined. First element in the array 34 * (at index 0) represents information for the inlined routine, referenced by 35 * Elf_AddressInfo structure itself. If name for a routine was not available 36 * (DW_AT_name attribute was missing), routine name is set to "<unknown>". 37 * Last entry in the array has all its fields set to zero. It's sufficient 38 * just to check for routine_name field of this structure to be NULL to detect 39 * last entry in the array. 40 */ 41 typedef struct Elf_InlineInfo { 42 /* Name of the routine where previous routine is inlined. 43 * This field can never be NULL, except for the last array entry. 44 */ 45 const char* routine_name; 46 47 /* Source file name where routine is inlined. 48 * This field can be NULL, if it was not possible to obtain information 49 * about source file location for the routine. If this field is NULL, content 50 * of inlined_in_file_dir and inlined_at_line fields is undefined and should 51 * be ignored. */ 52 const char* inlined_in_file; 53 54 /* Source file directory where routine is inlined. 55 * If inlined_in_file field contains NULL, content of this field is undefined 56 * and should be ignored. */ 57 const char* inlined_in_file_dir; 58 59 /* Source file line number where routine is inlined. 60 * If inlined_in_file field contains NULL, content of this field is undefined 61 * and should be ignored. */ 62 uint32_t inlined_at_line; 63 } Elf_InlineInfo; 64 65 /* Checks if an entry is the last entry in the array. 66 * Return: 67 * Boolean: 1 if this is last entry, or zero otherwise. 68 */ 69 static inline int 70 elfinlineinfo_is_last_entry(const Elf_InlineInfo* info) { 71 return info->routine_name == 0; 72 } 73 74 /* PC address information descriptor. 75 * This descriptor contains as much information about a PC address as it was 76 * possible to collect from an ELF file. */ 77 typedef struct Elf_AddressInfo { 78 /* Name of the routine containing the address. If name of the routine 79 * was not available (DW_AT_name attribute was missing) this field 80 * is set to "<unknown>". */ 81 const char* routine_name; 82 83 /* Name of the source file containing the routine. If source location for the 84 * routine was not available, this field is set to NULL, and content of 85 * dir_name, and line_number fields of this structure is not defined. */ 86 const char* file_name; 87 88 /* Path to the source file directory. If file_name field of this structure is 89 * NULL, content of this field is not defined. */ 90 const char* dir_name; 91 92 /* Line number in the source file for the address. If file_name field of this 93 * structure is NULL, content of this field is not defined. */ 94 uint32_t line_number; 95 96 /* If routine that contains the given address has been inlined (or it is part 97 * of even deeper inline branch) this array lists information about that 98 * inline branch rooting to the first routine that has not been inlined. The 99 * first element in the array references a routine, where routine containing 100 * the given address has been inlined. The second entry contains information 101 * about a routine referenced by the first entry (and so on). If routine, 102 * containing the given address has not been inlined, this field is set to 103 * NULL. The array ends with an entry containing all zeroes. */ 104 Elf_InlineInfo* inline_stack; 105 } Elf_AddressInfo; 106 107 //============================================================================= 108 // API routines 109 //============================================================================= 110 111 /* Initializes ELFF API for the given ELF file. 112 * Param: 113 * elf_file_path - Path to the ELF file to initialize API for. 114 * Return: 115 * On success, this routine returns a handle that can be used in subsequent 116 * calls to this API dealing with the given ELF file. On failure this routine 117 * returns NULL, with errno providing extended error information. 118 * NOTE: handle returned from this routine must be closed using elff_close(). 119 */ 120 ELFF_HANDLE elff_init(const char* elf_file_path); 121 122 /* Closes a handle obtained after successful call to elff_init routine. 123 * Param: 124 * handle - A handle to close. This handle must be a handle returned from 125 * a successful call to elff_init routine. 126 */ 127 void elff_close(ELFF_HANDLE handle); 128 129 /* Checks if ELF file represents an executable file, or a shared library. 130 * handle - A handle obtained from successful call to elff_init(). 131 * Return: 132 * 1 if ELF file represents an executable file, or 133 * 0 if ELF file represents a shared library, or 134 * -1 if handle is invalid. 135 */ 136 int elff_is_exec(ELFF_HANDLE handle); 137 138 /* Gets PC address information. 139 * Param: 140 * handle - A handle obtained from successful call to elff_init(). 141 * address - PC address to get information for. Address must be relative to 142 * the beginning of ELF file represented by the handle parameter. 143 * address_info - Upon success contains information about routine(s) that 144 * contain the given address. 145 * Return: 146 * 0 if routine(s) containing the given address has been found and information 147 * has been saved into address_info, or -1 if no appropriate routine for that 148 * address has been found, or there was a memory error when collecting 149 * routine(s) information. In case of failure, errno provides extended 150 * error information. 151 * NOTE: Successful call to this routine must be complimented with a call 152 * to free_pc_address_info, so ELFF API can release resources aquired for 153 * address_info. 154 */ 155 int elff_get_pc_address_info(ELFF_HANDLE handle, 156 uint64_t address, 157 Elf_AddressInfo* address_info); 158 159 /* Frees resources acquired for address information in successful call to 160 * get_pc_address_info(). 161 * Param: 162 * handle - A handle obtained from successful call to elff_init(). 163 * address_info - Address information structure, initialized in successful 164 * call to get_pc_address_info() routine. 165 */ 166 void elff_free_pc_address_info(ELFF_HANDLE handle, 167 Elf_AddressInfo* address_info); 168 169 #ifdef __cplusplus 170 } /* end of extern "C" */ 171 #endif 172 173 #endif // ELFF_API_H_ 174