Index: llvm/tools/llc/StubMaker.cpp |
=================================================================== |
--- a/llvm/tools/llc/StubMaker.cpp |
+++ b/llvm/tools/llc/StubMaker.cpp |
@@ -88,17 +88,22 @@ |
llvm_unreachable("Unknown visibility in GETELFVisibility"); |
} |
-// Return a value for the symbol table's st_size, which is the number of bytes |
-// in a data object. This may be 0 if the size is unknown. |
-static ELF::Elf32_Word GetELFSize(const GlobalValue *GV) { |
- const class PointerType *PT = GV->getType(); |
- const Type *ElemType = PT->getElementType(); |
+static ELF::Elf32_Word GetElfSizeForType(const GlobalValue *GV, |
+ const Type *ElemType) { |
unsigned bit_size = ElemType->getPrimitiveSizeInBits(); |
if (bit_size != 0) { |
return bit_size / 8; |
} |
+ if (isa<PointerType>(ElemType)) { |
+ // Pointers are 32-bit for NaCl. |
+ return 4; |
+ } |
+ if (isa<FunctionType>(ElemType)) { |
+ // This is not a data object, so just say unknown (0). |
+ return 0; |
+ } |
if (const ArrayType *ATy = dyn_cast<ArrayType>(ElemType)) { |
- unsigned elem_bit_size = ATy->getElementType()->getPrimitiveSizeInBits(); |
+ unsigned elem_bit_size = GetElfSizeForType(GV, ATy->getElementType()); |
if (elem_bit_size != 0) { |
unsigned num_elems = ATy->getNumElements(); |
if (num_elems != 0) { |
@@ -106,10 +111,45 @@ |
} |
} |
} |
- // For other cases, claim that we don't know the size (0). |
+ if (const VectorType *VTy = dyn_cast<VectorType>(ElemType)) { |
+ unsigned bit_width = VTy->getBitWidth(); |
+ if (bit_width) { |
+ return bit_width / 8; |
+ } else { |
+ // It's a vector of pointers, and pointers are 32-bit in NaCl |
+ return VTy->getNumElements() * 4; |
+ } |
+ } |
+ if (const StructType *STy = dyn_cast<StructType>(ElemType)) { |
+ // Alignment padding should have been added to the type in the front-end. |
+ unsigned size_so_far = 0; |
+ for (unsigned i = 0; i < STy->getNumElements(); ++i) { |
+ size_so_far += GetElfSizeForType(GV, STy->getElementType(i)); |
+ } |
+ return size_so_far; |
+ } |
+ // Unknown type! |
+ DEBUG({ |
+ dbgs() << "Unknown GetELFSize for var="; |
+ GV->dump(); |
+ dbgs() << " type= "; |
+ ElemType->dump(); |
+ dbgs() << "\n"; |
+ }); |
+ llvm_unreachable("Unhandled type for GetELFSize"); |
return 0; |
} |
+// Return a value for the symbol table's st_size, which is the number of bytes |
+// in a data object. Functions may report unknown size 0 (not data objects). |
+// This is known to be important for symbols that may sit in BSS |
+// with copy relocations (to know how much to copy). |
+static ELF::Elf32_Word GetELFSize(const GlobalValue *GV) { |
+ const class PointerType *PT = GV->getType(); |
+ const Type *ElemType = PT->getElementType(); |
+ return GetElfSizeForType(GV, ElemType); |
+} |
+ |
static unsigned char GetELFType(const GlobalValue *GV) { |
if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { |
return GVar->isThreadLocal() ? ELF::STT_TLS : ELF::STT_OBJECT; |