xref: /haiku/src/bin/debug/profile/Image.cpp (revision c28bcbdf58b7a03ea773ae82f2e0a3befcc96ac4)
1 /*
2  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include "Image.h"
7 
8 #include <stdio.h>
9 
10 #include <algorithm>
11 #include <new>
12 
13 #include <debug_support.h>
14 #include <ObjectList.h>
15 
16 #include "Options.h"
17 
18 
19 Image::Image(const image_info& info, team_id owner, int32 creationEvent)
20 	:
21 	fInfo(info),
22 	fOwner(owner),
23 	fSymbols(NULL),
24 	fSymbolCount(0),
25 	fCreationEvent(creationEvent),
26 	fDeletionEvent(-1)
27 {
28 }
29 
30 
31 Image::~Image()
32 {
33 	if (fSymbols != NULL) {
34 		for (int32 i = 0; i < fSymbolCount; i++)
35 			delete fSymbols[i];
36 		delete[] fSymbols;
37 	}
38 }
39 
40 
41 status_t
42 Image::LoadSymbols(debug_symbol_lookup_context* lookupContext)
43 {
44 //	fprintf(sOptions.output, "Loading symbols of image \"%s\" (%ld)...\n",
45 //		fInfo.name, fInfo.id);
46 
47 	// create symbol iterator
48 	debug_symbol_iterator* iterator;
49 	status_t error = debug_create_image_symbol_iterator(lookupContext,
50 		fInfo.id, &iterator);
51 	if (error != B_OK) {
52 		fprintf(stderr, "Failed to init symbol iterator: %s\n",
53 			strerror(error));
54 		return error;
55 	}
56 
57 	// iterate through the symbols
58 	BObjectList<Symbol>	symbols(512, true);
59 	char symbolName[1024];
60 	int32 symbolType;
61 	void* symbolLocation;
62 	size_t symbolSize;
63 	while (debug_next_image_symbol(iterator, symbolName, sizeof(symbolName),
64 			&symbolType, &symbolLocation, &symbolSize) == B_OK) {
65 //		printf("  %s %p (%6lu) %s\n",
66 //			symbolType == B_SYMBOL_TYPE_TEXT ? "text" : "data",
67 //			symbolLocation, symbolSize, symbolName);
68 		if (symbolSize > 0 && symbolType == B_SYMBOL_TYPE_TEXT) {
69 			Symbol* symbol = new(std::nothrow) Symbol(this,
70 				(addr_t)symbolLocation, symbolSize, symbolName);
71 			if (symbol == NULL || !symbols.AddItem(symbol)) {
72 				delete symbol;
73 				fprintf(stderr, "%s: Out of memory\n", kCommandName);
74 				debug_delete_image_symbol_iterator(iterator);
75 				return B_NO_MEMORY;
76 			}
77 		}
78 	}
79 
80 	debug_delete_image_symbol_iterator(iterator);
81 
82 	// sort the symbols
83 	fSymbolCount = symbols.CountItems();
84 	fSymbols = new(std::nothrow) Symbol*[fSymbolCount];
85 	if (fSymbols == NULL)
86 		return B_NO_MEMORY;
87 
88 	for (int32 i = fSymbolCount - 1; i >= 0 ; i--)
89 		fSymbols[i] = symbols.RemoveItemAt(i);
90 
91 	std::sort(fSymbols, fSymbols + fSymbolCount, SymbolComparator());
92 
93 	return B_OK;
94 }
95 
96 
97 int32
98 Image::FindSymbol(addr_t address) const
99 {
100 	// binary search the function
101 	int32 lower = 0;
102 	int32 upper = fSymbolCount;
103 
104 	while (lower < upper) {
105 		int32 mid = (lower + upper) / 2;
106 		if (address >= fSymbols[mid]->base + fSymbols[mid]->size)
107 			lower = mid + 1;
108 		else
109 			upper = mid;
110 	}
111 
112 	if (lower == fSymbolCount)
113 		return -1;
114 
115 	const Symbol* symbol = fSymbols[lower];
116 	if (address >= symbol->base && address < symbol->base + symbol->size)
117 		return lower;
118 	return -1;
119 }
120