1 //------------------------------------------------------------------------------
2 // Copyright (c) 2003, Ingo Weinhold
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:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
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.
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 //------------------------------------------------------------------------------
36 #include <debug/debug_support.h>
42 get_static_image_symbol(image_id image
, const char* name
, int32 symbolType
,
45 // try standard lookup first
46 status_t error
= get_image_symbol(image
, name
, symbolType
, _address
);
52 error
= get_image_info(image
, &imageInfo
);
56 // get a symbol iterator
57 debug_symbol_iterator
* iterator
;
58 error
= debug_create_file_symbol_iterator(imageInfo
.name
, &iterator
);
62 // get the unrelocated image info
63 image_info unrelocatedImageInfo
;
64 error
= debug_get_symbol_iterator_image_info(iterator
,
65 &unrelocatedImageInfo
);
67 debug_delete_symbol_iterator(iterator
);
71 // iterate through the symbols
72 int32 nameLength
= strlen(name
);
74 char foundName
[nameLength
+ 1];
78 if (debug_next_image_symbol(iterator
, foundName
, nameLength
+ 1,
79 &foundType
, &foundAddress
, &foundSize
) != B_OK
) {
80 debug_delete_symbol_iterator(iterator
);
81 return B_ENTRY_NOT_FOUND
;
84 if (strcmp(foundName
, name
) == 0
85 && (symbolType
== B_SYMBOL_TYPE_ANY
|| foundType
== symbolType
)) {
86 *_address
= (void*)((addr_t
)foundAddress
+ (addr_t
)imageInfo
.text
87 - (addr_t
)unrelocatedImageInfo
.text
);
88 debug_delete_symbol_iterator(iterator
);
108 ElfImage::~ElfImage()
115 ElfImage::SetTo(image_id image
)
118 status_t error
= _SetTo(image
);
144 ElfImage::FindSymbol(const char* symbolName
, void** address
)
146 return get_image_symbol(fImage
, symbolName
, B_SYMBOL_TYPE_ANY
, address
);
149 // GetSymbolRelocations
151 ElfImage::GetSymbolRelocations(const char* symbolName
, BList
* relocations
)
153 status_t error
= B_OK
;
154 ElfRelocation relocation
;
155 for (ElfRelocationIterator
it(&fFile
); it
.GetNext(&relocation
); ) {
156 uint32 type
= relocation
.GetType();
159 if ((type
== R_386_GLOB_DAT
|| type
== R_386_JMP_SLOT
)
160 && relocation
.GetSymbol(&symbol
) == B_OK
161 && symbol
.GetName()) {
162 // only undefined symbols with global binding
163 if ((symbol
.GetBinding() == STB_GLOBAL
164 || symbol
.GetBinding() == STB_WEAK
)
165 && (symbol
.GetTargetSectionIndex() == SHN_UNDEF
166 || symbol
.GetTargetSectionIndex()
167 >= (uint32
)fFile
.CountSections())
168 && !strcmp(symbol
.GetName(), symbolName
)) {
169 // get the address of the GOT entry for the symbol
171 = (void**)(fTextAddress
+ relocation
.GetOffset());
172 if (!relocations
->AddItem(gotEntry
)) {
185 ElfImage::_SetTo(image_id image
)
188 image_info imageInfo
;
189 status_t error
= get_image_info(image
, &imageInfo
);
192 fImage
= imageInfo
.id
;
193 // get the address of global offset table
194 error
= get_static_image_symbol(image
, "_GLOBAL_OFFSET_TABLE_",
195 B_SYMBOL_TYPE_ANY
, (void**)&fGotAddress
);
198 fTextAddress
= (uint8
*)imageInfo
.text
;
199 fDataAddress
= (uint8
*)imageInfo
.data
;
201 error
= fFile
.SetTo(imageInfo
.name
);