OLD | NEW |
1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 1774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1785 } else { | 1785 } else { |
1786 // Zero-length data symbols act as 'forward declares' in some sense. They | 1786 // Zero-length data symbols act as 'forward declares' in some sense. They |
1787 // are always followed by a non-zero length data symbol with the same name | 1787 // are always followed by a non-zero length data symbol with the same name |
1788 // and location. | 1788 // and location. |
1789 return DiaBrowser::kBrowserTerminatePath; | 1789 return DiaBrowser::kBrowserTerminatePath; |
1790 } | 1790 } |
1791 } | 1791 } |
1792 | 1792 |
1793 // Verify that the data symbol does not exceed the size of the block. | 1793 // Verify that the data symbol does not exceed the size of the block. |
1794 if (addr + length > block_addr + block->size()) { | 1794 if (addr + length > block_addr + block->size()) { |
| 1795 base::StringPiece spname(name); |
1795 // The data symbol can exceed the size of the block in the case of data | 1796 // The data symbol can exceed the size of the block in the case of data |
1796 // imports. For some reason the toolchain emits a global data symbol with | 1797 // imports. For some reason the toolchain emits a global data symbol with |
1797 // type information equal to the type of the data *pointed* to by the import | 1798 // type information equal to the type of the data *pointed* to by the import |
1798 // entry rather than the type of the entry itself. Thus, if the data type | 1799 // entry rather than the type of the entry itself. Thus, if the data type |
1799 // is bigger than the entire IAT this symbol will exceed it. To complicate | 1800 // is bigger than the entire IAT this symbol will exceed it. To complicate |
1800 // matters even more, a poorly written module can import its own export in | 1801 // matters even more, a poorly written module can import its own export in |
1801 // which case a linker generated pseudo-import-entry block will be | 1802 // which case a linker generated pseudo-import-entry block will be |
1802 // generated. This won't be part of the IAT, so we can't even filter based | 1803 // generated. This won't be part of the IAT, so we can't even filter based |
1803 // on that. Instead, we simply ignore global data symbols that exceed the | 1804 // on that. Instead, we simply ignore global data symbols that exceed the |
1804 // block size. | 1805 // block size. |
1805 base::StringPiece spname(name); | 1806 bool is_imported_data_symbol = (sym_tags.size() == 1 && |
1806 if (sym_tags.size() == 1 && spname.starts_with("_imp_")) { | 1807 spname.starts_with("_imp_")); |
| 1808 // In VS2017 we've noticed that the size returned by IDiaSymbol::get_length |
| 1809 // function is invalid for the objects using RTTI in VS2017. This has been |
| 1810 // reported here: |
| 1811 // https://developercommunity.visualstudio.com/content/problem/47386/invalid
-symbols-when-using-rtti.html |
| 1812 // |
| 1813 // In this situation the data symbol that we get always starts 4 bytes after |
| 1814 // the beginning of its parent block and has an identical size. |
| 1815 bool is_vtable_symbol = spname.ends_with("::`vftable'") && |
| 1816 (addr - block_addr == 4) && |
| 1817 length == block->size(); |
| 1818 if (is_imported_data_symbol) { |
1807 VLOG(1) << "Encountered an imported data symbol \"" << name << "\" that " | 1819 VLOG(1) << "Encountered an imported data symbol \"" << name << "\" that " |
1808 << "extends past its parent block \"" << block->name() << "\"."; | 1820 << "extends past its parent block \"" << block->name() << "\"."; |
| 1821 } else if (is_vtable_symbol) { |
| 1822 VLOG(1) << "Encountered a vtable data symbol \"" << name << "\" that " |
| 1823 << "extends past its parent block \"" << block->name() << "\"."; |
1809 } else { | 1824 } else { |
1810 LOG(ERROR) << "Received data symbol \"" << name << "\" that extends past " | 1825 LOG(ERROR) << "Received data symbol \"" << name << "\" that extends past " |
1811 << "its parent block \"" << block->name() << "\"."; | 1826 << "its parent block \"" << block->name() << "\"."; |
1812 return DiaBrowser::kBrowserAbort; | 1827 return DiaBrowser::kBrowserAbort; |
1813 } | 1828 } |
1814 } | 1829 } |
1815 | 1830 |
1816 if (!AddLabelToBlock(offset, name, attr, block)) | 1831 if (!AddLabelToBlock(offset, name, attr, block)) |
1817 return DiaBrowser::kBrowserAbort; | 1832 return DiaBrowser::kBrowserAbort; |
1818 | 1833 |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2201 block_type, block_end, next->first.start() - block_end)) { | 2216 block_type, block_end, next->first.start() - block_end)) { |
2202 return false; | 2217 return false; |
2203 } | 2218 } |
2204 } | 2219 } |
2205 } | 2220 } |
2206 | 2221 |
2207 return true; | 2222 return true; |
2208 } | 2223 } |
2209 | 2224 |
2210 } // namespace pe | 2225 } // namespace pe |
OLD | NEW |