Blame libdw/memory-access.h

Packit Service 97d2fb
/* Unaligned memory access functionality.
Packit Service 97d2fb
   Copyright (C) 2000-2014, 2018 Red Hat, Inc.
Packit Service 97d2fb
   This file is part of elfutils.
Packit Service 97d2fb
Packit Service 97d2fb
   This file is free software; you can redistribute it and/or modify
Packit Service 97d2fb
   it under the terms of either
Packit Service 97d2fb
Packit Service 97d2fb
     * the GNU Lesser General Public License as published by the Free
Packit Service 97d2fb
       Software Foundation; either version 3 of the License, or (at
Packit Service 97d2fb
       your option) any later version
Packit Service 97d2fb
Packit Service 97d2fb
   or
Packit Service 97d2fb
Packit Service 97d2fb
     * the GNU General Public License as published by the Free
Packit Service 97d2fb
       Software Foundation; either version 2 of the License, or (at
Packit Service 97d2fb
       your option) any later version
Packit Service 97d2fb
Packit Service 97d2fb
   or both in parallel, as here.
Packit Service 97d2fb
Packit Service 97d2fb
   elfutils is distributed in the hope that it will be useful, but
Packit Service 97d2fb
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 97d2fb
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 97d2fb
   General Public License for more details.
Packit Service 97d2fb
Packit Service 97d2fb
   You should have received copies of the GNU General Public License and
Packit Service 97d2fb
   the GNU Lesser General Public License along with this program.  If
Packit Service 97d2fb
   not, see <http://www.gnu.org/licenses/>.  */
Packit Service 97d2fb
Packit Service 97d2fb
#ifndef _MEMORY_ACCESS_H
Packit Service 97d2fb
#define _MEMORY_ACCESS_H 1
Packit Service 97d2fb
Packit Service 97d2fb
#include <byteswap.h>
Packit Service 97d2fb
#include <endian.h>
Packit Service 97d2fb
#include <limits.h>
Packit Service 97d2fb
#include <stdint.h>
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
/* Number decoding macros.  See 7.6 Variable Length Data.  */
Packit Service 97d2fb
Packit Service 97d2fb
#define len_leb128(var) ((8 * sizeof (var) + 6) / 7)
Packit Service 97d2fb
Packit Service 97d2fb
static inline size_t
Packit Service 97d2fb
__libdw_max_len_leb128 (const size_t type_len,
Packit Service 97d2fb
			const unsigned char *addr, const unsigned char *end)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const size_t pointer_len = likely (addr < end) ? end - addr : 0;
Packit Service 97d2fb
  return likely (type_len <= pointer_len) ? type_len : pointer_len;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
