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