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
elfinlineinfo_is_last_entry(const Elf_InlineInfo * info)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