static inline size_t
Packit Service 97d2fb
__libdw_max_len_uleb128 (const unsigned char *addr, const unsigned char *end)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const size_t type_len = len_leb128 (uint64_t);
Packit Service 97d2fb
  return __libdw_max_len_leb128 (type_len, addr, end);
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
static inline size_t
Packit Service 97d2fb
__libdw_max_len_sleb128 (const unsigned char *addr, const unsigned char *end)
Packit Service 97d2fb
{
Packit Service 97d2fb
  /* Subtract one step, so we don't shift into sign bit.  */
Packit Service 97d2fb
  const size_t type_len = len_leb128 (int64_t) - 1;
Packit Service 97d2fb
  return __libdw_max_len_leb128 (type_len, addr, end);
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
#define get_uleb128_step(var, addr, nth)				      \
Packit Service 97d2fb
  do {									      \
Packit Service 97d2fb
    unsigned char __b = *(addr)++;					      \
Packit Service 97d2fb
    (var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7);		      \
Packit Service 97d2fb
    if (likely ((__b & 0x80) == 0))					      \
Packit Service 97d2fb
      return (var);							      \
Packit Service 97d2fb
  } while (0)
Packit Service 97d2fb
Packit Service 97d2fb
static inline uint64_t
Packit Service 97d2fb
__libdw_get_uleb128 (const unsigned char **addrp, const unsigned char *end)
Packit Service 97d2fb
{
Packit Service 97d2fb
  uint64_t acc = 0;
Packit Service 97d2fb
Packit Service 97d2fb
  /* Unroll the first step to help the compiler optimize
Packit Service 97d2fb
     for the common single-byte case.  */
Packit Service 97d2fb
  get_uleb128_step (acc, *addrp, 0);
Packit Service 97d2fb
Packit Service 97d2fb
  const size_t max = __libdw_max_len_uleb128 (*addrp - 1, end);
Packit Service 97d2fb
  for (size_t i = 1; i < max; ++i)
Packit Service 97d2fb
    get_uleb128_step (acc, *addrp, i);
Packit Service 97d2fb
  /* Other implementations set VALUE to UINT_MAX in this
Packit Service 97d2fb
     case.  So we better do this as well.  */
Packit Service 97d2fb
  return UINT64_MAX;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
static inline uint64_t
Packit Service 97d2fb
__libdw_get_uleb128_unchecked (const unsigned char **addrp)
Packit Service 97d2fb
{
Packit Service 97d2fb
  uint64_t acc = 0;
Packit Service 97d2fb
Packit Service 97d2fb
  /* Unroll the first step to help the compiler optimize
Packit Service 97d2fb
     for the common single-byte case.  */
Packit Service 97d2fb
  get_uleb128_step (acc, *addrp, 0);
Packit Service 97d2fb
Packit Service 97d2fb
  const size_t max = len_leb128 (uint64_t);
Packit Service 97d2fb
  for (size_t i = 1; i < max; ++i)
Packit Service 97d2fb
    get_uleb128_step (acc, *addrp, i);
Packit Service 97d2fb
  /* Other implementations set VALUE to UINT_MAX in this
Packit Service 97d2fb
     case.  So we better do this as well.  */
Packit Service 97d2fb
  return UINT64_MAX;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
/* Note, addr needs to me smaller than end. */
Packit Service 97d2fb
#define get_uleb128(var, addr, end) ((var) = __libdw_get_uleb128 (&(addr), end))
Packit Service 97d2fb
#define get_uleb128_unchecked(var, addr) ((var) = __libdw_get_uleb128_unchecked (&(addr)))
Packit Service 97d2fb
Packit Service 97d2fb
/* The signed case is similar, but we sign-extend the result.  */
Packit Service 97d2fb
Packit Service 97d2fb
#define get_sleb128_step(var, addr, nth)				      \
Packit Service 97d2fb
  do {									      \
Packit Service 97d2fb
    unsigned char __b = *(addr)++;					      \
Packit Service 97d2fb
    (var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7);		      \
Packit Service 97d2fb
    if (likely ((__b & 0x80) == 0))					      \
Packit Service 97d2fb
      {									      \
Packit Service 97d2fb
	if ((__b & 0x40) != 0)						      \
Packit Service 97d2fb
	  (var) |= - ((typeof (var)) 1 << (((nth) + 1) * 7));		      \
Packit Service 97d2fb
	return (var);							      \
Packit Service 97d2fb
      }									      \
Packit Service 97d2fb
  } while (0)
Packit Service 97d2fb
Packit Service 97d2fb
static inline int64_t
Packit Service 97d2fb
__libdw_get_sleb128 (const unsigned char **addrp, const unsigned char *end)
Packit Service 97d2fb
{
Packit Service 97d2fb
  /* Do the work in an unsigned type, but use implementation-defined
Packit Service 97d2fb
     behavior to cast to signed on return.  This avoids some undefined
Packit Service 97d2fb
     behavior when shifting.  */
Packit Service 97d2fb
  uint64_t acc = 0;
Packit Service 97d2fb
Packit Service 97d2fb
  /* Unroll the first step to help the compiler optimize
Packit Service 97d2fb
     for the common single-byte case.  */
Packit Service 97d2fb
  get_sleb128_step (acc, *addrp, 0);
Packit Service 97d2fb
Packit Service 97d2fb
  const size_t max = __libdw_max_len_sleb128 (*addrp - 1, end);
Packit Service 97d2fb
  for (size_t i = 1; i < max; ++i)
Packit Service 97d2fb
    get_sleb128_step (acc, *addrp, i);
Packit Service 97d2fb
  if (*addrp == end)
Packit Service 97d2fb
    return INT64_MAX;
Packit Service 97d2fb
Packit Service 97d2fb
  /* There might be one extra byte.  */
Packit Service 97d2fb
  unsigned char b = **addrp;
Packit Service 97d2fb
  ++*addrp;
Packit Service 97d2fb
  if (likely ((b & 0x80) == 0))
Packit Service 97d2fb
    {
Packit Service 97d2fb
      /* We only need the low bit of the final byte, and as it is the
Packit Service 97d2fb
	 sign bit, we don't need to do anything else here.  */
Packit Service 97d2fb
      acc |= ((typeof (acc)) b) << 7 * max;
Packit Service 97d2fb
      return acc;
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
  /* Other implementations set VALUE to INT_MAX in this
Packit Service 97d2fb
     case.  So we better do this as well.  */
Packit Service 97d2fb
  return INT64_MAX;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
static inline int64_t
Packit Service 97d2fb
__libdw_get_sleb128_unchecked (const unsigned char **addrp)
Packit Service 97d2fb
{
Packit Service 97d2fb
  /* Do the work in an unsigned type, but use implementation-defined
Packit Service 97d2fb
     behavior to cast to signed on return.  This avoids some undefined
Packit Service 97d2fb
     behavior when shifting.  */
Packit Service 97d2fb
  uint64_t acc = 0;
Packit Service 97d2fb
Packit Service 97d2fb
  /* Unroll the first step to help the compiler optimize
Packit Service 97d2fb
     for the common single-byte case.  */
Packit Service 97d2fb
  get_sleb128_step (acc, *addrp, 0);
Packit Service 97d2fb
Packit Service 97d2fb
  /* Subtract one step, so we don't shift into sign bit.  */
Packit Service 97d2fb
  const size_t max = len_leb128 (int64_t) - 1;
Packit Service 97d2fb
  for (size_t i = 1; i < max; ++i)
Packit Service 97d2fb
    get_sleb128_step (acc, *addrp, i);
Packit Service 97d2fb
Packit Service 97d2fb
  /* There might be one extra byte.  */
Packit Service 97d2fb
  unsigned char b = **addrp;
Packit Service 97d2fb
  ++*addrp;
Packit Service 97d2fb
  if (likely ((b & 0x80) == 0))
Packit Service 97d2fb
    {
Packit Service 97d2fb
      /* We only need the low bit of the final byte, and as it is the
Packit Service 97d2fb
	 sign bit, we don't need to do anything else here.  */
Packit Service 97d2fb
      acc |= ((typeof (acc)) b) << 7 * max;
Packit Service 97d2fb
      return acc;
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
  /* Other implementations set VALUE to INT_MAX in this
Packit Service 97d2fb
     case.  So we better do this as well.  */
Packit Service 97d2fb
  return INT64_MAX;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
#define get_sleb128(var, addr, end) ((var) = __libdw_get_sleb128 (&(addr), end))
Packit Service 97d2fb
#define get_sleb128_unchecked(var, addr) ((var) = __libdw_get_sleb128_unchecked (&(addr)))
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
/* We use simple memory access functions in case the hardware allows it.
Packit Service 97d2fb
   The caller has to make sure we don't have alias problems.  */
Packit Service 97d2fb
#if ALLOW_UNALIGNED
Packit Service 97d2fb
Packit Service 97d2fb
# define read_2ubyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  (unlikely ((Dbg)->other_byte_order)					      \
Packit Service 97d2fb
   ? bswap_16 (*((const uint16_t *) (Addr)))				      \
Packit Service 97d2fb
   : *((const uint16_t *) (Addr)))
Packit Service 97d2fb
# define read_2sbyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  (unlikely ((Dbg)->other_byte_order)					      \
Packit Service 97d2fb
   ? (int16_t) bswap_16 (*((const int16_t *) (Addr)))			      \
Packit Service 97d2fb
   : *((const int16_t *) (Addr)))
Packit Service 97d2fb
Packit Service 97d2fb
# define read_4ubyte_unaligned_noncvt(Addr) \
Packit Service 97d2fb
   *((const uint32_t *) (Addr))
Packit Service 97d2fb
# define read_4ubyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  (unlikely ((Dbg)->other_byte_order)					      \
Packit Service 97d2fb
   ? bswap_32 (*((const uint32_t *) (Addr)))				      \
Packit Service 97d2fb
   : *((const uint32_t *) (Addr)))
Packit Service 97d2fb
# define read_4sbyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  (unlikely ((Dbg)->other_byte_order)					      \
Packit Service 97d2fb
   ? (int32_t) bswap_32 (*((const int32_t *) (Addr)))			      \
Packit Service 97d2fb
   : *((const int32_t *) (Addr)))
Packit Service 97d2fb
Packit Service 97d2fb
# define read_8ubyte_unaligned_noncvt(Addr) \
Packit Service 97d2fb
   *((const uint64_t *) (Addr))
Packit Service 97d2fb
# define read_8ubyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  (unlikely ((Dbg)->other_byte_order)					      \
Packit Service 97d2fb
   ? bswap_64 (*((const uint64_t *) (Addr)))				      \
Packit Service 97d2fb
   : *((const uint64_t *) (Addr)))
Packit Service 97d2fb
# define read_8sbyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  (unlikely ((Dbg)->other_byte_order)					      \
Packit Service 97d2fb
   ? (int64_t) bswap_64 (*((const int64_t *) (Addr)))			      \
Packit Service 97d2fb
   : *((const int64_t *) (Addr)))
Packit Service 97d2fb
Packit Service 97d2fb
#else
Packit Service 97d2fb
Packit Service 97d2fb
union unaligned
Packit Service 97d2fb
  {
Packit Service 97d2fb
    void *p;
Packit Service 97d2fb
    uint16_t u2;
Packit Service 97d2fb
    uint32_t u4;
Packit Service 97d2fb
    uint64_t u8;
Packit Service 97d2fb
    int16_t s2;
Packit Service 97d2fb
    int32_t s4;
Packit Service 97d2fb
    int64_t s8;
Packit Service 97d2fb
  } attribute_packed;
Packit Service 97d2fb
Packit Service 97d2fb
# define read_2ubyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  read_2ubyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
Packit Service 97d2fb
# define read_2sbyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  read_2sbyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
Packit Service 97d2fb
# define read_4ubyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  read_4ubyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
Packit Service 97d2fb
# define read_4sbyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  read_4sbyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
Packit Service 97d2fb
# define read_8ubyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  read_8ubyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
Packit Service 97d2fb
# define read_8sbyte_unaligned(Dbg, Addr) \
Packit Service 97d2fb
  read_8sbyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
Packit Service 97d2fb
Packit Service 97d2fb
static inline uint16_t
Packit Service 97d2fb
read_2ubyte_unaligned_1 (bool other_byte_order, const void *p)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const union unaligned *up = p;
Packit Service 97d2fb
  if (unlikely (other_byte_order))
Packit Service 97d2fb
    return bswap_16 (up->u2);
Packit Service 97d2fb
  return up->u2;
Packit Service 97d2fb
}
Packit Service 97d2fb
static inline int16_t
Packit Service 97d2fb
read_2sbyte_unaligned_1 (bool other_byte_order, const void *p)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const union unaligned *up = p;
Packit Service 97d2fb
  if (unlikely (other_byte_order))
Packit Service 97d2fb
    return (int16_t) bswap_16 (up->u2);
Packit Service 97d2fb
  return up->s2;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
static inline uint32_t
Packit Service 97d2fb
read_4ubyte_unaligned_noncvt (const void *p)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const union unaligned *up = p;
Packit Service 97d2fb
  return up->u4;
Packit Service 97d2fb
}
Packit Service 97d2fb
static inline uint32_t
Packit Service 97d2fb
read_4ubyte_unaligned_1 (bool other_byte_order, const void *p)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const union unaligned *up = p;
Packit Service 97d2fb
  if (unlikely (other_byte_order))
Packit Service 97d2fb
    return bswap_32 (up->u4);
Packit Service 97d2fb
  return up->u4;
Packit Service 97d2fb
}
Packit Service 97d2fb
static inline int32_t
Packit Service 97d2fb
read_4sbyte_unaligned_1 (bool other_byte_order, const void *p)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const union unaligned *up = p;
Packit Service 97d2fb
  if (unlikely (other_byte_order))
Packit Service 97d2fb
    return (int32_t) bswap_32 (up->u4);
Packit Service 97d2fb
  return up->s4;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
static inline uint64_t
Packit Service 97d2fb
read_8ubyte_unaligned_noncvt (const void *p)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const union unaligned *up = p;
Packit Service 97d2fb
  return up->u8;
