1*3e457fe3SDavid van Moolenbroek #include <magic/support/BitFieldAggregation.h>
2*3e457fe3SDavid van Moolenbroek
3*3e457fe3SDavid van Moolenbroek using namespace llvm;
4*3e457fe3SDavid van Moolenbroek
5*3e457fe3SDavid van Moolenbroek namespace llvm {
6*3e457fe3SDavid van Moolenbroek
7*3e457fe3SDavid van Moolenbroek #define DEBUG_BFA 0
8*3e457fe3SDavid van Moolenbroek
9*3e457fe3SDavid van Moolenbroek #define BitFieldAggregation_assert_or_return(R,RV,T,ET,X) do { \
10*3e457fe3SDavid van Moolenbroek if(!(X)) { \
11*3e457fe3SDavid van Moolenbroek if(R) return RV; \
12*3e457fe3SDavid van Moolenbroek errs() << "Assertion failed, dumping types...\n"; \
13*3e457fe3SDavid van Moolenbroek errs() << TypeUtil::getDescription(T, ET); \
14*3e457fe3SDavid van Moolenbroek } \
15*3e457fe3SDavid van Moolenbroek assert(X); \
16*3e457fe3SDavid van Moolenbroek } while(0)
17*3e457fe3SDavid van Moolenbroek
18*3e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
19*3e457fe3SDavid van Moolenbroek // Constructors, destructor, and operators
20*3e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
21*3e457fe3SDavid van Moolenbroek
BitFieldAggregation(TYPECONST Type * type,std::vector<EDIType> EDITypes,unsigned typeIndex,unsigned EDITypeIndex,std::vector<DIDerivedType> members,unsigned counter)22*3e457fe3SDavid van Moolenbroek BitFieldAggregation::BitFieldAggregation(TYPECONST Type* type, std::vector<EDIType> EDITypes, unsigned typeIndex, unsigned EDITypeIndex, std::vector<DIDerivedType> members, unsigned counter) {
23*3e457fe3SDavid van Moolenbroek init(type, EDITypes, typeIndex, EDITypeIndex, members, counter);
24*3e457fe3SDavid van Moolenbroek }
25*3e457fe3SDavid van Moolenbroek
BitFieldAggregation()26*3e457fe3SDavid van Moolenbroek BitFieldAggregation::BitFieldAggregation() {
27*3e457fe3SDavid van Moolenbroek type = NULL;
28*3e457fe3SDavid van Moolenbroek typeIndex = 0;
29*3e457fe3SDavid van Moolenbroek EDITypeIndex = 0;
30*3e457fe3SDavid van Moolenbroek name = "";
31*3e457fe3SDavid van Moolenbroek }
32*3e457fe3SDavid van Moolenbroek
init(TYPECONST Type * type,std::vector<EDIType> EDITypes,unsigned typeIndex,unsigned EDITypeIndex,std::vector<DIDerivedType> members,unsigned counter)33*3e457fe3SDavid van Moolenbroek void BitFieldAggregation::init(TYPECONST Type* type, std::vector<EDIType> EDITypes, unsigned typeIndex, unsigned EDITypeIndex, std::vector<DIDerivedType> members, unsigned counter) {
34*3e457fe3SDavid van Moolenbroek assert(members.size() == EDITypes.size());
35*3e457fe3SDavid van Moolenbroek assert(typeIndex <= EDITypeIndex);
36*3e457fe3SDavid van Moolenbroek size = members.size();
37*3e457fe3SDavid van Moolenbroek assert(size > 0);
38*3e457fe3SDavid van Moolenbroek
39*3e457fe3SDavid van Moolenbroek this->type = type;
40*3e457fe3SDavid van Moolenbroek this->EDITypes = EDITypes;
41*3e457fe3SDavid van Moolenbroek this->typeIndex = typeIndex;
42*3e457fe3SDavid van Moolenbroek this->EDITypeIndex = EDITypeIndex;
43*3e457fe3SDavid van Moolenbroek this->members = members;
44*3e457fe3SDavid van Moolenbroek raw_string_ostream ostream(name);
45*3e457fe3SDavid van Moolenbroek ostream << bfaNamePrefix << counter;
46*3e457fe3SDavid van Moolenbroek ostream.flush();
47*3e457fe3SDavid van Moolenbroek }
48*3e457fe3SDavid van Moolenbroek
49*3e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
50*3e457fe3SDavid van Moolenbroek // Getters
51*3e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
52*3e457fe3SDavid van Moolenbroek
getDescription() const53*3e457fe3SDavid van Moolenbroek const std::string BitFieldAggregation::getDescription() const {
54*3e457fe3SDavid van Moolenbroek std::string string;
55*3e457fe3SDavid van Moolenbroek raw_string_ostream ostream(string);
56*3e457fe3SDavid van Moolenbroek ostream << "[\nname = " << name << "\nmembers = ";
57*3e457fe3SDavid van Moolenbroek for(unsigned i=0;i<size;i++) {
58*3e457fe3SDavid van Moolenbroek ostream << (i==0 ? "" : ", ") << members[i].getName();
59*3e457fe3SDavid van Moolenbroek }
60*3e457fe3SDavid van Moolenbroek ostream << "\ntype = \n" << TypeUtil::getDescription(getType());
61*3e457fe3SDavid van Moolenbroek std::vector<EDIType> EDITypes = getEDITypes();
62*3e457fe3SDavid van Moolenbroek for(unsigned i=0;i<EDITypes.size();i++) {
63*3e457fe3SDavid van Moolenbroek ostream << "\nEDIType" << i << " =\n" << TypeUtil::getDescription(&EDITypes[i]);
64*3e457fe3SDavid van Moolenbroek }
65*3e457fe3SDavid van Moolenbroek ostream << "\n]";
66*3e457fe3SDavid van Moolenbroek ostream.flush();
67*3e457fe3SDavid van Moolenbroek return string;
68*3e457fe3SDavid van Moolenbroek }
69*3e457fe3SDavid van Moolenbroek
70*3e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
71*3e457fe3SDavid van Moolenbroek // Public static methods
72*3e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
73*3e457fe3SDavid van Moolenbroek
getBitFieldAggregations(TYPECONST Type * type,const EDIType * aEDIType,std::vector<BitFieldAggregation> & bfas,bool returnOnError)74*3e457fe3SDavid van Moolenbroek bool BitFieldAggregation::getBitFieldAggregations(TYPECONST Type *type, const EDIType *aEDIType, std::vector<BitFieldAggregation> &bfas, bool returnOnError) {
75*3e457fe3SDavid van Moolenbroek std::vector<BitFieldAggregation> emptyBfas;
76*3e457fe3SDavid van Moolenbroek if(!hasBitFields(type, aEDIType)) {
77*3e457fe3SDavid van Moolenbroek return true;
78*3e457fe3SDavid van Moolenbroek }
79*3e457fe3SDavid van Moolenbroek unsigned typeIndex = 0;
80*3e457fe3SDavid van Moolenbroek unsigned EDITypeIndex = 0;
81*3e457fe3SDavid van Moolenbroek unsigned typeContainedTypes = type->getNumContainedTypes();
82*3e457fe3SDavid van Moolenbroek unsigned aEDITypeContainedTypes = aEDIType->getNumContainedTypes();
83*3e457fe3SDavid van Moolenbroek unsigned counter = 1;
84*3e457fe3SDavid van Moolenbroek const EDIType privateEDIType(*aEDIType);
85*3e457fe3SDavid van Moolenbroek aEDIType = &privateEDIType;
86*3e457fe3SDavid van Moolenbroek while(typeIndex < typeContainedTypes) {
87*3e457fe3SDavid van Moolenbroek TYPECONST Type *containedType = type->getContainedType(typeIndex);
88*3e457fe3SDavid van Moolenbroek if(EDITypeIndex >= aEDITypeContainedTypes && typeIndex == typeContainedTypes-1 && TypeUtil::isPaddedType(type)) {
89*3e457fe3SDavid van Moolenbroek break;
90*3e457fe3SDavid van Moolenbroek }
91*3e457fe3SDavid van Moolenbroek BitFieldAggregation_assert_or_return(returnOnError, false, type, aEDIType, EDITypeIndex < aEDITypeContainedTypes);
92*3e457fe3SDavid van Moolenbroek const EDIType containedEDIType = aEDIType->getContainedType(EDITypeIndex);
93*3e457fe3SDavid van Moolenbroek unsigned typeBits = TypeUtil::typeToBits(containedType);
94*3e457fe3SDavid van Moolenbroek if(typeBits > 0 && containedEDIType.isIntegerTy()) {
95*3e457fe3SDavid van Moolenbroek unsigned EDITypeBits = aEDIType->getMember(EDITypeIndex).getSizeInBits();
96*3e457fe3SDavid van Moolenbroek assert(typeBits >= EDITypeBits);
97*3e457fe3SDavid van Moolenbroek if(typeBits > EDITypeBits) {
98*3e457fe3SDavid van Moolenbroek unsigned lastTypeIndex = typeIndex;
99*3e457fe3SDavid van Moolenbroek unsigned lastEDITypeIndex = EDITypeIndex;
100*3e457fe3SDavid van Moolenbroek while(lastEDITypeIndex+1 < aEDITypeContainedTypes && isBitField(type, aEDIType, lastEDITypeIndex+1)) { // grab all the bitfields following the first one found
101*3e457fe3SDavid van Moolenbroek lastEDITypeIndex++;
102*3e457fe3SDavid van Moolenbroek EDITypeBits += aEDIType->getMember(lastEDITypeIndex).getSizeInBits();
103*3e457fe3SDavid van Moolenbroek }
104*3e457fe3SDavid van Moolenbroek while(lastTypeIndex+1 < typeContainedTypes && EDITypeBits > typeBits) { // grab all the necessary fields to cover all the bits found in the bitfields
105*3e457fe3SDavid van Moolenbroek lastTypeIndex++;
106*3e457fe3SDavid van Moolenbroek typeBits += TypeUtil::typeToBits(type->getContainedType(lastTypeIndex));
107*3e457fe3SDavid van Moolenbroek }
108*3e457fe3SDavid van Moolenbroek BitFieldAggregation *bfa = BitFieldAggregation::getBitFieldAggregation(type, aEDIType, returnOnError, typeIndex, EDITypeIndex, lastTypeIndex, lastEDITypeIndex, counter++);
109*3e457fe3SDavid van Moolenbroek BitFieldAggregation_assert_or_return(returnOnError, false, type, aEDIType, bfa != NULL);
110*3e457fe3SDavid van Moolenbroek if(bfa->getSize() > 1) {
111*3e457fe3SDavid van Moolenbroek //we don't care about single-element aggregates
112*3e457fe3SDavid van Moolenbroek bfas.push_back(*bfa);
113*3e457fe3SDavid van Moolenbroek }
114*3e457fe3SDavid van Moolenbroek typeIndex++;
115*3e457fe3SDavid van Moolenbroek EDITypeIndex += bfa->getSize();
116*3e457fe3SDavid van Moolenbroek continue;
117*3e457fe3SDavid van Moolenbroek }
118*3e457fe3SDavid van Moolenbroek }
119*3e457fe3SDavid van Moolenbroek typeIndex++;
120*3e457fe3SDavid van Moolenbroek EDITypeIndex++;
121*3e457fe3SDavid van Moolenbroek }
122*3e457fe3SDavid van Moolenbroek return true;
123*3e457fe3SDavid van Moolenbroek }
124*3e457fe3SDavid van Moolenbroek
getBitFieldAggregation(TYPECONST Type * type,const EDIType * aEDIType,bool returnOnError,unsigned typeIndex,unsigned EDITypeIndex,unsigned lastTypeIndex,unsigned lastEDITypeIndex,unsigned counter)125*3e457fe3SDavid van Moolenbroek BitFieldAggregation *BitFieldAggregation::getBitFieldAggregation(TYPECONST Type *type, const EDIType *aEDIType, bool returnOnError, unsigned typeIndex, unsigned EDITypeIndex, unsigned lastTypeIndex, unsigned lastEDITypeIndex, unsigned counter) {
126*3e457fe3SDavid van Moolenbroek static BitFieldAggregation bfa;
127*3e457fe3SDavid van Moolenbroek TYPECONST Type *containedType = type->getContainedType(typeIndex);
128*3e457fe3SDavid van Moolenbroek unsigned typeBits = TypeUtil::typeToBits(containedType);
129*3e457fe3SDavid van Moolenbroek assert(typeBits > 0);
130*3e457fe3SDavid van Moolenbroek unsigned nextTypeBits = 0;
131*3e457fe3SDavid van Moolenbroek if (typeIndex < lastTypeIndex) {
132*3e457fe3SDavid van Moolenbroek nextTypeBits = TypeUtil::typeToBits(type->getContainedType(typeIndex+1));
133*3e457fe3SDavid van Moolenbroek }
134*3e457fe3SDavid van Moolenbroek const int maxNumMembers = (lastEDITypeIndex - EDITypeIndex) - (lastTypeIndex - typeIndex) + 1;
135*3e457fe3SDavid van Moolenbroek unsigned index = EDITypeIndex;
136*3e457fe3SDavid van Moolenbroek std::vector<DIDerivedType> members;
137*3e457fe3SDavid van Moolenbroek std::vector<EDIType> containedEDITypes;
138*3e457fe3SDavid van Moolenbroek
139*3e457fe3SDavid van Moolenbroek BitFieldAggregation_assert_or_return(returnOnError, NULL, type, aEDIType, maxNumMembers > 0);
140*3e457fe3SDavid van Moolenbroek #if DEBUG_BFA
141*3e457fe3SDavid van Moolenbroek BitFieldAggregationErr("getBitFieldAggregation(): typeIndex = " << typeIndex << ", EDITypeIndex = " << EDITypeIndex << ", maxNumMembers = " << maxNumMembers);
142*3e457fe3SDavid van Moolenbroek BitFieldAggregationErr("getBitFieldAggregation(): lastTypeIndex = " << lastTypeIndex << ", lastEDITypeIndex = " << lastEDITypeIndex);
143*3e457fe3SDavid van Moolenbroek BitFieldAggregationErr("getBitFieldAggregation(): " << TypeUtil::getDescription(type) << " VS " << TypeUtil::getDescription(aEDIType));
144*3e457fe3SDavid van Moolenbroek #endif
145*3e457fe3SDavid van Moolenbroek while(index <= lastEDITypeIndex && members.size() < (unsigned)maxNumMembers) {
146*3e457fe3SDavid van Moolenbroek const EDIType containedEDIType = aEDIType->getContainedType(index);
147*3e457fe3SDavid van Moolenbroek #if DEBUG_BFA
148*3e457fe3SDavid van Moolenbroek BitFieldAggregationErr("Examining type " << TypeUtil::getDescription(&containedEDIType));
149*3e457fe3SDavid van Moolenbroek #endif
150*3e457fe3SDavid van Moolenbroek BitFieldAggregation_assert_or_return(returnOnError, NULL, type, aEDIType, containedEDIType.isIntegerTy());
151*3e457fe3SDavid van Moolenbroek DIDerivedType member = aEDIType->getMember(index);
152*3e457fe3SDavid van Moolenbroek unsigned EDITypeBits = member.getSizeInBits();
153*3e457fe3SDavid van Moolenbroek #if DEBUG_BFA
154*3e457fe3SDavid van Moolenbroek BitFieldAggregationErr("Type bits = " << typeBits << ", next type bits = " << nextTypeBits << ", index = " << index);
155*3e457fe3SDavid van Moolenbroek BitFieldAggregationErr("This is member " << member.getName() << " with bits " << EDITypeBits);
156*3e457fe3SDavid van Moolenbroek #endif
157*3e457fe3SDavid van Moolenbroek if((index > EDITypeIndex && EDITypeBits == nextTypeBits) || EDITypeBits > typeBits) {
158*3e457fe3SDavid van Moolenbroek break;
159*3e457fe3SDavid van Moolenbroek }
160*3e457fe3SDavid van Moolenbroek typeBits -= EDITypeBits;
161*3e457fe3SDavid van Moolenbroek members.push_back(member);
162*3e457fe3SDavid van Moolenbroek containedEDITypes.push_back(containedEDIType);
163*3e457fe3SDavid van Moolenbroek index++;
164*3e457fe3SDavid van Moolenbroek }
165*3e457fe3SDavid van Moolenbroek bfa.init(containedType, containedEDITypes, typeIndex, EDITypeIndex, members, counter);
166*3e457fe3SDavid van Moolenbroek return &bfa;
167*3e457fe3SDavid van Moolenbroek }
168*3e457fe3SDavid van Moolenbroek
169*3e457fe3SDavid van Moolenbroek std::string BitFieldAggregation::bfaNamePrefix = BFA_NAME_PREFIX;
170*3e457fe3SDavid van Moolenbroek
171*3e457fe3SDavid van Moolenbroek }
172