1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2003, Ingo Weinhold 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: ElfImage.cpp 23 // Author: Ingo Weinhold (bonefish@users.sf.net) 24 // Description: Implementation of ElfImage, a class encapsulating 25 // a loaded ELF image, providing support for accessing the 26 // image's symbols and their relocation entries. 27 //------------------------------------------------------------------------------ 28 29 #include <new> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 34 #include <List.h> 35 36 #include "ElfImage.h" 37 38 // ElfImage 39 40 // constructor 41 ElfImage::ElfImage() 42 : fImage(-1), 43 fFile(), 44 fTextAddress(NULL), 45 fDataAddress(NULL), 46 fGotAddress(NULL) 47 { 48 } 49 50 // destructor 51 ElfImage::~ElfImage() 52 { 53 Unset(); 54 } 55 56 // SetTo 57 status_t 58 ElfImage::SetTo(image_id image) 59 { 60 Unset(); 61 status_t error = _SetTo(image); 62 if (error) 63 Unset(); 64 return error; 65 } 66 67 // Unset 68 void 69 ElfImage::Unset() 70 { 71 fFile.Unset(); 72 fImage = -1; 73 fTextAddress = NULL; 74 fDataAddress = NULL; 75 fGotAddress = NULL; 76 } 77 78 // Unload 79 void 80 ElfImage::Unload() 81 { 82 fFile.Unload(); 83 } 84 85 // FindSymbol 86 status_t 87 ElfImage::FindSymbol(const char* symbolName, void** address) 88 { 89 return get_image_symbol(fImage, symbolName, B_SYMBOL_TYPE_ANY, address); 90 } 91 92 // GetSymbolRelocations 93 status_t 94 ElfImage::GetSymbolRelocations(const char* symbolName, BList* relocations) 95 { 96 status_t error = B_OK; 97 ElfRelocation relocation; 98 for (ElfRelocationIterator it(&fFile); it.GetNext(&relocation); ) { 99 uint32 type = relocation.GetType(); 100 // get the symbol 101 ElfSymbol symbol; 102 if ((type == R_386_GLOB_DAT || type == R_386_JMP_SLOT) 103 && relocation.GetSymbol(&symbol) == B_OK 104 && symbol.GetName()) { 105 // only undefined symbols with global binding 106 if ((symbol.GetBinding() == STB_GLOBAL 107 || symbol.GetBinding() == STB_WEAK) 108 && (symbol.GetTargetSectionIndex() == SHN_UNDEF 109 || symbol.GetTargetSectionIndex() 110 >= (uint32)fFile.CountSections()) 111 && !strcmp(symbol.GetName(), symbolName)) { 112 // get the address of the GOT entry for the symbol 113 void** gotEntry 114 = (void**)(fTextAddress + relocation.GetOffset()); 115 if (!relocations->AddItem(gotEntry)) { 116 error = B_NO_MEMORY; 117 break; 118 } 119 } 120 } 121 } 122 return error; 123 } 124 125 // _SetTo 126 status_t 127 ElfImage::_SetTo(image_id image) 128 { 129 // get an image info 130 image_info imageInfo; 131 status_t error = get_image_info(image, &imageInfo); 132 if (error != B_OK) 133 return error; 134 fImage = imageInfo.id; 135 // get the address of global offset table 136 error = get_image_symbol(image, "_GLOBAL_OFFSET_TABLE_", 137 B_SYMBOL_TYPE_ANY, (void**)&fGotAddress); 138 if (error != B_OK) 139 return error; 140 fTextAddress = (uint8*)imageInfo.text; 141 fDataAddress = (uint8*)imageInfo.data; 142 // init the file 143 error = fFile.SetTo(imageInfo.name); 144 if (error != B_OK) 145 return error; 146 return B_OK; 147 } 148 149