| /* 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_ |