1

While reversing a C++ program compiled with g++, I've seen a _ZNSs4_Rep20_S_empty_rep_storageE being used. Running it through c++filt shows that before mangling it's a:

std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_empty_rep_storage

But what is this _S_empty_rep_storage used for? I included an assembly snippet below where it's used:

mov     rax, cs:_ZNSs4_Rep20_S_empty_rep_storageE_ptr
...
add     rax, 18h
...
mov     [rsp+328h+var_308], rax
mov     [rsp+328h+var_2F8], rax
mov     [rsp+328h+var_2E8], rax
...
lea     r14, [rsp+328h+var_308]
lea     rsi, [rsp+328h+var_2D8] ; std::string *
mov     rdi, r14        ; this
call    __ZNSs4swapERSs ; std::string::swap(std::string &)
lea     rdi, [rsp+328h+var_2D8] ; this
lea     r13, [rsp+328h+var_2F8]
lea     r12, [rsp+328h+var_2E8]
call    __ZNSsD1Ev      ; std::string::~string()

So my question is: What's the purpose of _S_empty_rep_storage here? Also why are var_308, var_2f8 and var_2e8 lea'd into r12-14? These registers are not used later on.

2

Check the comments at the beginning of libstdc++'s basic_string.h to see how GCC's std::string works.Basically, _S_empty_rep_storage is a pre-initialized (in fact, zeroed out) representation of an empty string, used to initialize the string in a default constructor. So var_308, var_2F8 and var_2E8 are three std::string objects, initialized to an empty string.

As for r12-r14, they seem to be used as temporary variables. We can at leas see that r14 is used to initialize rdi - the this pointer for the std::string::swap() call, so presumably r12 and r13 are also used later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.