~ubuntu-branches/ubuntu/trusty/tomahawk/trusty-proposed

« back to all changes in this revision

Viewing changes to thirdparty/breakpad/common/linux/elf_core_dump.cc

  • Committer: Package Import Robot
  • Author(s): Harald Sitter
  • Date: 2013-03-07 21:50:13 UTC
  • Revision ID: package-import@ubuntu.com-20130307215013-6gdjkdds7i9uenvs
Tags: upstream-0.6.0+dfsg
ImportĀ upstreamĀ versionĀ 0.6.0+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2011, Google Inc.
 
2
// All rights reserved.
 
3
//
 
4
// Redistribution and use in source and binary forms, with or without
 
5
// modification, are permitted provided that the following conditions are
 
6
// met:
 
7
//
 
8
//     * Redistributions of source code must retain the above copyright
 
9
// notice, this list of conditions and the following disclaimer.
 
10
//     * Redistributions in binary form must reproduce the above
 
11
// copyright notice, this list of conditions and the following disclaimer
 
12
// in the documentation and/or other materials provided with the
 
13
// distribution.
 
14
//     * Neither the name of Google Inc. nor the names of its
 
15
// contributors may be used to endorse or promote products derived from
 
16
// this software without specific prior written permission.
 
17
//
 
18
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
19
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
20
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
21
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
22
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
23
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
24
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
25
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
26
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
27
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
28
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
 
 
30
// elf_core_dump.cc: Implement google_breakpad::ElfCoreDump.
 
31
// See elf_core_dump.h for details.
 
32
 
 
33
#include "common/linux/elf_core_dump.h"
 
34
 
 
35
#include <stddef.h>
 
36
#include <string.h>
 
