Skip to content

Commit

Permalink
Merge pull request #163 from chaoticgd/handles_from_address_range
Browse files Browse the repository at this point in the history
Add SymbolList<>::handles_from_address_range function
  • Loading branch information
chaoticgd authored Jan 22, 2024
2 parents 2d0da57 + aaeeef0 commit 3195a9a
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 5 deletions.
15 changes: 14 additions & 1 deletion src/ccc/symbol_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ typename SymbolList<SymbolType>::AddressToHandleMapIterators SymbolList<SymbolTy
return {iterators.first, iterators.second};
}

template <typename SymbolType>
typename SymbolList<SymbolType>::AddressToHandleMapIterators SymbolList<SymbolType>::handles_from_address_range(AddressRange range) const
{
if(range.low.valid()) {
return {m_address_to_handle.lower_bound(range.low.value), m_address_to_handle.lower_bound(range.high.value)};
} else if(range.high.valid()) {
return {m_address_to_handle.begin(), m_address_to_handle.lower_bound(range.high.value)};
} else {
return {m_address_to_handle.end(), m_address_to_handle.end()};
}
}

template <typename SymbolType>
SymbolHandle<SymbolType> SymbolList<SymbolType>::first_handle_from_starting_address(Address address) const
{
Expand Down Expand Up @@ -130,7 +142,8 @@ SymbolHandle<SymbolType> SymbolList<SymbolType>::first_handle_from_name(const st
template <typename SymbolType>
SymbolType* SymbolList<SymbolType>::symbol_from_contained_address(Address address)
{
auto iterator = m_address_to_handle.lower_bound(address.value);
auto iterator = m_address_to_handle.upper_bound(address.value);
iterator--; // Find the greatest element that is less than or equal to the address.
if(iterator != m_address_to_handle.end()) {
SymbolType* symbol = symbol_from_handle(iterator->second);
if(symbol && address.value < symbol->m_address.value + symbol->m_size) {
Expand Down
4 changes: 3 additions & 1 deletion src/ccc/symbol_database.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class SymbolList {
std::span<SymbolType> optional_span(std::optional<SymbolRange<SymbolType>> range);
std::span<const SymbolType> optional_span(std::optional<SymbolRange<SymbolType>> range) const;

using AddressToHandleMap = std::multimap<u32, SymbolHandle<SymbolType>, std::greater<u32>>;
using AddressToHandleMap = std::multimap<u32, SymbolHandle<SymbolType>>;
using NameToHandleMap = std::multimap<std::string, SymbolHandle<SymbolType>>;

template <typename Iterator>
Expand All @@ -151,6 +151,7 @@ class SymbolList {
using NameToHandleMapIterators = Iterators<typename NameToHandleMap::const_iterator>;

AddressToHandleMapIterators handles_from_starting_address(Address address) const;
AddressToHandleMapIterators handles_from_address_range(AddressRange range) const;
SymbolHandle<SymbolType> first_handle_from_starting_address(Address address) const;
NameToHandleMapIterators handles_from_name(const std::string& name) const;
SymbolHandle<SymbolType> first_handle_from_name(const std::string& name) const;
Expand Down Expand Up @@ -259,6 +260,7 @@ class Symbol {
Address address() const { return m_address; }
u32 size() const { return m_size; }
void set_size(u32 size) { m_size = size; }
AddressRange address_range() const { return AddressRange(m_address, m_address.get_or_zero() + m_size); }

ast::Node* type() { return m_type.get(); }
const ast::Node* type() const { return m_type.get(); }
Expand Down
2 changes: 1 addition & 1 deletion src/ccc/symbol_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ static void write_json(JsonWriter& json, const LocalVariable& symbol, const Symb
write_json(json, *storage, database);
}

if(symbol.live_range.valid()) {
if(symbol.live_range.low.valid() && symbol.live_range.high.valid()) {
json.Key("live_range");
json.StartArray();
json.Uint(symbol.live_range.low.value);
Expand Down
5 changes: 4 additions & 1 deletion src/ccc/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,11 @@ struct AddressRange {
Address low;
Address high;

AddressRange() {}
AddressRange(Address address) : low(address), high(address) {}
AddressRange(Address l, Address h) : low(l), high(h) {}

friend auto operator<=>(const AddressRange& lhs, const AddressRange& rhs) = default;
bool valid() const { return low.valid(); }
};

// These functions are to be used only for source file paths present in the
Expand Down
49 changes: 48 additions & 1 deletion test/ccc/symbol_database_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,54 @@ TEST(CCCSymbolDatabase, SymbolListSpan)
}
}

TEST(CCCSymbolDatabase, HandleFromAddress)
TEST(CCCSymbolDatabase, HandlesFromAddressRange)
{
SymbolDatabase database;
FunctionHandle handles[20];

Result<SymbolSource*> source = database.symbol_sources.create_symbol("Source", SymbolSourceHandle());
CCC_GTEST_FAIL_IF_ERROR(source);

// Create the symbols.
for(u32 address = 10; address < 20; address++) {
Result<Function*> function = database.functions.create_symbol("", (*source)->handle(), nullptr, address);
CCC_GTEST_FAIL_IF_ERROR(function);
handles[address] = (*function)->handle();
}

// Try various address ranges.
auto empty_before = database.functions.handles_from_address_range(AddressRange(0, 10));
EXPECT_EQ(empty_before.begin(), empty_before.end());

auto empty_after = database.functions.handles_from_address_range(AddressRange(21, 30));
EXPECT_EQ(empty_after.begin(), empty_after.end());

auto empty_before_open = database.functions.handles_from_address_range(AddressRange(Address(), 10));
EXPECT_EQ(empty_before_open.begin(), empty_before_open.end());

auto empty_after_open = database.functions.handles_from_address_range(AddressRange(21, Address()));
EXPECT_EQ(empty_after_open.begin(), empty_after_open.end());

auto last = database.functions.handles_from_address_range(AddressRange(19, 30));
EXPECT_EQ(last.begin()->second, handles[19]);

auto last_open = database.functions.handles_from_address_range(AddressRange(19, Address()));
EXPECT_EQ(last_open.begin()->second, handles[19]);

auto first_half = database.functions.handles_from_address_range(AddressRange(5, 15));
EXPECT_EQ(first_half.begin()->second, handles[10]);
EXPECT_EQ(first_half.end()->second, handles[15]);

auto second_half = database.functions.handles_from_address_range(AddressRange(15, 25));
EXPECT_EQ(second_half.begin()->second, handles[15]);
EXPECT_EQ((--second_half.end())->second, handles[19]);

auto whole_range = database.functions.handles_from_address_range(AddressRange(10, 20));
EXPECT_EQ(whole_range.begin()->second, handles[10]);
EXPECT_EQ((--whole_range.end())->second, handles[19]);
}

TEST(CCCSymbolDatabase, HandleFromStartingAddress)
{
SymbolDatabase database;
FunctionHandle handles[10];
Expand Down

0 comments on commit 3195a9a

Please sign in to comment.