| OLD | NEW |
| 1 //===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===// | 1 //===- subzero/src/IceELFObjectWriter.cpp - ELF object file writer --------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file defines the writer for ELF relocatable object files. | 10 // This file defines the writer for ELF relocatable object files. |
| 11 // | 11 // |
| 12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
| 13 | 13 |
| 14 #include "llvm/Support/MathExtras.h" |
| 15 |
| 14 #include "assembler.h" | 16 #include "assembler.h" |
| 15 #include "IceDefs.h" | 17 #include "IceDefs.h" |
| 16 #include "IceELFObjectWriter.h" | 18 #include "IceELFObjectWriter.h" |
| 17 #include "IceELFSection.h" | 19 #include "IceELFSection.h" |
| 18 #include "IceELFStreamer.h" | 20 #include "IceELFStreamer.h" |
| 19 #include "IceGlobalContext.h" | 21 #include "IceGlobalContext.h" |
| 20 #include "IceGlobalInits.h" | 22 #include "IceGlobalInits.h" |
| 21 #include "IceOperand.h" | 23 #include "IceOperand.h" |
| 22 | 24 |
| 23 using namespace llvm::ELF; | 25 using namespace llvm::ELF; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType, | 98 T *ELFObjectWriter::createSection(const IceString &Name, Elf64_Word ShType, |
| 97 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, | 99 Elf64_Xword ShFlags, Elf64_Xword ShAddralign, |
| 98 Elf64_Xword ShEntsize) { | 100 Elf64_Xword ShEntsize) { |
| 99 assert(!SectionNumbersAssigned); | 101 assert(!SectionNumbersAssigned); |
| 100 T *NewSection = | 102 T *NewSection = |
| 101 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); | 103 new (Ctx.allocate<T>()) T(Name, ShType, ShFlags, ShAddralign, ShEntsize); |
| 102 ShStrTab->add(Name); | 104 ShStrTab->add(Name); |
| 103 return NewSection; | 105 return NewSection; |
| 104 } | 106 } |
| 105 | 107 |
| 108 ELFRelocationSection * |
| 109 ELFObjectWriter::createRelocationSection(bool IsELF64, |
| 110 const ELFSection *RelatedSection) { |
| 111 // Choice of RELA vs REL is actually separate from elf64 vs elf32, |
| 112 // but in practice we've only had .rela for elf64 (x86-64). |
| 113 // In the future, the two properties may need to be decoupled |
| 114 // and the ShEntSize can vary more. |
| 115 const Elf64_Word ShType = IsELF64 ? SHT_RELA : SHT_REL; |
| 116 IceString RelPrefix = IsELF64 ? ".rela" : ".rel"; |
| 117 IceString RelSectionName = RelPrefix + RelatedSection->getName(); |
| 118 const Elf64_Xword ShAlign = IsELF64 ? 8 : 4; |
| 119 const Elf64_Xword ShEntSize = |
| 120 IsELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); |
| 121 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, |
| 122 "Elf_Rel/Rela sizes cannot be derived from sizeof"); |
| 123 const Elf64_Xword ShFlags = 0; |
| 124 ELFRelocationSection *RelSection = createSection<ELFRelocationSection>( |
| 125 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); |
| 126 RelSection->setRelatedSection(RelatedSection); |
| 127 return RelSection; |
| 128 } |
| 129 |
| 106 template <typename UserSectionList> | 130 template <typename UserSectionList> |
| 107 void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber, | 131 void ELFObjectWriter::assignRelSectionNumInPairs(SizeT &CurSectionNumber, |
| 108 UserSectionList &UserSections, | 132 UserSectionList &UserSections, |
| 109 RelSectionList &RelSections, | 133 RelSectionList &RelSections, |
| 110 SectionList &AllSections) { | 134 SectionList &AllSections) { |
| 111 RelSectionList::iterator RelIt = RelSections.begin(); | 135 RelSectionList::iterator RelIt = RelSections.begin(); |
| 112 RelSectionList::iterator RelE = RelSections.end(); | 136 RelSectionList::iterator RelE = RelSections.end(); |
| 113 for (ELFSection *UserSection : UserSections) { | 137 for (ELFSection *UserSection : UserSections) { |
| 114 UserSection->setNumber(CurSectionNumber++); | 138 UserSection->setNumber(CurSectionNumber++); |
| 115 UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName())); | 139 UserSection->setNameStrIndex(ShStrTab->getIndex(UserSection->getName())); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 143 assert(!SectionNumbersAssigned); | 167 assert(!SectionNumbersAssigned); |
| 144 SizeT CurSectionNumber = 0; | 168 SizeT CurSectionNumber = 0; |
| 145 NullSection->setNumber(CurSectionNumber++); | 169 NullSection->setNumber(CurSectionNumber++); |
| 146 // The rest of the fields are initialized to 0, and stay that way. | 170 // The rest of the fields are initialized to 0, and stay that way. |
| 147 AllSections.push_back(NullSection); | 171 AllSections.push_back(NullSection); |
| 148 | 172 |
| 149 assignRelSectionNumInPairs<TextSectionList>(CurSectionNumber, TextSections, | 173 assignRelSectionNumInPairs<TextSectionList>(CurSectionNumber, TextSections, |
| 150 RelTextSections, AllSections); | 174 RelTextSections, AllSections); |
| 151 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, DataSections, | 175 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, DataSections, |
| 152 RelDataSections, AllSections); | 176 RelDataSections, AllSections); |
| 153 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, RoDataSections, | 177 for (ELFSection *BSSSection : BSSSections) { |
| 154 RelRoDataSections, AllSections); | 178 BSSSection->setNumber(CurSectionNumber++); |
| 179 BSSSection->setNameStrIndex(ShStrTab->getIndex(BSSSection->getName())); |
| 180 AllSections.push_back(BSSSection); |
| 181 } |
| 182 assignRelSectionNumInPairs<DataSectionList>(CurSectionNumber, RODataSections, |
| 183 RelRODataSections, AllSections); |
| 155 | 184 |
| 156 ShStrTab->setNumber(CurSectionNumber++); | 185 ShStrTab->setNumber(CurSectionNumber++); |
| 157 ShStrTab->setNameStrIndex(ShStrTab->getIndex(ShStrTab->getName())); | 186 ShStrTab->setNameStrIndex(ShStrTab->getIndex(ShStrTab->getName())); |
| 158 AllSections.push_back(ShStrTab); | 187 AllSections.push_back(ShStrTab); |
| 159 | 188 |
| 160 SymTab->setNumber(CurSectionNumber++); | 189 SymTab->setNumber(CurSectionNumber++); |
| 161 SymTab->setNameStrIndex(ShStrTab->getIndex(SymTab->getName())); | 190 SymTab->setNameStrIndex(ShStrTab->getIndex(SymTab->getName())); |
| 162 AllSections.push_back(SymTab); | 191 AllSections.push_back(SymTab); |
| 163 | 192 |
| 164 StrTab->setNumber(CurSectionNumber++); | 193 StrTab->setNumber(CurSectionNumber++); |
| 165 StrTab->setNameStrIndex(ShStrTab->getIndex(StrTab->getName())); | 194 StrTab->setNameStrIndex(ShStrTab->getIndex(StrTab->getName())); |
| 166 AllSections.push_back(StrTab); | 195 AllSections.push_back(StrTab); |
| 167 | 196 |
| 168 SymTab->setLinkNum(StrTab->getNumber()); | 197 SymTab->setLinkNum(StrTab->getNumber()); |
| 169 SymTab->setInfoNum(SymTab->getNumLocals()); | 198 SymTab->setInfoNum(SymTab->getNumLocals()); |
| 170 | 199 |
| 171 assignRelLinkNum(SymTab->getNumber(), RelTextSections); | 200 assignRelLinkNum(SymTab->getNumber(), RelTextSections); |
| 172 assignRelLinkNum(SymTab->getNumber(), RelDataSections); | 201 assignRelLinkNum(SymTab->getNumber(), RelDataSections); |
| 173 assignRelLinkNum(SymTab->getNumber(), RelRoDataSections); | 202 assignRelLinkNum(SymTab->getNumber(), RelRODataSections); |
| 174 SectionNumbersAssigned = true; | 203 SectionNumbersAssigned = true; |
| 175 } | 204 } |
| 176 | 205 |
| 177 Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) { | 206 Elf64_Off ELFObjectWriter::alignFileOffset(Elf64_Xword Align) { |
| 178 assert(llvm::isPowerOf2_32(Align)); | 207 assert(llvm::isPowerOf2_32(Align)); |
| 179 Elf64_Off OffsetInFile = Str.tell(); | 208 Elf64_Off OffsetInFile = Str.tell(); |
| 180 Elf64_Xword Mod = OffsetInFile & (Align - 1); | 209 Elf64_Xword Mod = OffsetInFile & (Align - 1); |
| 181 if (Mod == 0) | 210 if (Mod == 0) |
| 182 return OffsetInFile; | 211 return OffsetInFile; |
| 183 Elf64_Xword AlignDiff = Align - Mod; | 212 Elf64_Xword AlignDiff = Align - Mod; |
| 184 Str.writeZeroPadding(AlignDiff); | 213 Str.writeZeroPadding(AlignDiff); |
| 185 OffsetInFile += AlignDiff; | 214 OffsetInFile += AlignDiff; |
| 186 assert((OffsetInFile & (Align - 1)) == 0); | 215 assert((OffsetInFile & (Align - 1)) == 0); |
| 187 return OffsetInFile; | 216 return OffsetInFile; |
| 188 } | 217 } |
| 189 | 218 |
| 190 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, | 219 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, |
| 191 bool IsInternal, const Assembler *Asm) { | 220 bool IsInternal, const Assembler *Asm) { |
| 192 assert(!SectionNumbersAssigned); | 221 assert(!SectionNumbersAssigned); |
| 193 ELFTextSection *Section = nullptr; | 222 ELFTextSection *Section = nullptr; |
| 223 ELFRelocationSection *RelSection = nullptr; |
| 194 // TODO(jvoung): handle ffunction-sections. | 224 // TODO(jvoung): handle ffunction-sections. |
| 195 IceString SectionName = ".text"; | 225 IceString SectionName = ".text"; |
| 196 if (TextSections.size() == 0) { | 226 bool IsELF64 = isELF64(Ctx.getTargetArch()); |
| 227 if (TextSections.empty()) { |
| 197 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; | 228 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; |
| 198 // TODO(jvoung): Should be bundle size. Grab it from that target? | 229 // TODO(jvoung): Should be bundle size. Grab it from that target? |
| 199 const Elf64_Xword ShAlign = 32; | 230 const Elf64_Xword ShAlign = 32; |
| 200 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, | 231 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 201 ShAlign, 0); | 232 ShAlign, 0); |
| 202 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); | 233 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); |
| 203 Section->setFileOffset(OffsetInFile); | 234 Section->setFileOffset(OffsetInFile); |
| 204 TextSections.push_back(Section); | 235 TextSections.push_back(Section); |
| 236 RelSection = createRelocationSection(IsELF64, Section); |
| 237 RelTextSections.push_back(RelSection); |
| 205 } else { | 238 } else { |
| 206 Section = TextSections[0]; | 239 Section = TextSections[0]; |
| 240 RelSection = RelTextSections[0]; |
| 207 } | 241 } |
| 208 RelocOffsetT OffsetInSection = Section->getCurrentSize(); | 242 RelocOffsetT OffsetInSection = Section->getCurrentSize(); |
| 209 // Function symbols are set to 0 size in the symbol table, | 243 // Function symbols are set to 0 size in the symbol table, |
| 210 // in contrast to data symbols which have a proper size. | 244 // in contrast to data symbols which have a proper size. |
| 211 SizeT SymbolSize = 0; | 245 SizeT SymbolSize = 0; |
| 212 Section->appendData(Str, Asm->getBufferView()); | 246 Section->appendData(Str, Asm->getBufferView()); |
| 213 uint8_t SymbolType; | 247 uint8_t SymbolType; |
| 214 uint8_t SymbolBinding; | 248 uint8_t SymbolBinding; |
| 215 if (IsInternal) { | 249 if (IsInternal) { |
| 216 SymbolType = STT_NOTYPE; | 250 SymbolType = STT_NOTYPE; |
| 217 SymbolBinding = STB_LOCAL; | 251 SymbolBinding = STB_LOCAL; |
| 218 } else { | 252 } else { |
| 219 SymbolType = STT_FUNC; | 253 SymbolType = STT_FUNC; |
| 220 SymbolBinding = STB_GLOBAL; | 254 SymbolBinding = STB_GLOBAL; |
| 221 } | 255 } |
| 222 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, | 256 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, |
| 223 OffsetInSection, SymbolSize); | 257 OffsetInSection, SymbolSize); |
| 224 StrTab->add(FuncName); | 258 StrTab->add(FuncName); |
| 225 | 259 |
| 226 // Create a relocation section for the text section if needed, and copy the | 260 // Create a relocation section for the text section if needed, and copy the |
| 227 // fixup information from per-function Assembler memory to the object | 261 // fixup information from per-function Assembler memory to the object |
| 228 // writer's memory, for writing later. | 262 // writer's memory, for writing later. |
| 229 if (!Asm->fixups().empty()) { | 263 if (!Asm->fixups().empty()) { |
| 230 bool IsELF64 = isELF64(Ctx.getTargetArch()); | |
| 231 IceString RelSectionName = IsELF64 ? ".rela" : ".rel"; | |
| 232 RelSectionName += SectionName; | |
| 233 ELFRelocationSection *RelSection = nullptr; | |
| 234 // TODO(jvoung): Make this more efficient if -ffunction-sections | |
| 235 // efficiency becomes a problem. | |
| 236 auto RSI = | |
| 237 std::find_if(RelTextSections.begin(), RelTextSections.end(), | |
| 238 [&RelSectionName](const ELFRelocationSection *S) | |
| 239 -> bool { return S->getName() == RelSectionName; }); | |
| 240 if (RSI != RelTextSections.end()) { | |
| 241 RelSection = *RSI; | |
| 242 } else { | |
| 243 const Elf64_Word ShType = IsELF64 ? SHT_RELA : SHT_REL; | |
| 244 const Elf64_Xword ShAlign = IsELF64 ? 8 : 4; | |
| 245 const Elf64_Xword ShEntSize = | |
| 246 IsELF64 ? sizeof(Elf64_Rela) : sizeof(Elf32_Rel); | |
| 247 static_assert(sizeof(Elf64_Rela) == 24 && sizeof(Elf32_Rel) == 8, | |
| 248 "Elf_Rel/Rela sizes cannot be derived from sizeof"); | |
| 249 const Elf64_Xword ShFlags = 0; | |
| 250 RelSection = createSection<ELFRelocationSection>( | |
| 251 RelSectionName, ShType, ShFlags, ShAlign, ShEntSize); | |
| 252 RelSection->setRelatedSection(Section); | |
| 253 RelTextSections.push_back(RelSection); | |
| 254 } | |
| 255 RelSection->addRelocations(OffsetInSection, Asm->fixups()); | 264 RelSection->addRelocations(OffsetInSection, Asm->fixups()); |
| 256 } | 265 } |
| 257 } | 266 } |
| 258 | 267 |
| 259 void ELFObjectWriter::writeDataInitializer(const IceString &VarName, | 268 namespace { |
| 260 const llvm::StringRef Data) { | 269 |
| 270 ELFObjectWriter::SectionType |
| 271 classifyGlobalSection(const VariableDeclaration *Var) { |
| 272 if (Var->getIsConstant()) |
| 273 return ELFObjectWriter::ROData; |
| 274 if (Var->hasNonzeroInitializer()) |
| 275 return ELFObjectWriter::Data; |
| 276 return ELFObjectWriter::BSS; |
| 277 } |
| 278 |
| 279 // TODO(jvoung): dedupe, use the GlobalContext version |
| 280 // https://codereview.chromium.org/870653002/diff/200001/src/IceGlobalContext.h |
| 281 bool matchSymbolName(const IceString &SymbolName, const IceString &Match) { |
| 282 return Match.empty() || Match == SymbolName; |
| 283 } |
| 284 |
| 285 // Partition the Vars list by SectionType into VarsBySection. |
| 286 // If TranslateOnly is non-empty, then only the TranslateOnly variable |
| 287 // is kept for emission. |
| 288 void partitionGlobalsBySection(const VariableDeclarationList &Vars, |
| 289 VariableDeclarationList VarsBySection[], |
| 290 const IceString &TranslateOnly) { |
| 291 for (auto Var : Vars) { |
| 292 if (matchSymbolName(Var->getName(), TranslateOnly)) { |
| 293 size_t Section = classifyGlobalSection(Var); |
| 294 assert(Section < ELFObjectWriter::SectionType::NumSectionTypes); |
| 295 VarsBySection[Section].push_back(Var); |
| 296 } |
| 297 } |
| 298 } |
| 299 |
| 300 } // end of anonymous namespace |
| 301 |
| 302 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, |
| 303 FixupKind RelocationKind) { |
| 261 assert(!SectionNumbersAssigned); | 304 assert(!SectionNumbersAssigned); |
| 262 (void)Data; | 305 VariableDeclarationList VarsBySection[ELFObjectWriter::NumSectionTypes]; |
| 263 llvm_unreachable("TODO"); | 306 for (auto &SectionList : VarsBySection) |
| 264 StrTab->add(VarName); | 307 SectionList.reserve(Vars.size()); |
| 308 partitionGlobalsBySection(Vars, VarsBySection, Ctx.getFlags().TranslateOnly); |
| 309 bool IsELF64 = isELF64(Ctx.getTargetArch()); |
| 310 for (size_t I = ELFObjectWriter::BaseSectionType; |
| 311 I < ELFObjectWriter::NumSectionTypes; ++I) { |
| 312 writeDataOfType(static_cast<SectionType>(I), VarsBySection[I], |
| 313 RelocationKind, IsELF64); |
| 314 } |
| 315 } |
| 316 |
| 317 void ELFObjectWriter::writeDataOfType(SectionType SectionType, |
| 318 const VariableDeclarationList &Vars, |
| 319 FixupKind RelocationKind, bool IsELF64) { |
| 320 ELFDataSection *Section; |
| 321 ELFRelocationSection *RelSection; |
| 322 // TODO(jvoung): Handle fdata-sections. |
| 323 IceString SectionName; |
| 324 Elf64_Xword ShAddralign = 0; // Actual load-time alignment unknown for now. |
| 325 const Elf64_Xword ShEntsize = 0; // non-uniform data element size. |
| 326 // Lift this out, so it can be re-used if we do fdata-sections? |
| 327 switch (SectionType) { |
| 328 case SectionType::ROData: { |
| 329 SectionName = ".rodata"; |
| 330 // Only expecting to write the data sections all in one shot for now. |
| 331 assert(RODataSections.empty()); |
| 332 // Create the section. |
| 333 // A bunch of these properties can be looked up from a table |
| 334 // so make it into a defs file? |
| 335 const Elf64_Xword ShFlags = SHF_ALLOC; |
| 336 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 337 ShAddralign, ShEntsize); |
| 338 // Assume file offset doesn't need to be aligned by much (only the |
| 339 // sh_addralign is sensitive to the data alignment requirements) |
| 340 Section->setFileOffset(alignFileOffset(4)); |
| 341 RODataSections.push_back(Section); |
| 342 RelSection = createRelocationSection(IsELF64, Section); |
| 343 RelRODataSections.push_back(RelSection); |
| 344 break; |
| 345 } |
| 346 case SectionType::Data: { |
| 347 SectionName = ".data"; |
| 348 assert(DataSections.empty()); |
| 349 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; |
| 350 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 351 ShAddralign, ShEntsize); |
| 352 Section->setFileOffset(alignFileOffset(4)); |
| 353 DataSections.push_back(Section); |
| 354 RelSection = createRelocationSection(IsELF64, Section); |
| 355 RelDataSections.push_back(RelSection); |
| 356 break; |
| 357 } |
| 358 case SectionType::BSS: { |
| 359 SectionName = ".bss"; |
| 360 assert(BSSSections.empty()); |
| 361 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; |
| 362 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags, |
| 363 ShAddralign, ShEntsize); |
| 364 Section->setFileOffset(alignFileOffset(4)); |
| 365 BSSSections.push_back(Section); |
| 366 break; |
| 367 } |
| 368 case SectionType::NumSectionTypes: |
| 369 llvm_unreachable("Unknown SectionType"); |
| 370 break; |
| 371 } |
| 372 |
| 373 const uint8_t SymbolType = STT_OBJECT; |
| 374 bool WritePadding = SectionType != SectionType::BSS; |
| 375 for (auto *Var : Vars) { |
| 376 Elf64_Xword Align = Var->getAlignment(); |
| 377 |
| 378 Section->padToAlignment(Str, WritePadding, Align); |
| 379 ShAddralign = std::max(ShAddralign, Align); |
| 380 |
| 381 SizeT SymbolSize = Var->getNumBytes(); |
| 382 bool IsExternal = Var->isExternal() || Ctx.getFlags().DisableInternal; |
| 383 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; |
| 384 IceString MangledName = Var->mangleName(&Ctx); |
| 385 SymTab->createDefinedSym(MangledName, SymbolType, SymbolBinding, Section, |
| 386 Section->getCurrentSize(), SymbolSize); |
| 387 StrTab->add(MangledName); |
| 388 if (!Var->hasNonzeroInitializer()) { |
| 389 assert(SectionType == SectionType::BSS || |
| 390 SectionType == SectionType::ROData); |
| 391 if (SectionType == SectionType::ROData) |
| 392 Section->appendZeros(Str, SymbolSize); |
| 393 else |
| 394 Section->setSize(Section->getCurrentSize() + SymbolSize); |
| 395 } else { |
| 396 assert(SectionType != SectionType::BSS); |
| 397 for (VariableDeclaration::Initializer *Init : Var->getInitializers()) { |
| 398 switch (Init->getKind()) { |
| 399 case VariableDeclaration::Initializer::DataInitializerKind: { |
| 400 const auto Data = llvm::cast<VariableDeclaration::DataInitializer>( |
| 401 Init)->getContents(); |
| 402 Section->appendData(Str, llvm::StringRef(Data.data(), Data.size())); |
| 403 break; |
| 404 } |
| 405 case VariableDeclaration::Initializer::ZeroInitializerKind: |
| 406 Section->appendZeros(Str, Init->getNumBytes()); |
| 407 break; |
| 408 case VariableDeclaration::Initializer::RelocInitializerKind: { |
| 409 const auto Reloc = |
| 410 llvm::cast<VariableDeclaration::RelocInitializer>(Init); |
| 411 AssemblerFixup NewFixup; |
| 412 NewFixup.set_position(Section->getCurrentSize()); |
| 413 NewFixup.set_kind(RelocationKind); |
| 414 const bool SuppressMangling = true; |
| 415 NewFixup.set_value(Ctx.getConstantSym( |
| 416 Reloc->getOffset(), Reloc->getDeclaration()->mangleName(&Ctx), |
| 417 SuppressMangling)); |
| 418 RelSection->addRelocation(NewFixup); |
| 419 Section->appendRelocationOffset(Str, RelSection->isRela(), |
| 420 Reloc->getOffset()); |
| 421 break; |
| 422 } |
| 423 } |
| 424 } |
| 425 } |
| 426 } |
| 427 Section->setAlignment(ShAddralign); |
| 265 } | 428 } |
| 266 | 429 |
| 267 void ELFObjectWriter::writeInitialELFHeader() { | 430 void ELFObjectWriter::writeInitialELFHeader() { |
| 268 assert(!SectionNumbersAssigned); | 431 assert(!SectionNumbersAssigned); |
| 269 const Elf64_Off DummySHOffset = 0; | 432 const Elf64_Off DummySHOffset = 0; |
| 270 const SizeT DummySHStrIndex = 0; | 433 const SizeT DummySHStrIndex = 0; |
| 271 const SizeT DummyNumSections = 0; | 434 const SizeT DummyNumSections = 0; |
| 272 if (isELF64(Ctx.getTargetArch())) { | 435 if (isELF64(Ctx.getTargetArch())) { |
| 273 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, | 436 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, |
| 274 DummyNumSections); | 437 DummyNumSections); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 // between entries. | 501 // between entries. |
| 339 assert(WriteAmt % Align == 0); | 502 assert(WriteAmt % Align == 0); |
| 340 // Check that we write the full PrimType. | 503 // Check that we write the full PrimType. |
| 341 assert(WriteAmt == sizeof(typename ConstType::PrimType)); | 504 assert(WriteAmt == sizeof(typename ConstType::PrimType)); |
| 342 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; | 505 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; |
| 343 std::string SecBuffer; | 506 std::string SecBuffer; |
| 344 llvm::raw_string_ostream SecStrBuf(SecBuffer); | 507 llvm::raw_string_ostream SecStrBuf(SecBuffer); |
| 345 SecStrBuf << ".rodata.cst" << WriteAmt; | 508 SecStrBuf << ".rodata.cst" << WriteAmt; |
| 346 ELFDataSection *Section = createSection<ELFDataSection>( | 509 ELFDataSection *Section = createSection<ELFDataSection>( |
| 347 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); | 510 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); |
| 348 RoDataSections.push_back(Section); | 511 RODataSections.push_back(Section); |
| 349 SizeT OffsetInSection = 0; | 512 SizeT OffsetInSection = 0; |
| 350 // The symbol table entry doesn't need to know the defined symbol's | 513 // The symbol table entry doesn't need to know the defined symbol's |
| 351 // size since this is in a section with a fixed Entry Size. | 514 // size since this is in a section with a fixed Entry Size. |
| 352 const SizeT SymbolSize = 0; | 515 const SizeT SymbolSize = 0; |
| 353 Section->setFileOffset(alignFileOffset(Align)); | 516 Section->setFileOffset(alignFileOffset(Align)); |
| 354 | 517 |
| 355 // Write the data. | 518 // Write the data. |
| 356 for (Constant *C : Pool) { | 519 for (Constant *C : Pool) { |
| 357 auto Const = llvm::cast<ConstType>(C); | 520 auto Const = llvm::cast<ConstType>(C); |
| 358 std::string SymBuffer; | 521 std::string SymBuffer; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 375 // We may need to instantiate constant pools for integers as well | 538 // We may need to instantiate constant pools for integers as well |
| 376 // if we do constant-pooling of large integers to remove them | 539 // if we do constant-pooling of large integers to remove them |
| 377 // from the instruction stream (fewer bytes controlled by an attacker). | 540 // from the instruction stream (fewer bytes controlled by an attacker). |
| 378 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); | 541 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); |
| 379 | 542 |
| 380 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); | 543 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); |
| 381 | 544 |
| 382 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { | 545 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { |
| 383 writeRelocationSections(IsELF64, RelTextSections); | 546 writeRelocationSections(IsELF64, RelTextSections); |
| 384 writeRelocationSections(IsELF64, RelDataSections); | 547 writeRelocationSections(IsELF64, RelDataSections); |
| 385 writeRelocationSections(IsELF64, RelRoDataSections); | 548 writeRelocationSections(IsELF64, RelRODataSections); |
| 386 } | 549 } |
| 387 | 550 |
| 388 void ELFObjectWriter::writeRelocationSections(bool IsELF64, | 551 void ELFObjectWriter::writeRelocationSections(bool IsELF64, |
| 389 RelSectionList &RelSections) { | 552 RelSectionList &RelSections) { |
| 390 for (ELFRelocationSection *RelSec : RelSections) { | 553 for (ELFRelocationSection *RelSec : RelSections) { |
| 391 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); | 554 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); |
| 392 RelSec->setFileOffset(Offset); | 555 RelSec->setFileOffset(Offset); |
| 393 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab)); | 556 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab)); |
| 394 if (IsELF64) { | 557 if (IsELF64) { |
| 395 RelSec->writeData<true>(Ctx, Str, SymTab); | 558 RelSec->writeData<true>(Ctx, Str, SymTab); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 if (IsELF64) { | 607 if (IsELF64) { |
| 445 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 608 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
| 446 AllSections.size()); | 609 AllSections.size()); |
| 447 } else { | 610 } else { |
| 448 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 611 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
| 449 AllSections.size()); | 612 AllSections.size()); |
| 450 } | 613 } |
| 451 } | 614 } |
| 452 | 615 |
| 453 } // end of namespace Ice | 616 } // end of namespace Ice |
| OLD | NEW |