Chromium Code Reviews| 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 |