Home | History | Annotate | Download | only in elff
      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 "qemu-common.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
     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