1e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris/* 2e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * Copyright (C) 2018 The Android Open Source Project 3e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * 4e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * Licensed under the Apache License, Version 2.0 (the "License"); 5e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * you may not use this file except in compliance with the License. 6e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * You may obtain a copy of the License at 7e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * 8e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * http://www.apache.org/licenses/LICENSE-2.0 9e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * 10e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * Unless required by applicable law or agreed to in writing, software 11e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * distributed under the License is distributed on an "AS IS" BASIS, 12e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * See the License for the specific language governing permissions and 14e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris * limitations under the License. 15e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris */ 16e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 17e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <elf.h> 18e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <errno.h> 19e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <fcntl.h> 20e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <inttypes.h> 21e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <stdio.h> 22e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <stdlib.h> 23e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <string.h> 24e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <sys/mman.h> 25e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <sys/stat.h> 26e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <sys/types.h> 27e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <unistd.h> 28e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 29e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <unwindstack/DwarfLocation.h> 30e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <unwindstack/DwarfMemory.h> 31e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <unwindstack/DwarfSection.h> 32e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <unwindstack/DwarfStructs.h> 33e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <unwindstack/Elf.h> 34e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <unwindstack/ElfInterface.h> 35e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include <unwindstack/Log.h> 36e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 37e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris#include "DwarfOp.h" 38e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 39e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferrisnamespace unwindstack { 40e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 41e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferrisvoid PrintSignedValue(int64_t value) { 42e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (value < 0) { 43e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("- %" PRId64, -value); 44e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } else if (value > 0) { 45e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("+ %" PRId64, value); 46e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 47e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris} 48e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 49e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferrisvoid PrintExpression(Memory* memory, uint8_t class_type, uint64_t end, uint64_t length) { 50e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris std::vector<std::string> lines; 51e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris DwarfMemory dwarf_memory(memory); 52e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (class_type == ELFCLASS32) { 53e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris DwarfOp<uint32_t> op(&dwarf_memory, nullptr); 54e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris op.GetLogInfo(end - length, end, &lines); 55e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } else { 56e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris DwarfOp<uint64_t> op(&dwarf_memory, nullptr); 57e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris op.GetLogInfo(end - length, end, &lines); 58e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 59e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris for (auto& line : lines) { 60e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf(" %s\n", line.c_str()); 61e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 62e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris} 63e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 64e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferrisvoid PrintRegInformation(DwarfSection* section, Memory* memory, uint64_t pc, uint8_t class_type) { 65e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris const DwarfFde* fde = section->GetFdeFromPc(pc); 66e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (fde == nullptr) { 67e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf(" No fde found.\n"); 68e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return; 69e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 70e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 71e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris dwarf_loc_regs_t regs; 72e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (!section->GetCfaLocationInfo(pc, fde, ®s)) { 73e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf(" Cannot get location information.\n"); 74e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return; 75e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 76e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 77e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris std::vector<std::pair<uint32_t, DwarfLocation>> loc_regs; 78e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris for (auto& loc : regs) { 79e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris loc_regs.push_back(loc); 80e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 81e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris std::sort(loc_regs.begin(), loc_regs.end(), [](auto a, auto b) { 82e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (a.first == CFA_REG) { 83e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return true; 84e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } else if (b.first == CFA_REG) { 85e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return false; 86e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 87e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return a.first < b.first; 88e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris }); 89e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 90e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris for (auto& entry : loc_regs) { 91e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris const DwarfLocation* loc = &entry.second; 92e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (entry.first == CFA_REG) { 93e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf(" cfa = "); 94e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } else { 95e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf(" r%d = ", entry.first); 96e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 97e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris switch (loc->type) { 98e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris case DWARF_LOCATION_OFFSET: 99e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("[cfa "); 100e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris PrintSignedValue(loc->values[0]); 101e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("]\n"); 102e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris break; 103e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 104e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris case DWARF_LOCATION_VAL_OFFSET: 105e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("cfa "); 106e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris PrintSignedValue(loc->values[0]); 107e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\n"); 108e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris break; 109e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 110e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris case DWARF_LOCATION_REGISTER: 111e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("r%" PRId64 " ", loc->values[0]); 112e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris PrintSignedValue(loc->values[1]); 113e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\n"); 114e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris break; 115e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 116e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris case DWARF_LOCATION_EXPRESSION: { 117e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("EXPRESSION\n"); 118e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris PrintExpression(memory, class_type, loc->values[1], loc->values[0]); 119e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris break; 120e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 121e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 122e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris case DWARF_LOCATION_VAL_EXPRESSION: { 123e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("VAL EXPRESSION\n"); 124e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris PrintExpression(memory, class_type, loc->values[1], loc->values[0]); 125e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris break; 126e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 127e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 128e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris case DWARF_LOCATION_UNDEFINED: 129e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("undefine\n"); 130e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris break; 131e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 132e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris case DWARF_LOCATION_INVALID: 133e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("INVALID\n"); 134e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris break; 135e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 136e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 137e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris} 138e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 139e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferrisint GetInfo(const char* file, uint64_t pc) { 140e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris MemoryFileAtOffset* memory = new MemoryFileAtOffset; 141e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (!memory->Init(file, 0)) { 142e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris // Initializatation failed. 143e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("Failed to init\n"); 144e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return 1; 145e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 146e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 147e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris Elf elf(memory); 148e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (!elf.Init(true) || !elf.valid()) { 149e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("%s is not a valid elf file.\n", file); 150e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return 1; 151e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 152e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 153e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris ElfInterface* interface = elf.interface(); 154e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris uint64_t load_bias = elf.GetLoadBias(); 155e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (pc < load_bias) { 156e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("PC is less than load bias.\n"); 157e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return 1; 158e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 159e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 160beae42bc7f8fb6494138ff8a6d17ed6a65b2cf9aChristopher Ferris std::string soname; 161beae42bc7f8fb6494138ff8a6d17ed6a65b2cf9aChristopher Ferris if (elf.GetSoname(&soname)) { 162beae42bc7f8fb6494138ff8a6d17ed6a65b2cf9aChristopher Ferris printf("Soname: %s\n\n", soname.c_str()); 163beae42bc7f8fb6494138ff8a6d17ed6a65b2cf9aChristopher Ferris } 164beae42bc7f8fb6494138ff8a6d17ed6a65b2cf9aChristopher Ferris 165e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("PC 0x%" PRIx64 ":\n", pc); 166e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 167e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris DwarfSection* section = interface->eh_frame(); 168e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (section != nullptr) { 169e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\neh_frame:\n"); 170e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris PrintRegInformation(section, memory, pc - load_bias, elf.class_type()); 171e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } else { 172e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\nno eh_frame information\n"); 173e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 174e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 175e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris section = interface->debug_frame(); 176e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (section != nullptr) { 177e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\ndebug_frame:\n"); 178e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris PrintRegInformation(section, memory, pc - load_bias, elf.class_type()); 179e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\n"); 180e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } else { 181e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\nno debug_frame information\n"); 182e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 183e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 184e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris // If there is a gnu_debugdata interface, dump the information for that. 185e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris ElfInterface* gnu_debugdata_interface = elf.gnu_debugdata_interface(); 186e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (gnu_debugdata_interface != nullptr) { 187e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris section = gnu_debugdata_interface->eh_frame(); 188e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (section != nullptr) { 189e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\ngnu_debugdata (eh_frame):\n"); 190e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris PrintRegInformation(section, gnu_debugdata_interface->memory(), pc, elf.class_type()); 191e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\n"); 192e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } else { 193e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\nno gnu_debugdata (eh_frame)\n"); 194e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 195e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 196e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris section = gnu_debugdata_interface->debug_frame(); 197e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (section != nullptr) { 198e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\ngnu_debugdata (debug_frame):\n"); 199e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris PrintRegInformation(section, gnu_debugdata_interface->memory(), pc, elf.class_type()); 200e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\n"); 201e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } else { 202e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\nno gnu_debugdata (debug_frame)\n"); 203e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 204e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } else { 205e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("\nno valid gnu_debugdata information\n"); 206e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 207e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 208e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return 0; 209e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris} 210e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 211e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris} // namespace unwindstack 212e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 213e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferrisint main(int argc, char** argv) { 214e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (argc != 3) { 215e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("Usage: unwind_reg_info ELF_FILE PC\n"); 216e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf(" ELF_FILE\n"); 217e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf(" The path to an elf file.\n"); 218e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf(" PC\n"); 219e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf(" The pc for which the register information should be obtained.\n"); 220e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return 1; 221e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 222e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 223e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris struct stat st; 224e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (stat(argv[1], &st) == -1) { 225e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("Cannot stat %s: %s\n", argv[1], strerror(errno)); 226e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return 1; 227e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 228e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (!S_ISREG(st.st_mode)) { 229e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("%s is not a regular file.\n", argv[1]); 230e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return 1; 231e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 232e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 233e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris uint64_t pc = 0; 234e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris char* end; 235e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris pc = strtoull(argv[2], &end, 16); 236e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris if (*end != '\0') { 237e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris printf("Malformed OFFSET value: %s\n", argv[2]); 238e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return 1; 239e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris } 240e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris 241e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris return unwindstack::GetInfo(argv[1], pc); 242e37e2d05b1ae3f844750b76d3b71278b79d5de51Christopher Ferris} 243