[Sanitizer] Remove the hardcoded limit of address ranges in LoadedModule.

This should fix https://code.google.com/p/address-sanitizer/issues/detail?id=368.

llvm-svn: 225469
This commit is contained in:
Alexey Samsonov 2015-01-08 22:03:05 +00:00
parent e90f1165d8
commit b40fd1b24e
4 changed files with 38 additions and 30 deletions

View File

@ -12,8 +12,10 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_common.h"
#include "sanitizer_allocator_internal.h"
#include "sanitizer_flags.h"
#include "sanitizer_libc.h"
#include "sanitizer_placement_new.h"
namespace __sanitizer {
@ -237,20 +239,19 @@ void ReportErrorSummary(const char *error_type, const char *file,
LoadedModule::LoadedModule(const char *module_name, uptr base_address) {
full_name_ = internal_strdup(module_name);
base_address_ = base_address;
n_ranges_ = 0;
ranges_.clear();
}
void LoadedModule::addAddressRange(uptr beg, uptr end, bool executable) {
CHECK_LT(n_ranges_, kMaxNumberOfAddressRanges);
ranges_[n_ranges_].beg = beg;
ranges_[n_ranges_].end = end;
exec_[n_ranges_] = executable;
n_ranges_++;
void *mem = InternalAlloc(sizeof(AddressRange));
AddressRange *r = new(mem) AddressRange(beg, end, executable);
ranges_.push_back(r);
}
bool LoadedModule::containsAddress(uptr address) const {
for (uptr i = 0; i < n_ranges_; i++) {
if (ranges_[i].beg <= address && address < ranges_[i].end)
for (Iterator iter = ranges(); iter.hasNext();) {
const AddressRange *r = iter.next();
if (r->beg <= address && address < r->end)
return true;
}
return false;

View File

@ -16,10 +16,11 @@
#ifndef SANITIZER_COMMON_H
#define SANITIZER_COMMON_H
#include "sanitizer_flags.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_libc.h"
#include "sanitizer_list.h"
#include "sanitizer_mutex.h"
#include "sanitizer_flags.h"
namespace __sanitizer {
struct StackTrace;
@ -526,22 +527,23 @@ class LoadedModule {
const char *full_name() const { return full_name_; }
uptr base_address() const { return base_address_; }
uptr n_ranges() const { return n_ranges_; }
uptr address_range_start(int i) const { return ranges_[i].beg; }
uptr address_range_end(int i) const { return ranges_[i].end; }
bool address_range_executable(int i) const { return exec_[i]; }
private:
struct AddressRange {
AddressRange *next;
uptr beg;
uptr end;
bool executable;
AddressRange(uptr beg, uptr end, bool executable)
: next(nullptr), beg(beg), end(end), executable(executable) {}
};
typedef IntrusiveList<AddressRange>::ConstIterator Iterator;
Iterator ranges() const { return Iterator(&ranges_); }
private:
char *full_name_;
uptr base_address_;
static const uptr kMaxNumberOfAddressRanges = 6;
AddressRange ranges_[kMaxNumberOfAddressRanges];
bool exec_[kMaxNumberOfAddressRanges];
uptr n_ranges_;
IntrusiveList<AddressRange> ranges_;
};
// OS-dependent function that fills array with descriptions of at most

View File

@ -79,11 +79,12 @@ void CovUpdateMapping(const char *coverage_dir, uptr caller_pc) {
text.append("%d\n", sizeof(uptr) * 8);
for (int i = 0; i < n_modules; ++i) {
const char *module_name = StripModuleName(modules[i].full_name());
for (unsigned j = 0; j < modules[i].n_ranges(); ++j) {
if (modules[i].address_range_executable(j)) {
uptr start = modules[i].address_range_start(j);
uptr end = modules[i].address_range_end(j);
uptr base = modules[i].base_address();
uptr base = modules[i].base_address();
for (auto iter = modules[i].ranges(); iter.hasNext();) {
const auto *range = iter.next();
if (range->executable) {
uptr start = range->beg;
uptr end = range->end;
text.append("%zx %zx %zx %s\n", start, end, base, module_name);
if (caller_pc && caller_pc >= start && caller_pc < end)
cached_mapping.SetModuleRange(start, end);

View File

@ -115,21 +115,25 @@ struct IntrusiveList {
}
}
class Iterator {
template<class ListTy, class ItemTy>
class IteratorBase {
public:
explicit Iterator(IntrusiveList<Item> *list)
explicit IteratorBase(ListTy *list)
: list_(list), current_(list->first_) { }
Item *next() {
Item *ret = current_;
ItemTy *next() {
ItemTy *ret = current_;
if (current_) current_ = current_->next;
return ret;
}
bool hasNext() const { return current_ != 0; }
private:
IntrusiveList<Item> *list_;
Item *current_;
ListTy *list_;
ItemTy *current_;
};
typedef IteratorBase<IntrusiveList<Item>, Item> Iterator;
typedef IteratorBase<const IntrusiveList<Item>, const Item> ConstIterator;
// private, don't use directly.
uptr size_;
Item *first_;