Packit Service 97d2fb
}
Packit Service 97d2fb
static inline uint64_t
Packit Service 97d2fb
read_8ubyte_unaligned_1 (bool other_byte_order, const void *p)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const union unaligned *up = p;
Packit Service 97d2fb
  if (unlikely (other_byte_order))
Packit Service 97d2fb
    return bswap_64 (up->u8);
Packit Service 97d2fb
  return up->u8;
Packit Service 97d2fb
}
Packit Service 97d2fb
static inline int64_t
Packit Service 97d2fb
read_8sbyte_unaligned_1 (bool other_byte_order, const void *p)
Packit Service 97d2fb
{
Packit Service 97d2fb
  const union unaligned *up = p;
Packit Service 97d2fb
  if (unlikely (other_byte_order))
Packit Service 97d2fb
    return (int64_t) bswap_64 (up->u8);
Packit Service 97d2fb
  return up->s8;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
#endif	/* allow unaligned */
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
#define read_2ubyte_unaligned_inc(Dbg, Addr) \
Packit Service 97d2fb
  ({ uint16_t t_ = read_2ubyte_unaligned (Dbg, Addr);			      \
Packit Service 97d2fb
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2);		      \
Packit Service 97d2fb
     t_; })
Packit Service 97d2fb
#define read_2sbyte_unaligned_inc(Dbg, Addr) \
Packit Service 97d2fb
  ({ int16_t t_ = read_2sbyte_unaligned (Dbg, Addr);			      \
Packit Service 97d2fb
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2);		      \
Packit Service 97d2fb
     t_; })
