• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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