1501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* 2501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Copyright (C) 2011 The Android Open Source Project 3501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * 4501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * you may not use this file except in compliance with the License. 6501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * You may obtain a copy of the License at 7501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * 8501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * 10501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Unless required by applicable law or agreed to in writing, software 11501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * See the License for the specific language governing permissions and 14501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * limitations under the License. 15501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */ 16501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 17501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#define LOG_TAG "Corkscrew" 18501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown//#define LOG_NDEBUG 0 19501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 20501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include "../ptrace-arch.h" 21501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 22501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <sys/exec_elf.h> 23501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <cutils/log.h> 24501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 25501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#ifndef PT_ARM_EXIDX 26501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#define PT_ARM_EXIDX 0x70000001 27501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif 28501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 29501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownstatic void load_exidx_header(pid_t pid, map_info_t* mi, 30501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown uintptr_t* out_exidx_start, size_t* out_exidx_size) { 31501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown uint32_t elf_phoff; 32f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown uint32_t elf_phentsize_phnum; 33f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown if (try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phoff), &elf_phoff) 34f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown && try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phnum), 35f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown &elf_phentsize_phnum)) { 36f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown uint32_t elf_phentsize = elf_phentsize_phnum >> 16; 37f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown uint32_t elf_phnum = elf_phentsize_phnum & 0xffff; 38501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown for (uint32_t i = 0; i < elf_phnum; i++) { 39f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown uintptr_t elf_phdr = mi->start + elf_phoff + i * elf_phentsize; 40501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown uint32_t elf_phdr_type; 41f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown if (!try_get_word_ptrace(pid, elf_phdr + offsetof(Elf32_Phdr, p_type), &elf_phdr_type)) { 42501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown break; 43501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 44501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown if (elf_phdr_type == PT_ARM_EXIDX) { 45501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown uint32_t elf_phdr_offset; 46501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown uint32_t elf_phdr_filesz; 47f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown if (!try_get_word_ptrace(pid, elf_phdr + offsetof(Elf32_Phdr, p_offset), 48501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown &elf_phdr_offset) 49f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown || !try_get_word_ptrace(pid, elf_phdr + offsetof(Elf32_Phdr, p_filesz), 50501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown &elf_phdr_filesz)) { 51501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown break; 52501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 53501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown *out_exidx_start = mi->start + elf_phdr_offset; 54f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown *out_exidx_size = elf_phdr_filesz / 8; 55f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown ALOGV("Parsed EXIDX header info for %s: start=0x%08x, size=%d", mi->name, 56f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown *out_exidx_start, *out_exidx_size); 57501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown return; 58501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 59501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 60501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 61501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown *out_exidx_start = 0; 62501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown *out_exidx_size = 0; 63501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 64501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 65501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownvoid load_ptrace_map_info_data_arch(pid_t pid, map_info_t* mi, map_info_data_t* data) { 66501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown load_exidx_header(pid, mi, &data->exidx_start, &data->exidx_size); 67501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 68501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 69501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownvoid free_ptrace_map_info_data_arch(map_info_t* mi, map_info_data_t* data) { 70501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 71