OLD | NEW |
---|---|
1 // Create a high-level representation of the needed library. | 1 // Create a high-level representation of the needed library. |
2 | 2 |
3 #include "StubMaker.h" | 3 #include "StubMaker.h" |
4 | 4 |
5 #include "llvm/ADT/StringMap.h" | 5 #include "llvm/ADT/StringMap.h" |
6 #include "llvm/ADT/StringRef.h" | 6 #include "llvm/ADT/StringRef.h" |
7 #include "llvm/ADT/Triple.h" | 7 #include "llvm/ADT/Triple.h" |
8 #include "llvm/DerivedTypes.h" | 8 #include "llvm/DerivedTypes.h" |
9 #include "llvm/Support/ELF.h" | 9 #include "llvm/Support/ELF.h" |
10 #include "llvm/Support/ErrorHandling.h" | 10 #include "llvm/Support/ErrorHandling.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 | 81 |
82 static unsigned char GetELFVisibility(const GlobalValue *GV) { | 82 static unsigned char GetELFVisibility(const GlobalValue *GV) { |
83 switch (GV->getVisibility()) { | 83 switch (GV->getVisibility()) { |
84 case GlobalValue::DefaultVisibility: return ELF::STV_DEFAULT; | 84 case GlobalValue::DefaultVisibility: return ELF::STV_DEFAULT; |
85 case GlobalValue::HiddenVisibility: return ELF::STV_HIDDEN; | 85 case GlobalValue::HiddenVisibility: return ELF::STV_HIDDEN; |
86 case GlobalValue::ProtectedVisibility: return ELF::STV_PROTECTED; | 86 case GlobalValue::ProtectedVisibility: return ELF::STV_PROTECTED; |
87 } | 87 } |
88 llvm_unreachable("Unknown visibility in GETELFVisibility"); | 88 llvm_unreachable("Unknown visibility in GETELFVisibility"); |
89 } | 89 } |
90 | 90 |
91 // Return a value for the symbol table's st_size, which is the number of bytes | 91 static ELF::Elf32_Word GetElfSizeForType(const GlobalValue *GV, |
92 // in a data object. This may be 0 if the size is unknown. | 92 const Type *ElemType) { |
93 static ELF::Elf32_Word GetELFSize(const GlobalValue *GV) { | |
94 const class PointerType *PT = GV->getType(); | |
95 const Type *ElemType = PT->getElementType(); | |
96 unsigned bit_size = ElemType->getPrimitiveSizeInBits(); | 93 unsigned bit_size = ElemType->getPrimitiveSizeInBits(); |
97 if (bit_size != 0) { | 94 if (bit_size != 0) { |
98 return bit_size / 8; | 95 return bit_size / 8; |
99 } | 96 } |
100 if (const ArrayType *ATy = dyn_cast<ArrayType>(ElemType)) { | 97 if (const ArrayType *ATy = dyn_cast<ArrayType>(ElemType)) { |
101 unsigned elem_bit_size = ATy->getElementType()->getPrimitiveSizeInBits(); | 98 unsigned elem_bit_size = ATy->getElementType()->getPrimitiveSizeInBits(); |
102 if (elem_bit_size != 0) { | 99 if (elem_bit_size != 0) { |
103 unsigned num_elems = ATy->getNumElements(); | 100 unsigned num_elems = ATy->getNumElements(); |
104 if (num_elems != 0) { | 101 if (num_elems != 0) { |
105 return elem_bit_size * num_elems / 8; | 102 return elem_bit_size * num_elems / 8; |
106 } | 103 } |
107 } | 104 } |
108 } | 105 } |
109 // For other cases, claim that we don't know the size (0). | 106 if (const VectorType *VTy = dyn_cast<VectorType>(ElemType)) { |
107 unsigned bit_width = VTy->getBitWidth(); | |
108 if (bit_width) { | |
109 return bit_width / 8; | |
110 } else { | |
111 // It's a vector of pointers, and pointers are 32-bit in NaCl | |
112 return VTy->getNumElements() * 4; | |
113 } | |
114 } | |
115 if (isa<PointerType>(ElemType)) { | |
116 // Pointers are 32-bit for NaCl. | |
117 return 4; | |
118 } | |
119 if (isa<FunctionType>(ElemType)) { | |
120 // This is not a data object, so shouldn't be in BSS. Just say unknown (0). | |
121 return 0; | |
122 } | |
123 if (const StructType *STy = dyn_cast<StructType>(ElemType)) { | |
124 // Alignment padding should have been added to the type in the front-end. | |
125 unsigned size_so_far = 0; | |
126 for (unsigned i = 0; i < STy->getNumElements(); ++i) { | |
127 size_so_far += GetElfSizeForType(GV, STy->getElementType(i)); | |
128 } | |
129 return size_so_far; | |
130 } | |
131 // Unknown type! | |
132 DEBUG({ | |
robertm
2012/04/25 17:42:07
would it be better to assert for now?
otherwise we
jvoung - send to chromium...
2012/04/25 18:20:51
Good point. Switched over to an assert and already
jvoung - send to chromium...
2012/04/25 18:22:19
Err... n/m about the PSO stub. The header file sho
| |
133 dbgs() << "Unknown GetELFSize for var="; | |
134 GV->dump(); | |
135 dbgs() << " type= "; | |
136 ElemType->dump(); | |
137 dbgs() << "\n"; | |
138 }); | |
110 return 0; | 139 return 0; |
111 } | 140 } |
112 | 141 |
142 // Return a value for the symbol table's st_size, which is the number of bytes | |
143 // in a data object. This is important for symbols that may sit in BSS | |
robertm
2012/04/25 17:42:07
why wouldn't it also be important for non bss symb
jvoung - send to chromium...
2012/04/25 18:20:51
Well, I'm not sure, but I don't think it matters f
| |
144 // with copy relocations. This may be 0 if the size is unknown. | |
145 static ELF::Elf32_Word GetELFSize(const GlobalValue *GV) { | |
146 const class PointerType *PT = GV->getType(); | |
147 const Type *ElemType = PT->getElementType(); | |
148 return GetElfSizeForType(GV, ElemType); | |
149 } | |
150 | |
113 static unsigned char GetELFType(const GlobalValue *GV) { | 151 static unsigned char GetELFType(const GlobalValue *GV) { |
114 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { | 152 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { |
115 return GVar->isThreadLocal() ? ELF::STT_TLS : ELF::STT_OBJECT; | 153 return GVar->isThreadLocal() ? ELF::STT_TLS : ELF::STT_OBJECT; |
116 } else if (isa<Function>(GV)) { | 154 } else if (isa<Function>(GV)) { |
117 // TODO(pdox): Handle STT_GNU_IFUNC | 155 // TODO(pdox): Handle STT_GNU_IFUNC |
118 return ELF::STT_FUNC; | 156 return ELF::STT_FUNC; |
119 } | 157 } |
120 // TODO(pdox): Do we need to resolve GlobalAliases? | 158 // TODO(pdox): Do we need to resolve GlobalAliases? |
121 llvm_unreachable("Unknown GlobalValue type in GetELFType!"); | 159 llvm_unreachable("Unknown GlobalValue type in GetELFType!"); |
122 } | 160 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 } | 218 } |
181 | 219 |
182 void FreeStubList(llvm::SmallVectorImpl<ELFStub*> *StubList) { | 220 void FreeStubList(llvm::SmallVectorImpl<ELFStub*> *StubList) { |
183 for (unsigned i = 0; i < StubList->size(); ++i) { | 221 for (unsigned i = 0; i < StubList->size(); ++i) { |
184 delete (*StubList)[i]; | 222 delete (*StubList)[i]; |
185 } | 223 } |
186 StubList->clear(); | 224 StubList->clear(); |
187 } | 225 } |
188 | 226 |
189 } // namespace | 227 } // namespace |
OLD | NEW |