Planeshift

elfutils.h

Go to the documentation of this file.
00001 // Copyright (c) 2012, Google Inc.
00002 // All rights reserved.
00003 //
00004 // Redistribution and use in source and binary forms, with or without
00005 // modification, are permitted provided that the following conditions are
00006 // met:
00007 //
00008 //     * Redistributions of source code must retain the above copyright
00009 // notice, this list of conditions and the following disclaimer.
00010 //     * Redistributions in binary form must reproduce the above
00011 // copyright notice, this list of conditions and the following disclaimer
00012 // in the documentation and/or other materials provided with the
00013 // distribution.
00014 //     * Neither the name of Google Inc. nor the names of its
00015 // contributors may be used to endorse or promote products derived from
00016 // this software without specific prior written permission.
00017 //
00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00022 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00023 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00024 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 //
00030 // elfutils.h: Utilities for dealing with ELF files.
00031 //
00032 
00033 #ifndef COMMON_LINUX_ELFUTILS_H__
00034 #define COMMON_LINUX_ELFUTILS_H__
00035 
00036 #include <elf.h>
00037 #include <link.h>
00038 #include <stdint.h>
00039 
00040 namespace google_breakpad {
00041 
00042 // Traits classes so consumers can write templatized code to deal
00043 // with specific ELF bits.
00044 struct ElfClass32 {
00045   typedef Elf32_Addr Addr;
00046   typedef Elf32_Ehdr Ehdr;
00047   typedef Elf32_Nhdr Nhdr;
00048   typedef Elf32_Phdr Phdr;
00049   typedef Elf32_Shdr Shdr;
00050   typedef Elf32_Half Half;
00051   typedef Elf32_Off Off;
00052   typedef Elf32_Word Word;
00053   static const int kClass = ELFCLASS32;
00054   static const size_t kAddrSize = sizeof(Elf32_Addr);
00055 };
00056 
00057 struct ElfClass64 {
00058   typedef Elf64_Addr Addr;
00059   typedef Elf64_Ehdr Ehdr;
00060   typedef Elf64_Nhdr Nhdr;
00061   typedef Elf64_Phdr Phdr;
00062   typedef Elf64_Shdr Shdr;
00063   typedef Elf64_Half Half;
00064   typedef Elf64_Off Off;
00065   typedef Elf64_Word Word;
00066   static const int kClass = ELFCLASS64;
00067   static const size_t kAddrSize = sizeof(Elf64_Addr);
00068 };
00069 
00070 bool IsValidElf(const void* elf_header);
00071 int ElfClass(const void* elf_base);
00072 
00073 // Attempt to find a section named |section_name| of type |section_type|
00074 // in the ELF binary data at |elf_mapped_base|. On success, returns true
00075 // and sets |*section_start| to point to the start of the section data,
00076 // and |*section_size| to the size of the section's data. If |elfclass|
00077 // is not NULL, set |*elfclass| to the ELF file class.
00078 bool FindElfSection(const void *elf_mapped_base,
00079                     const char *section_name,
00080                     uint32_t section_type,
00081                     const void **section_start,
00082                     int *section_size,
00083                     int *elfclass);
00084 
00085 // Internal helper method, exposed for convenience for callers
00086 // that already have more info.
00087 template<typename ElfClass>
00088 const typename ElfClass::Shdr*
00089 FindElfSectionByName(const char* name,
00090                      typename ElfClass::Word section_type,
00091                      const typename ElfClass::Shdr* sections,
00092                      const char* section_names,
00093                      const char* names_end,
00094                      int nsection);
00095 
00096 // Attempt to find the first segment of type |segment_type| in the ELF
00097 // binary data at |elf_mapped_base|. On success, returns true and sets
00098 // |*segment_start| to point to the start of the segment data, and
00099 // and |*segment_size| to the size of the segment's data. If |elfclass|
00100 // is not NULL, set |*elfclass| to the ELF file class.
00101 bool FindElfSegment(const void *elf_mapped_base,
00102                     uint32_t segment_type,
00103                     const void **segment_start,
00104                     int *segment_size,
00105                     int *elfclass);
00106 
00107 // Convert an offset from an Elf header into a pointer to the mapped
00108 // address in the current process. Takes an extra template parameter
00109 // to specify the return type to avoid having to dynamic_cast the
00110 // result.
00111 template<typename ElfClass, typename T>
00112 const T*
00113 GetOffset(const typename ElfClass::Ehdr* elf_header,
00114           typename ElfClass::Off offset);
00115 
00116 }  // namespace google_breakpad
00117 
00118 #endif  // COMMON_LINUX_ELFUTILS_H__