Skip to content

Commit

Permalink
Make memory-analyzer compatible with i386
Browse files Browse the repository at this point in the history
We previously hard-coded x86_64 calling conventions for malloc.
  • Loading branch information
tautschnig committed Aug 23, 2023
1 parent 0794f5b commit c1f9237
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 7 deletions.
7 changes: 6 additions & 1 deletion regression/memory-analyzer/chain.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,10 @@ args=$(echo $cmd | cut -d ' ' -f 2-)
name=${name%.gb}
opts=${*:3:$#-3}

$goto_gcc -g -std=c11 -o "${name}.gb" "${name}.c"
bit_width=`$memory_analyzer -h | grep -- -bit | sed 's/-bit.*//' | sed 's/.* //'`
if [[ "$bit_width" != "64" ]] && [[ $(uname -m) = "x86_64" ]]; then
$goto_gcc -g -m32 -std=c11 -o "${name}.gb" "${name}.c"
else
$goto_gcc -g -std=c11 -o "${name}.gb" "${name}.c"
fi
$memory_analyzer $opts "${name}.gb" $args
8 changes: 4 additions & 4 deletions src/memory-analyzer/analyze_symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,9 @@ exprt gdb_value_extractort::get_non_char_pointer_value(

// Check if pointer was dynamically allocated (via malloc). If so we will
// replace the pointee with a static array filled with values stored at the
// expected positions. Since the allocated size is over-approximation we may
// end up querying pass the allocated bounds and building larger array with
// meaningless values.
// expected positions. Since the allocated size is an over-approximation we
// may end up querying past the allocated bounds and building a larger array
// with meaningless values.
mp_integer allocated_size = get_malloc_size(c_converter.convert(expr));
// get the sizeof(target_type) and thus the number of elements
const auto number_of_elements = allocated_size / get_type_size(target_type);
Expand All @@ -406,7 +406,7 @@ exprt gdb_value_extractort::get_non_char_pointer_value(
for(size_t i = 0; i < number_of_elements; i++)
{
const auto sub_expr_value = get_expr_value(
index_exprt{expr, from_integer(i, index_type())},
dereference_exprt{plus_exprt{expr, from_integer(i, index_type())}},
*zero_expr,
location);
elements.push_back(sub_expr_value);
Expand Down
16 changes: 14 additions & 2 deletions src/memory-analyzer/gdb_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,8 @@ void gdb_apit::run_gdb_from_core(const std::string &corefile)

void gdb_apit::collect_malloc_calls()
{
// this is what the registers look like at the function call entry:
#if defined(__x86_64__)
// this is what the registers look like at the function call entry for x86-64:
//
// reg. name hex. value dec. value
// 0: rax 0xffffffff 4294967295
Expand All @@ -303,6 +304,17 @@ void gdb_apit::collect_malloc_calls()
write_to_gdb("-data-list-register-values d 5");
auto record = get_most_recent_record("^done", true);
auto allocated_size = safe_string2size_t(get_register_value(record));
#elif defined(__i386__)
// x86 32-bit Linux calling conventions use the stack to pass arguments. The
// top of the stack is the return address, so look at the next element (+4 as
// the stack grows downwards).
write_to_gdb("-data-evaluate-expression \"*(unsigned long*)($esp + 4)\"");
auto record = get_most_recent_record("^done", true);
auto allocated_size =
safe_string2size_t(get_value_from_record(record, "value"));
#else
# error malloc calling conventions not know for current platform
#endif

write_to_gdb("-exec-finish");
if(!most_recent_line_has_tag("*running"))
Expand All @@ -324,7 +336,7 @@ void gdb_apit::collect_malloc_calls()
record = get_most_recent_record("*stopped");
}

// now we can read the rax register to the the allocated memory address
// now we can read the eax/rax register to the allocated memory address
write_to_gdb("-data-list-register-values x 0");
record = get_most_recent_record("^done", true);
allocated_memory[get_register_value(record)] = allocated_size;
Expand Down

0 comments on commit c1f9237

Please sign in to comment.