Packit Service 97d2fb
Packit Service 97d2fb
#define read_4ubyte_unaligned_inc(Dbg, Addr) \
Packit Service 97d2fb
  ({ uint32_t t_ = read_4ubyte_unaligned (Dbg, Addr);			      \
Packit Service 97d2fb
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4);		      \
Packit Service 97d2fb
     t_; })
Packit Service 97d2fb
#define read_4sbyte_unaligned_inc(Dbg, Addr) \
Packit Service 97d2fb
  ({ int32_t t_ = read_4sbyte_unaligned (Dbg, Addr);			      \
Packit Service 97d2fb
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4);		      \
Packit Service 97d2fb
     t_; })
Packit Service 97d2fb
Packit Service 97d2fb
#define read_8ubyte_unaligned_inc(Dbg, Addr) \
Packit Service 97d2fb
  ({ uint64_t t_ = read_8ubyte_unaligned (Dbg, Addr);			      \
Packit Service 97d2fb
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8);		      \
Packit Service 97d2fb
     t_; })
Packit Service 97d2fb
#define read_8sbyte_unaligned_inc(Dbg, Addr) \
Packit Service 97d2fb
  ({ int64_t t_ = read_8sbyte_unaligned (Dbg, Addr);			      \
Packit Service 97d2fb
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8);		      \
Packit Service 97d2fb
     t_; })
