tools/profiler/LulElfInt.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/profiler/LulElfInt.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,234 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */
     1.6 +
     1.7 +// Copyright (c) 2006, 2012, Google Inc.
     1.8 +// All rights reserved.
     1.9 +//
    1.10 +// Redistribution and use in source and binary forms, with or without
    1.11 +// modification, are permitted provided that the following conditions are
    1.12 +// met:
    1.13 +//
    1.14 +//     * Redistributions of source code must retain the above copyright
    1.15 +// notice, this list of conditions and the following disclaimer.
    1.16 +//     * Redistributions in binary form must reproduce the above
    1.17 +// copyright notice, this list of conditions and the following disclaimer
    1.18 +// in the documentation and/or other materials provided with the
    1.19 +// distribution.
    1.20 +//     * Neither the name of Google Inc. nor the names of its
    1.21 +// contributors may be used to endorse or promote products derived from
    1.22 +// this software without specific prior written permission.
    1.23 +//
    1.24 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.25 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.26 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.27 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    1.28 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.29 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.30 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.31 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.32 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.33 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.34 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.35 +
    1.36 +// This file is derived from the following files in
    1.37 +// toolkit/crashreporter/google-breakpad:
    1.38 +//   src/common/android/include/elf.h
    1.39 +//   src/common/linux/elfutils.h
    1.40 +//   src/common/linux/file_id.h
    1.41 +//   src/common/linux/elfutils-inl.h
    1.42 +
    1.43 +#ifndef LulElfInt_h
    1.44 +#define LulElfInt_h
    1.45 +
    1.46 +// This header defines functions etc internal to the ELF reader.  It
    1.47 +// should not be included outside of LulElf.cpp.
    1.48 +
    1.49 +#include <elf.h>
    1.50 +#include <stdlib.h>
    1.51 +
    1.52 +#include "mozilla/Assertions.h"
    1.53 +
    1.54 +#include "LulPlatformMacros.h"
    1.55 +
    1.56 +
    1.57 +// (derived from)
    1.58 +// elfutils.h: Utilities for dealing with ELF files.
    1.59 +//
    1.60 +
    1.61 +#if defined(LUL_OS_android)
    1.62 +
    1.63 +// From toolkit/crashreporter/google-breakpad/src/common/android/include/elf.h
    1.64 +// The Android headers don't always define this constant.
    1.65 +#ifndef EM_X86_64
    1.66 +#define EM_X86_64  62
    1.67 +#endif
    1.68 +
    1.69 +#ifndef EM_PPC64
    1.70 +#define EM_PPC64   21
    1.71 +#endif
    1.72 +
    1.73 +#ifndef EM_S390
    1.74 +#define EM_S390    22
    1.75 +#endif
    1.76 +
    1.77 +#ifndef NT_GNU_BUILD_ID
    1.78 +#define NT_GNU_BUILD_ID 3
    1.79 +#endif
    1.80 +
    1.81 +#define ElfW(type)      _ElfW (Elf, ELFSIZE, type)
    1.82 +#define _ElfW(e,w,t)    _ElfW_1 (e, w, _##t)
    1.83 +#define _ElfW_1(e,w,t)  e##w##t
    1.84 +
    1.85 +//FIXME
    1.86 +extern "C" {
    1.87 +  extern char*  basename(const char*  path);
    1.88 +};
    1.89 +#else
    1.90 +
    1.91 +# include <link.h>
    1.92 +#endif
    1.93 +
    1.94 +
    1.95 +namespace lul {
    1.96 +
    1.97 +// Traits classes so consumers can write templatized code to deal
    1.98 +// with specific ELF bits.
    1.99 +struct ElfClass32 {
   1.100 +  typedef Elf32_Addr Addr;
   1.101 +  typedef Elf32_Ehdr Ehdr;
   1.102 +  typedef Elf32_Nhdr Nhdr;
   1.103 +  typedef Elf32_Phdr Phdr;
   1.104 +  typedef Elf32_Shdr Shdr;
   1.105 +  typedef Elf32_Half Half;
   1.106 +  typedef Elf32_Off Off;
   1.107 +  typedef Elf32_Word Word;
   1.108 +  static const int kClass = ELFCLASS32;
   1.109 +  static const size_t kAddrSize = sizeof(Elf32_Addr);
   1.110 +};
   1.111 +
   1.112 +struct ElfClass64 {
   1.113 +  typedef Elf64_Addr Addr;
   1.114 +  typedef Elf64_Ehdr Ehdr;
   1.115 +  typedef Elf64_Nhdr Nhdr;
   1.116 +  typedef Elf64_Phdr Phdr;
   1.117 +  typedef Elf64_Shdr Shdr;
   1.118 +  typedef Elf64_Half Half;
   1.119 +  typedef Elf64_Off Off;
   1.120 +  typedef Elf64_Word Word;
   1.121 +  static const int kClass = ELFCLASS64;
   1.122 +  static const size_t kAddrSize = sizeof(Elf64_Addr);
   1.123 +};
   1.124 +
   1.125 +bool IsValidElf(const void* elf_header);
   1.126 +int ElfClass(const void* elf_base);
   1.127 +
   1.128 +// Attempt to find a section named |section_name| of type |section_type|
   1.129 +// in the ELF binary data at |elf_mapped_base|. On success, returns true
   1.130 +// and sets |*section_start| to point to the start of the section data,
   1.131 +// and |*section_size| to the size of the section's data. If |elfclass|
   1.132 +// is not NULL, set |*elfclass| to the ELF file class.
   1.133 +bool FindElfSection(const void *elf_mapped_base,
   1.134 +                    const char *section_name,
   1.135 +                    uint32_t section_type,
   1.136 +                    const void **section_start,
   1.137 +                    int *section_size,
   1.138 +                    int *elfclass);
   1.139 +
   1.140 +// Internal helper method, exposed for convenience for callers
   1.141 +// that already have more info.
   1.142 +template<typename ElfClass>
   1.143 +const typename ElfClass::Shdr*
   1.144 +FindElfSectionByName(const char* name,
   1.145 +                     typename ElfClass::Word section_type,
   1.146 +                     const typename ElfClass::Shdr* sections,
   1.147 +                     const char* section_names,
   1.148 +                     const char* names_end,
   1.149 +                     int nsection);
   1.150 +
   1.151 +// Attempt to find the first segment of type |segment_type| in the ELF
   1.152 +// binary data at |elf_mapped_base|. On success, returns true and sets
   1.153 +// |*segment_start| to point to the start of the segment data, and
   1.154 +// and |*segment_size| to the size of the segment's data. If |elfclass|
   1.155 +// is not NULL, set |*elfclass| to the ELF file class.
   1.156 +bool FindElfSegment(const void *elf_mapped_base,
   1.157 +                    uint32_t segment_type,
   1.158 +                    const void **segment_start,
   1.159 +                    int *segment_size,
   1.160 +                    int *elfclass);
   1.161 +
   1.162 +// Convert an offset from an Elf header into a pointer to the mapped
   1.163 +// address in the current process. Takes an extra template parameter
   1.164 +// to specify the return type to avoid having to dynamic_cast the
   1.165 +// result.
   1.166 +template<typename ElfClass, typename T>
   1.167 +const T*
   1.168 +GetOffset(const typename ElfClass::Ehdr* elf_header,
   1.169 +          typename ElfClass::Off offset);
   1.170 +
   1.171 +
   1.172 +// (derived from)
   1.173 +// file_id.h: Return a unique identifier for a file
   1.174 +//
   1.175 +
   1.176 +static const size_t kMDGUIDSize = sizeof(MDGUID);
   1.177 +
   1.178 +class FileID {
   1.179 + public:
   1.180 +
   1.181 +  // Load the identifier for the elf file mapped into memory at |base| into
   1.182 +  // |identifier|.  Return false if the identifier could not be created for the
   1.183 +  // file.
   1.184 +  static bool ElfFileIdentifierFromMappedFile(const void* base,
   1.185 +                                              uint8_t identifier[kMDGUIDSize]);
   1.186 +
   1.187 +  // Convert the |identifier| data to a NULL terminated string.  The string will
   1.188 +  // be formatted as a UUID (e.g., 22F065BB-FC9C-49F7-80FE-26A7CEBD7BCE).
   1.189 +  // The |buffer| should be at least 37 bytes long to receive all of the data
   1.190 +  // and termination.  Shorter buffers will contain truncated data.
   1.191 +  static void ConvertIdentifierToString(const uint8_t identifier[kMDGUIDSize],
   1.192 +                                        char* buffer, int buffer_length);
   1.193 +};
   1.194 +
   1.195 +
   1.196 +
   1.197 +template<typename ElfClass, typename T>
   1.198 +const T* GetOffset(const typename ElfClass::Ehdr* elf_header,
   1.199 +                   typename ElfClass::Off offset) {
   1.200 +  return reinterpret_cast<const T*>(reinterpret_cast<uintptr_t>(elf_header) +
   1.201 +                                    offset);
   1.202 +}
   1.203 +
   1.204 +template<typename ElfClass>
   1.205 +const typename ElfClass::Shdr* FindElfSectionByName(
   1.206 +    const char* name,
   1.207 +    typename ElfClass::Word section_type,
   1.208 +    const typename ElfClass::Shdr* sections,
   1.209 +    const char* section_names,
   1.210 +    const char* names_end,
   1.211 +    int nsection) {
   1.212 +  MOZ_ASSERT(name != NULL);
   1.213 +  MOZ_ASSERT(sections != NULL);
   1.214 +  MOZ_ASSERT(nsection > 0);
   1.215 +
   1.216 +  int name_len = strlen(name);
   1.217 +  if (name_len == 0)
   1.218 +    return NULL;
   1.219 +
   1.220 +  for (int i = 0; i < nsection; ++i) {
   1.221 +    const char* section_name = section_names + sections[i].sh_name;
   1.222 +    if (sections[i].sh_type == section_type &&
   1.223 +        names_end - section_name >= name_len + 1 &&
   1.224 +        strcmp(name, section_name) == 0) {
   1.225 +      return sections + i;
   1.226 +    }
   1.227 +  }
   1.228 +  return NULL;
   1.229 +}
   1.230 +
   1.231 +} // namespace lul
   1.232 +
   1.233 +
   1.234 +// And finally, the external interface, offered to LulMain.cpp
   1.235 +#include "LulElfExt.h"
   1.236 +
   1.237 +#endif // LulElfInt_h

mercurial