static inline bool
do_check64 (size_t i, const Elf64_auxv_t (*a64)[], uint_fast8_t *elfdata)
{
  /* The AUXV pointer might not even be naturally aligned for 64-bit
     data, because note payloads in a core file are not aligned.  */

  uint64_t type = read_8ubyte_unaligned_noncvt (&(*a64)[i].a_type);
  uint64_t val = read_8ubyte_unaligned_noncvt (&(*a64)[i].a_un.a_val);

  if (type == BE64 (PROBE_TYPE)
      && val == BE64 (PROBE_VAL64))
    {
      *elfdata = ELFDATA2MSB;
      return true;
    }

  if (type == LE64 (PROBE_TYPE)
      && val == LE64 (PROBE_VAL64))
    {
      *elfdata = ELFDATA2LSB;
      return true;
    }

  return false;
}
示例#2
0
/* Examine an auxv data block and determine its format.
   Return true iff we figured it out.  */
static bool
auxv_format_probe (const void *auxv, size_t size,
                   uint_fast8_t *elfclass, uint_fast8_t *elfdata)
{
    const union
    {
        char buf[size];
        Elf32_auxv_t a32[size / sizeof (Elf32_auxv_t)];
        Elf64_auxv_t a64[size / sizeof (Elf64_auxv_t)];
    } *u = auxv;

    inline bool check64 (size_t i)
    {
        /* The AUXV pointer might not even be naturally aligned for 64-bit
           data, because note payloads in a core file are not aligned.  */

        uint64_t type = read_8ubyte_unaligned_noncvt (&u->a64[i].a_type);
        uint64_t val = read_8ubyte_unaligned_noncvt (&u->a64[i].a_un.a_val);

        if (type == BE64 (PROBE_TYPE)
                && val == BE64 (PROBE_VAL64))
        {
            *elfdata = ELFDATA2MSB;
            return true;
        }

        if (type == LE64 (PROBE_TYPE)
                && val == LE64 (PROBE_VAL64))
        {
            *elfdata = ELFDATA2LSB;
            return true;
        }

        return false;
    }
static int
report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
		Dwfl *dwfl, GElf_Addr r_debug_vaddr,
		Dwfl_Memory_Callback *memory_callback,
		void *memory_callback_arg,
		struct r_debug_info *r_debug_info)
{
  /* Skip r_version, to aligned r_map field.  */
  GElf_Addr read_vaddr = r_debug_vaddr + addrsize (elfclass);

  void *buffer = NULL;
  size_t buffer_available = 0;
  inline int release_buffer (int result)
  {
    if (buffer != NULL)
      (void) (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0,
				 memory_callback_arg);
    return result;
  }

  GElf_Addr addrs[4];
  inline bool read_addrs (GElf_Addr vaddr, size_t n)
  {
    size_t nb = n * addrsize (elfclass); /* Address words -> bytes to read.  */

    /* Read a new buffer if the old one doesn't cover these words.  */
    if (buffer == NULL
	|| vaddr < read_vaddr
	|| vaddr - read_vaddr + nb > buffer_available)
      {
	release_buffer (0);

	read_vaddr = vaddr;
	int segndx = INTUSE(dwfl_addrsegment) (dwfl, vaddr, NULL);
	if (unlikely (segndx < 0)
	    || unlikely (! (*memory_callback) (dwfl, segndx,
					       &buffer, &buffer_available,
					       vaddr, nb, memory_callback_arg)))
	  return true;
      }

    Elf32_Addr (*a32)[n] = vaddr - read_vaddr + buffer;
    Elf64_Addr (*a64)[n] = (void *) a32;

    if (elfclass == ELFCLASS32)
      {
	if (elfdata == ELFDATA2MSB)
	  for (size_t i = 0; i < n; ++i)
	    addrs[i] = BE32 (read_4ubyte_unaligned_noncvt (&(*a32)[i]));
	else
	  for (size_t i = 0; i < n; ++i)
	    addrs[i] = LE32 (read_4ubyte_unaligned_noncvt (&(*a32)[i]));
      }
    else
      {
	if (elfdata == ELFDATA2MSB)
	  for (size_t i = 0; i < n; ++i)
	    addrs[i] = BE64 (read_8ubyte_unaligned_noncvt (&(*a64)[i]));
	else
	  for (size_t i = 0; i < n; ++i)
	    addrs[i] = LE64 (read_8ubyte_unaligned_noncvt (&(*a64)[i]));
      }

    return false;
  }