Packit Service 97d2fb
Packit Service 97d2fb
/* 3ubyte reads are only used for DW_FORM_addrx3 and DW_FORM_strx3.
Packit Service 97d2fb
   And are probably very rare.  They are not optimized.  They are
Packit Service 97d2fb
   handled as if reading a 4byte value with the first (for big endian)
Packit Service 97d2fb
   or last (for little endian) byte zero.  */
Packit Service 97d2fb
Packit Service 97d2fb
static inline int
Packit Service 97d2fb
file_byte_order (bool other_byte_order)
Packit Service 97d2fb
{
Packit Service 97d2fb
#if __BYTE_ORDER == __LITTLE_ENDIAN
Packit Service 97d2fb
  return other_byte_order ? __BIG_ENDIAN : __LITTLE_ENDIAN;
Packit Service 97d2fb
#else
Packit Service 97d2fb
  return other_byte_order ? __LITTLE_ENDIAN : __BIG_ENDIAN;
Packit Service 97d2fb
#endif
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
static inline uint32_t
Packit Service 97d2fb
read_3ubyte_unaligned (Dwarf *dbg, const unsigned char *p)
Packit Service 97d2fb
{
Packit Service 97d2fb
  union
Packit Service 97d2fb
  {
Packit Service 97d2fb
    uint32_t u4;
Packit Service 97d2fb
    unsigned char c[4];
Packit Service 97d2fb
  } d;
Packit Service 97d2fb
  bool other_byte_order = dbg->other_byte_order;
Packit Service 97d2fb
Packit Service 97d2fb
  if (file_byte_order (other_byte_order) == __BIG_ENDIAN)
Packit Service 97d2fb
    {
Packit Service 97d2fb
      d.c[0] = 0x00;
Packit Service 97d2fb
      d.c[1] = p[0];
Packit Service 97d2fb
      d.c[2] = p[1];
Packit Service 97d2fb
      d.c[3] = p[2];
Packit Service 97d2fb
    }
Packit Service 97d2fb
  else
Packit Service 97d2fb
    {
Packit Service 97d2fb
      d.c[0] = p[0];
Packit Service 97d2fb
      d.c[1] = p[1];
Packit Service 97d2fb
      d.c[2] = p[2];
Packit Service 97d2fb
      d.c[3] = 0x00;
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
  if (other_byte_order)
Packit Service 97d2fb
    return bswap_32 (d.u4);
Packit Service 97d2fb
  else
Packit Service 97d2fb
    return d.u4;
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
#define read_3ubyte_unaligned_inc(Dbg, Addr) \
Packit Service 97d2fb
  ({ uint32_t t_ = read_3ubyte_unaligned (Dbg, Addr);			      \
Packit Service 97d2fb
     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 3);		      \
Packit Service 97d2fb
     t_; })
Packit Service 97d2fb
Packit Service 97d2fb
#define read_addr_unaligned_inc(Nbytes, Dbg, Addr)			\
Packit Service 97d2fb
  (assert ((Nbytes) == 4 || (Nbytes) == 8),				\
Packit Service 97d2fb
    ((Nbytes) == 4 ? read_4ubyte_unaligned_inc (Dbg, Addr)		\
Packit Service 97d2fb
     : read_8ubyte_unaligned_inc (Dbg, Addr)))
Packit Service 97d2fb
Packit Service 97d2fb
#endif	/* memory-access.h */