1 : // Copyright (c) 2010 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 : // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
31 :
32 : // dwarf_line_to_module.cc: Implementation of DwarfLineToModule class.
33 : // See dwarf_line_to_module.h for details.
34 :
35 : #include "common/dwarf_line_to_module.h"
36 :
37 : // Trying to support Windows paths in a reasonable way adds a lot of
38 : // variations to test; it would be better to just put off dealing with
39 : // it until we actually have to deal with DWARF on Windows.
40 :
41 : // Return true if PATH is an absolute path, false if it is relative.
42 352727 : static bool PathIsAbsolute(const string &path) {
43 352727 : return (path.size() >= 1 && path[0] == '/');
44 : }
45 :
46 : // If PATH is an absolute path, return PATH. If PATH is a relative path,
47 : // treat it as relative to BASE and return the combined path.
48 352727 : static string ExpandPath(const string &path, const string &base) {
49 352727 : if (PathIsAbsolute(path))
50 0 : return path;
51 352727 : return base + "/" + path;
52 : }
53 :
54 : namespace google_breakpad {
55 :
56 46276 : void DwarfLineToModule::DefineDir(const string &name, uint32 dir_num) {
57 : // Directory number zero is reserved to mean the compilation
58 : // directory. Silently ignore attempts to redefine it.
59 46276 : if (dir_num != 0)
60 46276 : directories_[dir_num] = name;
61 46276 : }
62 :
63 357415 : void DwarfLineToModule::DefineFile(const string &name, int32 file_num,
64 : uint32 dir_num, uint64 mod_time,
65 : uint64 length) {
66 357415 : if (file_num == -1)
67 0 : file_num = ++highest_file_number_;
68 357415 : else if (file_num > highest_file_number_)
69 357415 : highest_file_number_ = file_num;
70 :
71 714830 : std::string full_name;
72 357415 : if (dir_num != 0) {
73 352727 : DirectoryTable::const_iterator directory_it = directories_.find(dir_num);
74 352727 : if (directory_it != directories_.end()) {
75 352727 : full_name = ExpandPath(name, directory_it->second);
76 : } else {
77 0 : if (!warned_bad_directory_number_) {
78 : fprintf(stderr, "warning: DWARF line number data refers to undefined"
79 0 : " directory numbers\n");
80 0 : warned_bad_directory_number_ = true;
81 : }
82 0 : full_name = name; // just treat name as relative
83 : }
84 : } else {
85 : // Directory number zero is the compilation directory; we just report
86 : // relative paths in that case.
87 4688 : full_name = name;
88 : }
89 :
90 : // Find a Module::File object of the given name, and add it to the
91 : // file table.
92 357415 : files_[file_num] = module_->FindFile(full_name);
93 357415 : }
94 :
95 4084034 : void DwarfLineToModule::AddLine(uint64 address, uint64 length,
96 : uint32 file_num, uint32 line_num,
97 : uint32 column_num) {
98 4084034 : if (length == 0)
99 0 : return;
100 :
101 : // Clip lines not to extend beyond the end of the address space.
102 4084034 : if (address + length < address)
103 0 : length = -address;
104 :
105 : // Should we omit this line? (See the comments for omitted_line_end_.)
106 4084034 : if (address == 0 || address == omitted_line_end_) {
107 6596 : omitted_line_end_ = address + length;
108 6596 : return;
109 : } else {
110 4077438 : omitted_line_end_ = 0;
111 : }
112 :
113 : // Find the source file being referred to.
114 4077438 : Module::File *file = files_[file_num];
115 4077438 : if (!file) {
116 0 : if (!warned_bad_file_number_) {
117 : fprintf(stderr, "warning: DWARF line number data refers to "
118 0 : "undefined file numbers\n");
119 0 : warned_bad_file_number_ = true;
120 : }
121 0 : return;
122 : }
123 : Module::Line line;
124 4077438 : line.address = address;
125 : // We set the size when we get the next line or the EndSequence call.
126 4077438 : line.size = length;
127 4077438 : line.file = file;
128 4077438 : line.number = line_num;
129 4077438 : lines_->push_back(line);
130 : }
131 :
132 : } // namespace google_breakpad
|