Hello all,
my goal is to extract parameter values of function calls and therefore I
use getLocalVariableValue(...). This works quite well so far but not in
case the parameter is a struct. getLocalVariableValue() uses
Type::getSize() which calls typeStruct::updateSize() in case of a
struct. This method just calculates the sum of the sizes of all struct
elements. The problem I have is when padding comes into play, e.g.:
struct st {
int i; // 4 Bytes
char c; // 1 Byte + 3 Bytes padding
float f; // 4 Bytes
}
The size of struct st is 12 Bytes on my machine but getSize() returns 9.
getLocalVariableValue() uses this wrong size to fill the result buffer
with 9 Bytes of information. This buffer then contains the 3 Bytes of
padding but not the last 3 Bytes of the float. Nevertheless,
getLocalVariableValue() returns 0 to indicate everything went well, even
if thats obviously not the case. In order to solve that I made a little
patch that considers padding within the struct but not at the end (which
is fine for me so far). I'm really not an expert in DynInst so I don't
know if this breaks something or not. Perhaps I miss something that
already solves my problem?
--- a/symtabAPI/src/Type.C
+++ b/symtabAPI/src/Type.C
@@ -197,7 +197,9 @@ unsigned int Type::getSize()
{
- if (!size_)
+ // If default constructed, update
+ if (!size_ || (size_ == sizeof(int)))
const_cast<Type *>(this)->updateSize();
return size_;
}
@@ -896,15 +898,25 @@ void typeStruct::updateSize()
// Calculate the size of the entire structure
size_ = 0;
- for(unsigned int i = 0; i < fieldList.size(); ++i) {
- size_ += fieldList[i]->getSize();
- // Is the type of this field still a placeholder?
- if(fieldList[i]->getType()->getDataClass() == dataUnknownType) {
- size_ = 0;
- break;
- }
- }
+
+ // considers padding
+ Field* lastElement = fieldList.back();
+ size_ = (lastElement->getOffset() / 8) + lastElement->getSize();
Best regards,
Fabian
|