1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file. 4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef CRAZY_LINKER_PROC_MAPS_H 6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define CRAZY_LINKER_PROC_MAPS_H 7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Helper classes and functions to extract useful information out of 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// /proc/self/maps. 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <stdint.h> 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <sys/mman.h> // for PROT_READ etc... 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace crazy { 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ProcMapsInternal; 17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ProcMaps { 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public: 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Used to open /proc/self/maps. 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // There is no error reporting. If the file can't be opened, then 22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // GetNextEntry() will return false on the first call. 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ProcMaps(); 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Used to open /proc/$PID/maps. 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // There is also no error reporting. 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) explicit ProcMaps(pid_t pid); 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ~ProcMaps(); 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Small structure to model an entry. 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) struct Entry { 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t vma_start; 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t vma_end; 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int prot_flags; 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t load_offset; 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* path; // can be NULL, not always zero-terminated. 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t path_len; // 0 if |path| is NULL. 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) }; 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Rewind(); 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Get next entry in maps, return NULL on failure. 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // On success, return true and set |entry| to valid values. 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Note that the |entry->path| field can be NULL or will point to 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // an address which content may change on the next call to this method. 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool GetNextEntry(Entry* entry); 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int GetProtectionFlagsForAddress(void* address); 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private: 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ProcMapsInternal* internal_; 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Find which loaded ELF binary contains |address|. 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// On success, returns true and sets |*load_address| to its load address, 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// and fills |path_buffer| with the path to the corresponding file. 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool FindElfBinaryForAddress(void* address, 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uintptr_t* load_address, 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) char* path_buffer, 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t path_buffer_len); 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Returns the current protection bit flags for the page holding a given 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// |address|. On success, returns true and sets |*prot_flags|. 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool FindProtectionFlagsForAddress(void* address, int* prot_flags); 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Return the load address of a given ELF binary. 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If |file_name| contains a slash, this will try to perform an 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// exact match with the content of /proc/self/maps. Otherwise, 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// it will be taken as a base name, and the load address of the first 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// matching entry will be returned. 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// On success, returns true and sets |*load_address| to the load address, 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// and |*load_offset| to the load offset. 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool FindLoadAddressForFile(const char* file_name, 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uintptr_t* load_address, 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uintptr_t* load_offset); 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace crazy 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif // CRAZY_LINKER_PROC_MAPS_H 81