| /* |
| * Copyright (c) 2015, Intel Corporation |
| * Author: Andi Kleen |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * 2. 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. |
| * |
| * 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 HOLDER 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. |
| */ |
| |
| #include "symtab.h" |
| |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <unistd.h> |
| |
| #include "garnet/lib/debugger_utils/elf_reader.h" |
| #include "garnet/lib/debugger_utils/elf_symtab.h" |
| #include "garnet/lib/debugger_utils/util.h" |
| |
| #include "lib/fxl/logging.h" |
| |
| #include "third_party/processor-trace/libipt/include/intel-pt.h" |
| |
| namespace simple_pt { |
| |
| SymbolTable::SymbolTable(debugger_utils::ElfReader* reader, |
| const std::string& contents, |
| uint64_t cr3, |
| uint64_t base, |
| uint64_t offset, |
| bool is_kernel) |
| : debugger_utils::ElfSymbolTable(reader->file_name(), contents), |
| cr3_(cr3), |
| base_(base), |
| end_(0), |
| offset_(offset), |
| is_kernel_(is_kernel) {} |
| |
| const Symbol* SymbolTable::FindSymbol(uint64_t addr) const { |
| if (addr < base_ || addr >= end_) |
| return nullptr; |
| return debugger_utils::ElfSymbolTable::FindSymbol(addr - offset_); |
| } |
| |
| static bool Cr3Matches(uint64_t cr3_1, uint64_t cr3_2) { |
| // TODO(dje): Zero was used early on to mean "match everything". |
| // pt_asid_no_cr3 currently serves that purpose too. Both currently mean |
| // the same thing for backwards compatibility, but it may be useful to |
| // distinguish "match everything" vs "match nothing". |
| if (cr3_1 == 0 || cr3_2 == 0) |
| return true; |
| if (cr3_1 == pt_asid_no_cr3 || cr3_2 == pt_asid_no_cr3) |
| return true; |
| return cr3_1 == cr3_2; |
| } |
| |
| const SymbolTable* FindSymbolTable(const SymbolTableTable& symtabs, |
| uint64_t cr3, uint64_t pc) { |
| for (auto& st : symtabs) { |
| if (!Cr3Matches(st->cr3(), cr3)) |
| continue; |
| if (pc < st->base() || pc >= st->end()) |
| continue; |
| return st.get(); |
| } |
| |
| return nullptr; |
| } |
| |
| const Symbol* FindSymbol(const SymbolTableTable& symtabs, |
| uint64_t cr3, uint64_t pc, |
| const SymbolTable** out_symtab) { |
| const SymbolTable* symtab = FindSymbolTable(symtabs, cr3, pc); |
| if (!symtab) { |
| *out_symtab = nullptr; |
| return nullptr; |
| } |
| *out_symtab = symtab; |
| return symtab->FindSymbol(pc); |
| } |
| |
| const char* FindPcFileName(const SymbolTableTable& symtabs, |
| uint64_t cr3, uint64_t pc) { |
| for (const auto& st : symtabs) { |
| if (!Cr3Matches(st->cr3(), cr3)) |
| continue; |
| if (pc < st->base() || pc >= st->end()) |
| continue; |
| return st->file_name().c_str(); |
| } |
| return nullptr; |
| } |
| |
| bool SeenCr3(const SymbolTableTable& symtabs, uint64_t cr3) { |
| for (const auto& st : symtabs) { |
| if (st->cr3() == cr3) |
| return true; |
| } |
| return false; |
| } |
| |
| } // simple_pt |