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