forked from OSchip/llvm-project
[asan] remove objdump-based tests in favour of much simpler LLVM-ish tests
llvm-svn: 147514
This commit is contained in:
parent
801d98b3f0
commit
cc1d7893d6
|
@ -61,89 +61,6 @@ static inline uint32_t my_rand(uint32_t* state) {
|
|||
|
||||
static uint32_t global_seed = 0;
|
||||
|
||||
class ObjdumpOfMyself {
|
||||
public:
|
||||
explicit ObjdumpOfMyself(const string &binary) {
|
||||
is_correct = true;
|
||||
string objdump_name = APPLE ? "gobjdump" : "objdump";
|
||||
string prog = objdump_name + " -d " + binary;
|
||||
// TODO(glider): popen() succeeds even if the file does not exist.
|
||||
FILE *pipe = popen(prog.c_str(), "r");
|
||||
string objdump;
|
||||
if (pipe) {
|
||||
const int kBuffSize = 4096;
|
||||
char buff[kBuffSize+1];
|
||||
int read_bytes;
|
||||
while ((read_bytes = fread(buff, 1, kBuffSize, pipe)) > 0) {
|
||||
buff[read_bytes] = 0;
|
||||
objdump.append(buff);
|
||||
}
|
||||
pclose(pipe);
|
||||
} else {
|
||||
is_correct = false;
|
||||
}
|
||||
// cut the objdump into functions
|
||||
string fn, next_fn;
|
||||
size_t next_start;
|
||||
for (size_t start = fn_start(objdump, 0, &fn);
|
||||
start != string::npos;
|
||||
start = next_start, fn = next_fn) {
|
||||
next_start = fn_start(objdump, start, &next_fn);
|
||||
// fprintf(stderr, "start: %d next_start = %d fn: %s\n",
|
||||
// (int)start, (int)next_start, fn.c_str());
|
||||
// Mac OS adds the "_" prefix to function names.
|
||||
if (fn.find(APPLE ? "_Disasm" : "Disasm") == string::npos) {
|
||||
continue;
|
||||
}
|
||||
string fn_body = objdump.substr(start, next_start - start);
|
||||
// fprintf(stderr, "%s:\n%s", fn.c_str(), fn_body.c_str());
|
||||
functions_[fn] = fn_body;
|
||||
}
|
||||
}
|
||||
|
||||
string &GetFuncDisasm(const string &fn) {
|
||||
return functions_[fn];
|
||||
}
|
||||
|
||||
int CountInsnInFunc(const string &fn, const vector<string> &insns) {
|
||||
// Mac OS adds the "_" prefix to function names.
|
||||
string fn_ref = APPLE ? "_" + fn : fn;
|
||||
const string &disasm = GetFuncDisasm(fn_ref);
|
||||
if (disasm.empty()) return -1;
|
||||
size_t counter = 0;
|
||||
for (size_t i = 0; i < insns.size(); i++) {
|
||||
size_t pos = 0;
|
||||
while ((pos = disasm.find(insns[i], pos)) != string::npos) {
|
||||
counter++;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
bool IsCorrect() { return is_correct; }
|
||||
|
||||
private:
|
||||
size_t fn_start(const string &objdump, size_t start_pos, string *fn) {
|
||||
size_t pos = objdump.find(">:\n", start_pos);
|
||||
if (pos == string::npos)
|
||||
return string::npos;
|
||||
size_t beg = pos;
|
||||
while (beg > 0 && objdump[beg - 1] != '<')
|
||||
beg--;
|
||||
*fn = objdump.substr(beg, pos - beg);
|
||||
return pos + 3;
|
||||
}
|
||||
|
||||
map<string, string> functions_;
|
||||
bool is_correct;
|
||||
};
|
||||
|
||||
static ObjdumpOfMyself *objdump_of_myself() {
|
||||
static ObjdumpOfMyself *o = new ObjdumpOfMyself(progname);
|
||||
return o;
|
||||
}
|
||||
|
||||
const size_t kLargeMalloc = 1 << 24;
|
||||
|
||||
template<class T>
|
||||
|
@ -1561,76 +1478,6 @@ TEST(AddressSanitizer, StrDupTest) {
|
|||
free(strdup(Ident("123")));
|
||||
}
|
||||
|
||||
TEST(AddressSanitizer, ObjdumpTest) {
|
||||
ObjdumpOfMyself *o = objdump_of_myself();
|
||||
EXPECT_TRUE(o->IsCorrect());
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
__attribute__((noinline))
|
||||
static void DisasmSimple() {
|
||||
Ident(0);
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
static void DisasmParamWrite(int *a) {
|
||||
*a = 1;
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
static void DisasmParamInc(int *a) {
|
||||
(*a)++;
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
static void DisasmParamReadIfWrite(int *a) {
|
||||
if (*a)
|
||||
*a = 1;
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
static int DisasmParamIfReadWrite(int *a, int cond) {
|
||||
int res = 0;
|
||||
if (cond)
|
||||
res = *a;
|
||||
*a = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int GLOBAL;
|
||||
|
||||
__attribute__((noinline))
|
||||
static void DisasmWriteGlob() {
|
||||
GLOBAL = 1;
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
TEST(AddressSanitizer, DisasmTest) {
|
||||
int a;
|
||||
DisasmSimple();
|
||||
DisasmParamWrite(&a);
|
||||
DisasmParamInc(&a);
|
||||
Ident(DisasmWriteGlob)();
|
||||
DisasmParamReadIfWrite(&a);
|
||||
|
||||
a = 7;
|
||||
EXPECT_EQ(7, DisasmParamIfReadWrite(&a, Ident(1)));
|
||||
EXPECT_EQ(0, a);
|
||||
|
||||
ObjdumpOfMyself *o = objdump_of_myself();
|
||||
vector<string> insns;
|
||||
insns.push_back("ud2");
|
||||
insns.push_back("__asan_report_");
|
||||
EXPECT_EQ(0, o->CountInsnInFunc("DisasmSimple", insns));
|
||||
EXPECT_EQ(1, o->CountInsnInFunc("DisasmParamWrite", insns));
|
||||
EXPECT_EQ(1, o->CountInsnInFunc("DisasmParamInc", insns));
|
||||
EXPECT_EQ(0, o->CountInsnInFunc("DisasmWriteGlob", insns));
|
||||
|
||||
// TODO(kcc): implement these (needs just one __asan_report).
|
||||
EXPECT_EQ(2, o->CountInsnInFunc("DisasmParamReadIfWrite", insns));
|
||||
EXPECT_EQ(2, o->CountInsnInFunc("DisasmParamIfReadWrite", insns));
|
||||
}
|
||||
|
||||
// Currently we create and poison redzone at right of global variables.
|
||||
char glob5[5];
|
||||
static char static110[110];
|
||||
|
|
Loading…
Reference in New Issue