| 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;
|
|
|