37
 
 
38
namespace google_breakpad {
 
39
 
 
40
// Implementation of ElfCoreDump::Note.
 
41
 
 
42
ElfCoreDump::Note::Note() {}
 
43
 
 
44
ElfCoreDump::Note::Note(const MemoryRange& content) : content_(content) {}
 
45
 
 
46
bool ElfCoreDump::Note::IsValid() const {
 
47
  return GetHeader() != NULL;
 
48
}
 
49
 
 
50
const ElfCoreDump::Nhdr* ElfCoreDump::Note::GetHeader() const {
 
51
  return content_.GetData<Nhdr>(0);
 
52
}
 
53
 
 
54
ElfCoreDump::Word ElfCoreDump::Note::GetType() const {
 
55
  const Nhdr* header = GetHeader();
 
56
  // 0 is not being used as a NOTE type.
 
57
  return header ? header->n_type : 0;
 
58
}
 
59
 
 
60
MemoryRange ElfCoreDump::Note::GetName() const {
 
61
  const Nhdr* header = GetHeader();
 
62
  if (header) {
 
63
      return content_.Subrange(sizeof(Nhdr), header->n_namesz);
 
64
  }
 
65
  return MemoryRange();
 
66
}
 
67
 
 
68
MemoryRange ElfCoreDump::Note::GetDescription() const {
 
69
  const Nhdr* header = GetHeader();
 
70
  if (header) {
 
71
    return content_.Subrange(AlignedSize(sizeof(Nhdr) + header->n_namesz),
 
72
                             header->n_descsz);
 
73
  }
 
74
  return MemoryRange();
 
75
}
 
76
 
 
77
ElfCoreDump::Note ElfCoreDump::Note::GetNextNote() const {
 
78
  MemoryRange next_content;
 
79
  const Nhdr* header = GetHeader();
 
80
  if (header) {
 
81
    size_t next_offset = AlignedSize(sizeof(Nhdr) + header->n_namesz);
 
82
    next_offset = AlignedSize(next_offset + header->n_descsz);
 
83
    next_content =
 
84
        content_.Subrange(next_offset, content_.length() - next_offset);
 
85
  }
 
86
  return Note(next_content);
 
87
}
 
88
 
 
89
// static
 
90
size_t ElfCoreDump::Note::AlignedSize(size_t size) {
 
91
  size_t mask = sizeof(Word) - 1;
 
92
  return (size + mask) & ~mask;
 
93
}
 
94
 
 
95
 
 
96
// Implementation of ElfCoreDump.
 
97
 
 
98
ElfCoreDump::ElfCoreDump() {}
 
99
 
 
100
ElfCoreDump::ElfCoreDump(const MemoryRange& content)
 
101
    : content_(content) {
 
102
}
 
103
 
 
104
void ElfCoreDump::SetContent(const MemoryRange& content) {
 
105
  content_ = content;
 
106
}
 
107
 
 
108
bool ElfCoreDump::IsValid() const {
 
109
  const Ehdr* header = GetHeader();
 
110
  return (header &&
 
111
          header->e_ident[0] == ELFMAG0 &&
 
112
          header->e_ident[1] == ELFMAG1 &&
 
113
          header->e_ident[2] == ELFMAG2 &&
 
114
          header->e_ident[3] == ELFMAG3 &&
 
115
          header->e_ident[4] == kClass &&
 
116
          header->e_version == EV_CURRENT &&
 
117
          header->e_type == ET_CORE);
 
118
}
 
119
 
 
120
const ElfCoreDump::Ehdr* ElfCoreDump::GetHeader() const {
 
121
  return content_.GetData<Ehdr>(0);
 
122
}
 
123
 
 
124
const ElfCoreDump::Phdr* ElfCoreDump::GetProgramHeader(unsigned index) const {
 
125
  const Ehdr* header = GetHeader();
 
126
  if (header) {
 
127
    return reinterpret_cast<const Phdr*>(content_.GetArrayElement(
 
128
        header->e_phoff, header->e_phentsize, index));
 
129
  }
 
130
  return NULL;
 
131
}
 
132
 
 
133
const ElfCoreDump::Phdr* ElfCoreDump::GetFirstProgramHeaderOfType(
 
134
    Word type) const {
 
135
  for (unsigned i = 0, n = GetProgramHeaderCount(); i < n; ++i) {
 
136
    const Phdr* program = GetProgramHeader(i);
 
137
    if (program->p_type == type) {
 
138
      return program;
 
139
    }
 
140
  }
 
141
  return NULL;
 
142
}
 
143
 
 
144
unsigned ElfCoreDump::GetProgramHeaderCount() const {
 
145
  const Ehdr* header = GetHeader();
 
146
  return header ? header->e_phnum : 0;
 
147
}
 
148
 
 
149
bool ElfCoreDump::CopyData(void* buffer, Addr virtual_address, size_t length) {
 
150
  for (unsigned i = 0, n = GetProgramHeaderCount(); i < n; ++i) {
 
151
    const Phdr* program = GetProgramHeader(i);
 
152
    if (program->p_type != PT_LOAD)
 
153
      continue;
 
154
 
 
155
    size_t offset_in_segment = virtual_address - program->p_vaddr;
 
156
    if (virtual_address >= program->p_vaddr &&
 
157
        offset_in_segment < program->p_filesz) {
 
158
      const void* data =
 
159
          content_.GetData(program->p_offset + offset_in_segment, length);
 
160
      if (data) {
 
161
        memcpy(buffer, data, length);
 
162
        return true;
 
163
      }
 
164
    }
 
165
  }
 
166
  return false;
 
167
}
 
168
 
 
169
ElfCoreDump::Note ElfCoreDump::GetFirstNote() const {
 
170
  MemoryRange note_content;
 
171
  const Phdr* program_header = GetFirstProgramHeaderOfType(PT_NOTE);
 
172
  if (program_header) {
 
173
    note_content = content_.Subrange(program_header->p_offset,
 
174
                                     program_header->p_filesz);
 
175
  }
 
176
  return Note(note_content);
 
177
}
 
178
 
 
179
}  // namespace google_breakpad