forked from Lephenixnoir/fxos
lib: allow declaring exclusive claims multiple times
This commit is contained in:
parent
97029d4f3e
commit
44babe3baf
|
@ -144,6 +144,9 @@ struct Claim
|
|||
/* Utility to check for intersections */
|
||||
bool intersects(Claim const &other) const;
|
||||
|
||||
/* Check equality of claims (raw equality) */
|
||||
bool operator==(Claim const &other) const;
|
||||
|
||||
/* String representation */
|
||||
std::string str() const;
|
||||
};
|
||||
|
@ -194,11 +197,15 @@ struct Disassembly
|
|||
/* Access the claim that owns the address, if there is one */
|
||||
Claim const *getClaimAt(uint32_t address);
|
||||
|
||||
/* Access the first claim that overlaps this region, if any */
|
||||
/* Find the first claim that overlaps this region, if any */
|
||||
Claim const *findClaimConflict(uint32_t address, int size);
|
||||
|
||||
/* Find all (or up to max ≥ 0) claims that overlaps this region */
|
||||
std::vector<Claim const *> findClaimConflicts(
|
||||
uint32_t address, int size, int max = -1);
|
||||
|
||||
/* Add a new exclusive claim. If there is any intersection with previous
|
||||
claims, this fails. */
|
||||
claims which do not compare equal to c, this fails. */
|
||||
bool addExclusiveClaim(Claim const &c);
|
||||
|
||||
// TODO: Add non-exclusive claims/handle collisions
|
||||
|
|
|
@ -65,6 +65,12 @@ bool Claim::intersects(Claim const &other) const
|
|||
return inter_start < inter_end;
|
||||
}
|
||||
|
||||
bool Claim::operator==(Claim const &other) const
|
||||
{
|
||||
return this->address == other.address && this->size == other.size
|
||||
&& this->type == other.type && this->owner == other.owner;
|
||||
}
|
||||
|
||||
std::string Claim::str() const
|
||||
{
|
||||
std::string details = format(" (claim 0x%08x:%d)", address, size);
|
||||
|
@ -140,7 +146,8 @@ Function *Disassembly::getFunctionAt(uint32_t pc)
|
|||
return &it->second;
|
||||
}
|
||||
|
||||
Claim const *Disassembly::findClaimConflict(uint32_t address, int size)
|
||||
std::vector<Claim const *> Disassembly::findClaimConflicts(
|
||||
uint32_t address, int size, int max)
|
||||
{
|
||||
Claim fake_claim = {
|
||||
.address = address,
|
||||
|
@ -148,6 +155,7 @@ Claim const *Disassembly::findClaimConflict(uint32_t address, int size)
|
|||
.type = 0,
|
||||
.owner = 0,
|
||||
};
|
||||
std::vector<Claim const *> conflicts;
|
||||
|
||||
/* Find the first claim whose start is [> address] */
|
||||
auto it = this->claims.upper_bound(fake_claim);
|
||||
|
@ -155,19 +163,26 @@ Claim const *Disassembly::findClaimConflict(uint32_t address, int size)
|
|||
if(it != this->claims.begin())
|
||||
it--;
|
||||
|
||||
while(it != this->claims.end()) {
|
||||
while(it != this->claims.end()
|
||||
&& (max < 0 || conflicts.size() < (size_t)max)) {
|
||||
/* We completely passed address+size, no conflict found */
|
||||
if(it->address >= address + size)
|
||||
return nullptr;
|
||||
break;
|
||||
|
||||
/* There is an intersection */
|
||||
if(it->intersects(fake_claim))
|
||||
return &*it;
|
||||
conflicts.push_back(&*it);
|
||||
|
||||
it++;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return conflicts;
|
||||
}
|
||||
|
||||
Claim const *Disassembly::findClaimConflict(uint32_t address, int size)
|
||||
{
|
||||
auto claims = findClaimConflicts(address, size, 1);
|
||||
return claims.size() > 0 ? claims[0] : nullptr;
|
||||
}
|
||||
|
||||
Claim const *Disassembly::getClaimAt(uint32_t address)
|
||||
|
@ -177,15 +192,22 @@ Claim const *Disassembly::getClaimAt(uint32_t address)
|
|||
|
||||
bool Disassembly::addExclusiveClaim(Claim const &c)
|
||||
{
|
||||
Claim const *conflict = this->findClaimConflict(c.address, c.size);
|
||||
if(conflict) {
|
||||
auto conflicts = this->findClaimConflicts(c.address, c.size);
|
||||
bool exclusive = true;
|
||||
|
||||
for(auto conflict: conflicts) {
|
||||
/* Allow declaring the same claim twice */
|
||||
if(*conflict == c)
|
||||
continue;
|
||||
|
||||
FxOS_log(ERR, "exclusive claim for %s conflicts with %s", c.str(),
|
||||
conflict->str());
|
||||
return false;
|
||||
conflicts[0]->str());
|
||||
exclusive = false;
|
||||
}
|
||||
|
||||
this->claims.insert(c);
|
||||
return true;
|
||||
if(exclusive)
|
||||
this->claims.insert(c);
|
||||
return exclusive;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue