Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: obsolete/breakpad/common/stabs_reader.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2010 Google Inc. All Rights Reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 // * Neither the name of Google Inc. nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
30
31 // This file implements the google_breakpad::StabsReader class.
32 // See stabs_reader.h.
33
34 #include <a.out.h>
35 #include <stab.h>
36 #include <cstring>
37 #include <cassert>
38
39 #include "common/stabs_reader.h"
40
41 namespace google_breakpad {
42
43 StabsReader::StabsReader(const uint8_t *stab, size_t stab_size,
44 const uint8_t *stabstr, size_t stabstr_size,
45 StabsHandler *handler) :
46 stabstr_(stabstr),
47 stabstr_size_(stabstr_size),
48 handler_(handler),
49 string_offset_(0),
50 next_cu_string_offset_(0),
51 symbol_(NULL),
52 current_source_file_(NULL) {
53 symbols_ = reinterpret_cast<const struct nlist *>(stab);
54 symbols_end_ = symbols_ + (stab_size / sizeof (*symbols_));
55 }
56
57 const char *StabsReader::SymbolString() {
58 ptrdiff_t offset = string_offset_ + symbol_->n_un.n_strx;
59 if (offset < 0 || (size_t) offset >= stabstr_size_) {
60 handler_->Warning("symbol %d: name offset outside the string section\n",
61 symbol_ - symbols_);
62 // Return our null string, to keep our promise about all names being
63 // taken from the string section.
64 offset = 0;
65 }
66 return reinterpret_cast<const char *>(stabstr_ + offset);
67 }
68
69 bool StabsReader::Process() {
70 symbol_ = symbols_;
71 while (symbol_ < symbols_end_) {
72 if (symbol_->n_type == N_SO) {
73 if (! ProcessCompilationUnit())
74 return false;
75 } else if (symbol_->n_type == N_UNDF) {
76 // At the head of each compilation unit's entries there is an
77 // N_UNDF stab giving the number of symbols in the compilation
78 // unit, and the number of bytes that compilation unit's strings
79 // take up in the .stabstr section. Each CU's strings are
80 // separate; the n_strx values are offsets within the current
81 // CU's portion of the .stabstr section.
82 //
83 // As an optimization, the GNU linker combines all the
84 // compilation units into one, with a single N_UNDF at the
85 // beginning. However, other linkers, like Gold, do not perform
86 // this optimization.
87 string_offset_ = next_cu_string_offset_;
88 next_cu_string_offset_ = SymbolValue();
89 symbol_++;
90 } else
91 symbol_++;
92 }
93 return true;
94 }
95
96 bool StabsReader::ProcessCompilationUnit() {
97 assert(symbol_ < symbols_end_ && symbol_->n_type == N_SO);
98
99 // There may be an N_SO entry whose name ends with a slash,
100 // indicating the directory in which the compilation occurred.
101 // The build directory defaults to NULL.
102 const char *build_directory = NULL;
103 {
104 const char *name = SymbolString();
105 if (name[0] && name[strlen(name) - 1] == '/') {
106 build_directory = name;
107 symbol_++;
108 }
109 }
110
111 // We expect to see an N_SO entry with a filename next, indicating
112 // the start of the compilation unit.
113 {
114 if (symbol_ >= symbols_end_ || symbol_->n_type != N_SO)
115 return true;
116 const char *name = SymbolString();
117 if (name[0] == '\0') {
118 // This seems to be a stray end-of-compilation-unit marker;
119 // consume it, but don't report the end, since we didn't see a
120 // beginning.
121 symbol_++;
122 return true;
123 }
124 current_source_file_ = name;
125 }
126
127 if (! handler_->StartCompilationUnit(current_source_file_,
128 SymbolValue(),
129 build_directory))
130 return false;
131
132 symbol_++;
133
134 // The STABS documentation says that some compilers may emit
135 // additional N_SO entries with names immediately following the
136 // first, and that they should be ignored. However, the original
137 // Breakpad STABS reader doesn't ignore them, so we won't either.
138
139 // Process the body of the compilation unit, up to the next N_SO.
140 while (symbol_ < symbols_end_ && symbol_->n_type != N_SO) {
141 if (symbol_->n_type == N_FUN) {
142 if (! ProcessFunction())
143 return false;
144 } else
145 // Ignore anything else.
146 symbol_++;
147 }
148
149 // An N_SO with an empty name indicates the end of the compilation
150 // unit. Default to zero.
151 uint64_t ending_address = 0;
152 if (symbol_ < symbols_end_) {
153 assert(symbol_->n_type == N_SO);
154 const char *name = SymbolString();
155 if (name[0] == '\0') {
156 ending_address = SymbolValue();
157 symbol_++;
158 }
159 }
160
161 if (! handler_->EndCompilationUnit(ending_address))
162 return false;
163
164 return true;
165 }
166
167 bool StabsReader::ProcessFunction() {
168 assert(symbol_ < symbols_end_ && symbol_->n_type == N_FUN);
169
170 uint64_t function_address = SymbolValue();
171 // The STABS string for an N_FUN entry is the name of the function,
172 // followed by a colon, followed by type information for the
173 // function. We want to pass the name alone to StartFunction.
174 const char *stab_string = SymbolString();
175 const char *name_end = strchr(stab_string, ':');
176 if (! name_end)
177 name_end = stab_string + strlen(stab_string);
178 std::string name(stab_string, name_end - stab_string);
179 if (! handler_->StartFunction(name, function_address))
180 return false;
181 symbol_++;
182
183 while (symbol_ < symbols_end_) {
184 if (symbol_->n_type == N_SO || symbol_->n_type == N_FUN)
185 break;
186 else if (symbol_->n_type == N_SLINE) {
187 // The value of an N_SLINE entry is the offset of the line from
188 // the function's start address.
189 uint64_t line_address = function_address + SymbolValue();
190 // The n_desc of a N_SLINE entry is the line number. It's a
191 // signed 16-bit field; line numbers from 32768 to 65535 are
192 // stored as n-65536.
193 uint16_t line_number = symbol_->n_desc;
194 if (! handler_->Line(line_address, current_source_file_, line_number))
195 return false;
196 symbol_++;
197 } else if (symbol_->n_type == N_SOL) {
198 current_source_file_ = SymbolString();
199 symbol_++;
200 } else
201 // Ignore anything else.
202 symbol_++;
203 }
204
205 // If there is a subsequent N_SO or N_FUN entry, its address is our
206 // end address.
207 uint64_t ending_address = 0;
208 if (symbol_ < symbols_end_) {
209 assert(symbol_->n_type == N_SO || symbol_->n_type == N_FUN);
210 ending_address = SymbolValue();
211 // Note: we do not increment symbol_ here, since we haven't consumed it.
212 }
213
214 if (! handler_->EndFunction(ending_address))
215 return false;
216
217 return true;
218 }
219
220 } // namespace google_breakpad
OLDNEW
« no previous file with comments | « obsolete/breakpad/common/stabs_reader.h ('k') | obsolete/breakpad/common/stabs_reader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698