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 } |
| 97 if (isa<PointerType>(ElemType)) { |
| 98 // Pointers are 32-bit for NaCl. |
| 99 return 4; |
| 100 } |
| 101 if (isa<FunctionType>(ElemType)) { |
| 102 // This is not a data object, so just say unknown (0). |
| 103 return 0; |
| 104 } |
100 if (const ArrayType *ATy = dyn_cast<ArrayType>(ElemType)) { | 105 if (const ArrayType *ATy = dyn_cast<ArrayType>(ElemType)) { |
101 unsigned elem_bit_size = ATy->getElementType()->getPrimitiveSizeInBits(); | 106 unsigned elem_bit_size = GetElfSizeForType(GV, ATy->getElementType()); |
102 if (elem_bit_size != 0) { | 107 if (elem_bit_size != 0) { |
103 unsigned num_elems = ATy->getNumElements(); | 108 unsigned num_elems = ATy->getNumElements(); |
104 if (num_elems != 0) { | 109 if (num_elems != 0) { |
105 return elem_bit_size * num_elems / 8; | 110 return elem_bit_size * num_elems / 8; |
106 } | 111 } |
107 } | 112 } |
108 } | 113 } |
109 // For other cases, claim that we don't know the size (0). | 114 if (const VectorType *VTy = dyn_cast<VectorType>(ElemType)) { |
| 115 unsigned bit_width = VTy->getBitWidth(); |
| 116 if (bit_width) { |
| 117 return bit_width / 8; |
| 118 } else { |
| 119 // It's a vector of pointers, and pointers are 32-bit in NaCl |
| 120 return VTy->getNumElements() * 4; |
| 121 } |
| 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({ |
| 133 dbgs() << "Unknown GetELFSize for var="; |
| 134 GV->dump(); |
| 135 dbgs() << " type= "; |
| 136 ElemType->dump(); |
| 137 dbgs() << "\n"; |
| 138 }); |
| 139 llvm_unreachable("Unhandled type for GetELFSize"); |
110 return 0; | 140 return 0; |
111 } | 141 } |
112 | 142 |
| 143 // Return a value for the symbol table's st_size, which is the number of bytes |
| 144 // in a data object. Functions may report unknown size 0 (not data objects). |
| 145 // This is known to be important for symbols that may sit in BSS |
| 146 // with copy relocations (to know how much to copy). |
| 147 static ELF::Elf32_Word GetELFSize(const GlobalValue *GV) { |
| 148 const class PointerType *PT = GV->getType(); |
| 149 const Type *ElemType = PT->getElementType(); |
| 150 return GetElfSizeForType(GV, ElemType); |
| 151 } |
| 152 |
113 static unsigned char GetELFType(const GlobalValue *GV) { | 153 static unsigned char GetELFType(const GlobalValue *GV) { |
114 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { | 154 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { |
115 return GVar->isThreadLocal() ? ELF::STT_TLS : ELF::STT_OBJECT; | 155 return GVar->isThreadLocal() ? ELF::STT_TLS : ELF::STT_OBJECT; |
116 } else if (isa<Function>(GV)) { | 156 } else if (isa<Function>(GV)) { |
117 // TODO(pdox): Handle STT_GNU_IFUNC | 157 // TODO(pdox): Handle STT_GNU_IFUNC |
118 return ELF::STT_FUNC; | 158 return ELF::STT_FUNC; |
119 } | 159 } |
120 // TODO(pdox): Do we need to resolve GlobalAliases? | 160 // TODO(pdox): Do we need to resolve GlobalAliases? |
121 llvm_unreachable("Unknown GlobalValue type in GetELFType!"); | 161 llvm_unreachable("Unknown GlobalValue type in GetELFType!"); |
122 } | 162 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 } | 220 } |
181 | 221 |
182 void FreeStubList(llvm::SmallVectorImpl<ELFStub*> *StubList) { | 222 void FreeStubList(llvm::SmallVectorImpl<ELFStub*> *StubList) { |
183 for (unsigned i = 0; i < StubList->size(); ++i) { | 223 for (unsigned i = 0; i < StubList->size(); ++i) { |
184 delete (*StubList)[i]; | 224 delete (*StubList)[i]; |
185 } | 225 } |
186 StubList->clear(); | 226 StubList->clear(); |
187 } | 227 } |
188 | 228 |
189 } // namespace | 229 } // namespace |
OLD | NEW |