mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-30 01:00:13 +02:00
* Added breakpad support for Linux.
This commit is contained in:
313
thirdparty/breakpad/client/mac/handler/dynamic_images.h
vendored
Normal file
313
thirdparty/breakpad/client/mac/handler/dynamic_images.h
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
// Copyright (c) 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// dynamic_images.h
|
||||
//
|
||||
// Implements most of the function of the dyld API, but allowing an
|
||||
// arbitrary task to be introspected, unlike the dyld API which
|
||||
// only allows operation on the current task. The current implementation
|
||||
// is limited to use by 32-bit tasks.
|
||||
|
||||
#ifndef CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__
|
||||
#define CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
//==============================================================================
|
||||
// The memory layout of this struct matches the dyld_image_info struct
|
||||
// defined in "dyld_gdb.h" in the darwin source.
|
||||
typedef struct dyld_image_info32 {
|
||||
uint32_t load_address_; // struct mach_header*
|
||||
uint32_t file_path_; // char*
|
||||
uint32_t file_mod_date_;
|
||||
} dyld_image_info32;
|
||||
|
||||
typedef struct dyld_image_info64 {
|
||||
uint64_t load_address_; // struct mach_header*
|
||||
uint64_t file_path_; // char*
|
||||
uint64_t file_mod_date_;
|
||||
} dyld_image_info64;
|
||||
|
||||
//==============================================================================
|
||||
// This is as defined in "dyld_gdb.h" in the darwin source.
|
||||
// _dyld_all_image_infos (in dyld) is a structure of this type
|
||||
// which will be used to determine which dynamic code has been loaded.
|
||||
typedef struct dyld_all_image_infos32 {
|
||||
uint32_t version; // == 1 in Mac OS X 10.4
|
||||
uint32_t infoArrayCount;
|
||||
uint32_t infoArray; // const struct dyld_image_info*
|
||||
uint32_t notification;
|
||||
bool processDetachedFromSharedRegion;
|
||||
} dyld_all_image_infos32;
|
||||
|
||||
typedef struct dyld_all_image_infos64 {
|
||||
uint32_t version; // == 1 in Mac OS X 10.4
|
||||
uint32_t infoArrayCount;
|
||||
uint64_t infoArray; // const struct dyld_image_info*
|
||||
uint64_t notification;
|
||||
bool processDetachedFromSharedRegion;
|
||||
} dyld_all_image_infos64;
|
||||
|
||||
// some typedefs to isolate 64/32 bit differences
|
||||
#ifdef __LP64__
|
||||
typedef mach_header_64 breakpad_mach_header;
|
||||
typedef segment_command_64 breakpad_mach_segment_command;
|
||||
#else
|
||||
typedef mach_header breakpad_mach_header;
|
||||
typedef segment_command breakpad_mach_segment_command;
|
||||
#endif
|
||||
|
||||
// Helper functions to deal with 32-bit/64-bit Mach-O differences.
|
||||
class DynamicImage;
|
||||
template<typename MachBits>
|
||||
bool FindTextSection(DynamicImage& image);
|
||||
|
||||
template<typename MachBits>
|
||||
uint32_t GetFileTypeFromHeader(DynamicImage& image);
|
||||
|
||||
//==============================================================================
|
||||
// Represents a single dynamically loaded mach-o image
|
||||
class DynamicImage {
|
||||
public:
|
||||
DynamicImage(uint8_t *header, // data is copied
|
||||
size_t header_size, // includes load commands
|
||||
uint64_t load_address,
|
||||
string file_path,
|
||||
uintptr_t image_mod_date,
|
||||
mach_port_t task,
|
||||
cpu_type_t cpu_type)
|
||||
: header_(header, header + header_size),
|
||||
header_size_(header_size),
|
||||
load_address_(load_address),
|
||||
vmaddr_(0),
|
||||
vmsize_(0),
|
||||
slide_(0),
|
||||
version_(0),
|
||||
file_path_(file_path),
|
||||
file_mod_date_(image_mod_date),
|
||||
task_(task),
|
||||
cpu_type_(cpu_type) {
|
||||
CalculateMemoryAndVersionInfo();
|
||||
}
|
||||
|
||||
// Size of mach_header plus load commands
|
||||
size_t GetHeaderSize() const {return header_.size();}
|
||||
|
||||
// Full path to mach-o binary
|
||||
string GetFilePath() {return file_path_;}
|
||||
|
||||
uint64_t GetModDate() const {return file_mod_date_;}
|
||||
|
||||
// Actual address where the image was loaded
|
||||
uint64_t GetLoadAddress() const {return load_address_;}
|
||||
|
||||
// Address where the image should be loaded
|
||||
mach_vm_address_t GetVMAddr() const {return vmaddr_;}
|
||||
|
||||
// Difference between GetLoadAddress() and GetVMAddr()
|
||||
ptrdiff_t GetVMAddrSlide() const {return slide_;}
|
||||
|
||||
// Size of the image
|
||||
mach_vm_size_t GetVMSize() const {return vmsize_;}
|
||||
|
||||
// Task owning this loaded image
|
||||
mach_port_t GetTask() {return task_;}
|
||||
|
||||
// CPU type of the task
|
||||
cpu_type_t GetCPUType() {return cpu_type_;}
|
||||
|
||||
// filetype from the Mach-O header.
|
||||
uint32_t GetFileType();
|
||||
|
||||
// Return true if the task is a 64-bit architecture.
|
||||
bool Is64Bit() { return (GetCPUType() & CPU_ARCH_ABI64) == CPU_ARCH_ABI64; }
|
||||
|
||||
uint32_t GetVersion() {return version_;}
|
||||
// For sorting
|
||||
bool operator<(const DynamicImage &inInfo) {
|
||||
return GetLoadAddress() < inInfo.GetLoadAddress();
|
||||
}
|
||||
|
||||
// Sanity checking
|
||||
bool IsValid() {return GetVMSize() != 0;}
|
||||
|
||||
private:
|
||||
DynamicImage(const DynamicImage &);
|
||||
DynamicImage &operator=(const DynamicImage &);
|
||||
|
||||
friend class DynamicImages;
|
||||
template<typename MachBits>
|
||||
friend bool FindTextSection(DynamicImage& image);
|
||||
template<typename MachBits>
|
||||
friend uint32_t GetFileTypeFromHeader(DynamicImage& image);
|
||||
|
||||
// Initializes vmaddr_, vmsize_, and slide_
|
||||
void CalculateMemoryAndVersionInfo();
|
||||
|
||||
const vector<uint8_t> header_; // our local copy of the header
|
||||
size_t header_size_; // mach_header plus load commands
|
||||
uint64_t load_address_; // base address image is mapped into
|
||||
mach_vm_address_t vmaddr_;
|
||||
mach_vm_size_t vmsize_;
|
||||
ptrdiff_t slide_;
|
||||
uint32_t version_; // Dylib version
|
||||
string file_path_; // path dyld used to load the image
|
||||
uintptr_t file_mod_date_; // time_t of image file
|
||||
|
||||
mach_port_t task_;
|
||||
cpu_type_t cpu_type_; // CPU type of task_
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// DynamicImageRef is just a simple wrapper for a pointer to
|
||||
// DynamicImage. The reason we use it instead of a simple typedef is so
|
||||
// that we can use stl::sort() on a vector of DynamicImageRefs
|
||||
// and simple class pointers can't implement operator<().
|
||||
//
|
||||
class DynamicImageRef {
|
||||
public:
|
||||
explicit DynamicImageRef(DynamicImage *inP) : p(inP) {}
|
||||
// The copy constructor is required by STL
|
||||
DynamicImageRef(const DynamicImageRef &inRef) : p(inRef.p) {}
|
||||
|
||||
bool operator<(const DynamicImageRef &inRef) const {
|
||||
return (*const_cast<DynamicImageRef*>(this)->p)
|
||||
< (*const_cast<DynamicImageRef&>(inRef).p);
|
||||
}
|
||||
|
||||
bool operator==(const DynamicImageRef &inInfo) const {
|
||||
return (*const_cast<DynamicImageRef*>(this)->p).GetLoadAddress() ==
|
||||
(*const_cast<DynamicImageRef&>(inInfo)).GetLoadAddress();
|
||||
}
|
||||
|
||||
// Be just like DynamicImage*
|
||||
DynamicImage *operator->() {return p;}
|
||||
operator DynamicImage*() {return p;}
|
||||
|
||||
private:
|
||||
DynamicImage *p;
|
||||
};
|
||||
|
||||
// Helper function to deal with 32-bit/64-bit Mach-O differences.
|
||||
class DynamicImages;
|
||||
template<typename MachBits>
|
||||
void ReadImageInfo(DynamicImages& images, uint64_t image_list_address);
|
||||
|
||||
//==============================================================================
|
||||
// An object of type DynamicImages may be created to allow introspection of
|
||||
// an arbitrary task's dynamically loaded mach-o binaries. This makes the
|
||||
// assumption that the current task has send rights to the target task.
|
||||
class DynamicImages {
|
||||
public:
|
||||
explicit DynamicImages(mach_port_t task);
|
||||
|
||||
~DynamicImages() {
|
||||
for (int i = 0; i < GetImageCount(); ++i) {
|
||||
delete image_list_[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the number of dynamically loaded mach-o images.
|
||||
int GetImageCount() const {return static_cast<int>(image_list_.size());}
|
||||
|
||||
// Returns an individual image.
|
||||
DynamicImage *GetImage(int i) {
|
||||
if (i < (int)image_list_.size()) {
|
||||
return image_list_[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Returns the image corresponding to the main executable.
|
||||
DynamicImage *GetExecutableImage();
|
||||
int GetExecutableImageIndex();
|
||||
|
||||
// Returns the task which we're looking at.
|
||||
mach_port_t GetTask() const {return task_;}
|
||||
|
||||
// CPU type of the task
|
||||
cpu_type_t GetCPUType() {return cpu_type_;}
|
||||
|
||||
// Return true if the task is a 64-bit architecture.
|
||||
bool Is64Bit() { return (GetCPUType() & CPU_ARCH_ABI64) == CPU_ARCH_ABI64; }
|
||||
|
||||
// Determine the CPU type of the task being dumped.
|
||||
static cpu_type_t DetermineTaskCPUType(task_t task);
|
||||
|
||||
// Get the native CPU type of this task.
|
||||
static cpu_type_t GetNativeCPUType() {
|
||||
#if defined(__i386__)
|
||||
return CPU_TYPE_I386;
|
||||
#elif defined(__x86_64__)
|
||||
return CPU_TYPE_X86_64;
|
||||
#elif defined(__ppc__)
|
||||
return CPU_TYPE_POWERPC;
|
||||
#elif defined(__ppc64__)
|
||||
return CPU_TYPE_POWERPC64;
|
||||
#else
|
||||
#error "GetNativeCPUType not implemented for this architecture"
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename MachBits>
|
||||
friend void ReadImageInfo(DynamicImages& images, uint64_t image_list_address);
|
||||
|
||||
bool IsOurTask() {return task_ == mach_task_self();}
|
||||
|
||||
// Initialization
|
||||
void ReadImageInfoForTask();
|
||||
uint64_t GetDyldAllImageInfosPointer();
|
||||
|
||||
mach_port_t task_;
|
||||
cpu_type_t cpu_type_; // CPU type of task_
|
||||
vector<DynamicImageRef> image_list_;
|
||||
};
|
||||
|
||||
// Fill bytes with the contents of memory at a particular
|
||||
// location in another task.
|
||||
kern_return_t ReadTaskMemory(task_port_t target_task,
|
||||
const uint64_t address,
|
||||
size_t length,
|
||||
vector<uint8_t> &bytes);
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__
|
Reference in New Issue
Block a user