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 some helpful macros, and inline routines.
     15  */
     16 
     17 #ifndef ELFF_ELF_DEFS_H_
     18 #define ELFF_ELF_DEFS_H_
     19 
     20 #include "elff_elf.h"
     21 
     22 //=============================================================================
     23 // Macros.
     24 //=============================================================================
     25 
     26 /* Increments a pointer by n bytes.
     27  * Param:
     28  *  p - Pointer to increment.
     29  *  n - Number of bytes to increment the pointer with.
     30  */
     31 #define INC_PTR(p, n)   (reinterpret_cast<uint8_t*>(p) + (n))
     32 
     33 /* Increments a constant pointer by n bytes.
     34  * Param:
     35  *  p - Pointer to increment.
     36  *  n - Number of bytes to increment the pointer with.
     37  */
     38 #define INC_CPTR(p, n)  (reinterpret_cast<const uint8_t*>(p) + (n))
     39 
     40 /* Increments a pointer of a given type by n bytes.
     41  * Param:
     42  *  T - Pointer type
     43  *  p - Pointer to increment.
     44  *  n - Number of bytes to increment the pointer with.
     45  */
     46 #define INC_PTR_T(T, p, n)                              \
     47     reinterpret_cast<T*>                                \
     48         (reinterpret_cast<uint8_t*>(p) + (n))
     49 
     50 /* Increments a constant pointer of a given type by n bytes.
     51  * Param:
     52  *  T - Pointer type
     53  *  p - Pointer to increment.
     54  *  n - Number of bytes to increment the pointer with.
     55  */
     56 #define INC_CPTR_T(T, p, n)                                 \
     57     reinterpret_cast<const T*>                              \
     58         (reinterpret_cast<const uint8_t*>(p) + (n))
     59 
     60 /* Calculates number of entries in a static array.
     61  * Param:
     62  *  a - Array.
     63  * Return:
     64  *  Number of entries in the array.
     65  */
     66 #define ELFF_ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
     67 
     68 /* Calculates offset of a field inside a structure (or a class) of the
     69  * given type.
     70  * Param:
     71  *  T - Structure (or class) type.
     72  *  f - Name of a field (member variable) for this structure (or class).
     73  */
     74 #define ELFF_FIELD_OFFSET(T, f) ((size_t)(size_t*)&(((T *)0)->f))
     75 
     76 //=============================================================================
     77 // Inline routines.
     78 //=============================================================================
     79 
     80 /* Calculates byte interval between two pointers.
     81  * Param:
     82  *  s - Starting pointer of the interval. Must be less, or equal to 'e'.
     83  *  e - Ending pointer of the interval. Must be greater, or equal to 's'.
     84  * Return:
     85  *  Byte interval between two pointers.
     86  */
     87 static inline size_t
     88 diff_ptr(const void* s, const void* e) {
     89   assert(s <= e);
     90   return ((size_t)(reinterpret_cast<const uint8_t*>(e) -
     91          reinterpret_cast<const uint8_t*>(s)));
     92 }
     93 
     94 /* Gets one byte from an index inside a memory block.
     95  * Param:
     96  *  ptr - Address of the beginning of the memory block.
     97  *  bt - Index of a byte inside the block to get.
     98  * Return:
     99  *  A byte at the given index inside the given memory block.
    100  */
    101 static inline uint8_t
    102 get_byte(const void* ptr, uint32_t bt) {
    103   return *(reinterpret_cast<const uint8_t*>(ptr) + bt);
    104 }
    105 
    106 /* Checks if given address range is fully contained within a section.
    107  * Param:
    108  *  rp - Beginning of the range to check.
    109  *  rsize - Size of the range to check.
    110  *  ss - Beginning of the section that should contain the checking range.
    111  *  ssize - Size of the section that should contain the checking range.
    112  * Return:
    113  *  true, if given address range is fully contained within a section, or
    114  *  false, if any part of the address range is not contained in the secton.
    115  */
    116 static inline bool
    117 is_in_section(const void* rp, size_t rsize, const void* ss, size_t ssize) {
    118   const void* rend = INC_CPTR(rp, rsize);
    119   /* We also make sure here that increment didn't overflow the pointer. */
    120   return rp >= ss && ss != NULL && (diff_ptr(ss, rend) <= ssize) && rend >= rp;
    121 }
    122 
    123 /* Checks if this code runs on CPU with a little-endian data format.
    124  * Return:
    125  *  true, if this code runs on CPU with a little-endian data format,
    126  *  or false, if this code runs on CPU with a big-endian data format.
    127  */
    128 static inline bool
    129 is_little_endian_cpu(void) {
    130   uint16_t tmp = 0x00FF;
    131   /* Lets see if byte has flipped for little-endian. */
    132   return get_byte(&tmp, 0) == 0xFF;
    133 }
    134 
    135 #endif  // ELFF_ELF_DEFS_H_
    136