Chromium Code Reviews| 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)); | |
| 179 Elf64_Off OffsetInFile = Str.tell(); | 207 Elf64_Off OffsetInFile = Str.tell(); |
| 180 Elf64_Xword Mod = OffsetInFile & (Align - 1); | 208 Elf64_Xword AlignDiff = Utils::OffsetToAlignment(OffsetInFile, Align); |
| 181 if (Mod == 0) | 209 if (AlignDiff == 0) |
| 182 return OffsetInFile; | 210 return OffsetInFile; |
| 183 Elf64_Xword AlignDiff = Align - Mod; | |
| 184 Str.writeZeroPadding(AlignDiff); | 211 Str.writeZeroPadding(AlignDiff); |
| 185 OffsetInFile += AlignDiff; | 212 OffsetInFile += AlignDiff; |
| 186 assert((OffsetInFile & (Align - 1)) == 0); | |
| 187 return OffsetInFile; | 213 return OffsetInFile; |
| 188 } | 214 } |
| 189 | 215 |
| 190 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, | 216 void ELFObjectWriter::writeFunctionCode(const IceString &FuncName, |
| 191 bool IsInternal, const Assembler *Asm) { | 217 bool IsInternal, const Assembler *Asm) { |
| 192 assert(!SectionNumbersAssigned); | 218 assert(!SectionNumbersAssigned); |
| 193 ELFTextSection *Section = nullptr; | 219 ELFTextSection *Section = nullptr; |
| 194 // TODO(jvoung): handle ffunction-sections. | 220 ELFRelocationSection *RelSection = nullptr; |
| 195 IceString SectionName = ".text"; | 221 if (TextSections.empty()) { |
| 196 if (TextSections.size() == 0) { | 222 // TODO(jvoung): handle ffunction-sections. |
| 223 IceString SectionName = ".text"; | |
| 224 bool IsELF64 = isELF64(Ctx.getTargetArch()); | |
| 197 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; | 225 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_EXECINSTR; |
| 198 // TODO(jvoung): Should be bundle size. Grab it from that target? | 226 // TODO(jvoung): Should be bundle size. Grab it from that target? |
| 199 const Elf64_Xword ShAlign = 32; | 227 const Elf64_Xword ShAlign = 32; |
| 200 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, | 228 Section = createSection<ELFTextSection>(SectionName, SHT_PROGBITS, ShFlags, |
| 201 ShAlign, 0); | 229 ShAlign, 0); |
| 202 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); | 230 Elf64_Off OffsetInFile = alignFileOffset(Section->getSectionAlign()); |
| 203 Section->setFileOffset(OffsetInFile); | 231 Section->setFileOffset(OffsetInFile); |
| 204 TextSections.push_back(Section); | 232 TextSections.push_back(Section); |
| 233 RelSection = createRelocationSection(IsELF64, Section); | |
| 234 RelTextSections.push_back(RelSection); | |
| 205 } else { | 235 } else { |
| 206 Section = TextSections[0]; | 236 Section = TextSections[0]; |
| 237 RelSection = RelTextSections[0]; | |
| 207 } | 238 } |
| 208 RelocOffsetT OffsetInSection = Section->getCurrentSize(); | 239 RelocOffsetT OffsetInSection = Section->getCurrentSize(); |
| 209 // Function symbols are set to 0 size in the symbol table, | 240 // Function symbols are set to 0 size in the symbol table, |
| 210 // in contrast to data symbols which have a proper size. | 241 // in contrast to data symbols which have a proper size. |
| 211 SizeT SymbolSize = 0; | 242 SizeT SymbolSize = 0; |
| 212 Section->appendData(Str, Asm->getBufferView()); | 243 Section->appendData(Str, Asm->getBufferView()); |
| 213 uint8_t SymbolType; | 244 uint8_t SymbolType; |
| 214 uint8_t SymbolBinding; | 245 uint8_t SymbolBinding; |
| 215 if (IsInternal) { | 246 if (IsInternal) { |
| 216 SymbolType = STT_NOTYPE; | 247 SymbolType = STT_NOTYPE; |
| 217 SymbolBinding = STB_LOCAL; | 248 SymbolBinding = STB_LOCAL; |
| 218 } else { | 249 } else { |
| 219 SymbolType = STT_FUNC; | 250 SymbolType = STT_FUNC; |
| 220 SymbolBinding = STB_GLOBAL; | 251 SymbolBinding = STB_GLOBAL; |
| 221 } | 252 } |
| 222 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, | 253 SymTab->createDefinedSym(FuncName, SymbolType, SymbolBinding, Section, |
| 223 OffsetInSection, SymbolSize); | 254 OffsetInSection, SymbolSize); |
| 224 StrTab->add(FuncName); | 255 StrTab->add(FuncName); |
| 225 | 256 |
| 226 // Create a relocation section for the text section if needed, and copy the | 257 // Create a relocation section for the text section if needed, and copy the |
| 227 // fixup information from per-function Assembler memory to the object | 258 // fixup information from per-function Assembler memory to the object |
| 228 // writer's memory, for writing later. | 259 // writer's memory, for writing later. |
| 229 if (!Asm->fixups().empty()) { | 260 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()); | 261 RelSection->addRelocations(OffsetInSection, Asm->fixups()); |
| 256 } | 262 } |
| 257 } | 263 } |
| 258 | 264 |
| 259 void ELFObjectWriter::writeDataInitializer(const IceString &VarName, | 265 namespace { |
| 260 const llvm::StringRef Data) { | 266 |
| 267 ELFObjectWriter::SectionType | |
| 268 classifyGlobalSection(const VariableDeclaration *Var) { | |
| 269 if (Var->getIsConstant()) | |
| 270 return ELFObjectWriter::ROData; | |
| 271 if (Var->hasNonzeroInitializer()) | |
| 272 return ELFObjectWriter::Data; | |
| 273 return ELFObjectWriter::BSS; | |
| 274 } | |
| 275 | |
| 276 // Partition the Vars list by SectionType into VarsBySection. | |
| 277 // If TranslateOnly is non-empty, then only the TranslateOnly variable | |
| 278 // is kept for emission. | |
| 279 void partitionGlobalsBySection(const VariableDeclarationList &Vars, | |
| 280 VariableDeclarationList VarsBySection[], | |
| 281 const IceString &TranslateOnly) { | |
| 282 for (VariableDeclaration *Var : Vars) { | |
| 283 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | |
| 284 size_t Section = classifyGlobalSection(Var); | |
| 285 assert(Section < ELFObjectWriter::SectionType::NumSectionTypes); | |
| 286 VarsBySection[Section].push_back(Var); | |
| 287 } | |
| 288 } | |
| 289 } | |
| 290 | |
| 291 } // end of anonymous namespace | |
| 292 | |
| 293 void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars, | |
| 294 FixupKind RelocationKind) { | |
| 261 assert(!SectionNumbersAssigned); | 295 assert(!SectionNumbersAssigned); |
| 262 (void)Data; | 296 VariableDeclarationList VarsBySection[ELFObjectWriter::NumSectionTypes]; |
| 263 llvm_unreachable("TODO"); | 297 for (auto &SectionList : VarsBySection) |
| 264 StrTab->add(VarName); | 298 SectionList.reserve(Vars.size()); |
| 299 partitionGlobalsBySection(Vars, VarsBySection, Ctx.getFlags().TranslateOnly); | |
| 300 bool IsELF64 = isELF64(Ctx.getTargetArch()); | |
| 301 for (size_t I = ELFObjectWriter::BaseSectionType; | |
|
Jim Stichnoth
2015/01/28 20:35:08
Consider doing something like this to make the sec
jvoung (off chromium)
2015/01/28 23:37:52
Done sort of -- If I is type SectionType, then I++
Jim Stichnoth
2015/01/29 00:38:14
BTW, JF pointed out this would be possible using a
| |
| 302 I < ELFObjectWriter::NumSectionTypes; ++I) { | |
| 303 writeDataOfType(static_cast<SectionType>(I), VarsBySection[I], | |
| 304 RelocationKind, IsELF64); | |
| 305 } | |
| 306 } | |
| 307 | |
| 308 void ELFObjectWriter::writeDataOfType(SectionType SectionType, | |
| 309 const VariableDeclarationList &Vars, | |
| 310 FixupKind RelocationKind, bool IsELF64) { | |
| 311 ELFDataSection *Section; | |
| 312 ELFRelocationSection *RelSection; | |
| 313 // TODO(jvoung): Handle fdata-sections. | |
| 314 IceString SectionName; | |
| 315 Elf64_Xword ShAddralign = 0; | |
| 316 for (auto *Var : Vars) { | |
|
Jim Stichnoth
2015/01/28 20:35:08
auto --> VariableDeclaration
jvoung (off chromium)
2015/01/28 23:37:53
Done.
| |
| 317 Elf64_Xword Align = Var->getAlignment(); | |
| 318 ShAddralign = std::max(ShAddralign, Align); | |
| 319 } | |
| 320 const Elf64_Xword ShEntsize = 0; // non-uniform data element size. | |
| 321 // Lift this out, so it can be re-used if we do fdata-sections? | |
| 322 switch (SectionType) { | |
| 323 case SectionType::ROData: { | |
| 324 SectionName = ".rodata"; | |
| 325 // Only expecting to write the data sections all in one shot for now. | |
| 326 assert(RODataSections.empty()); | |
| 327 const Elf64_Xword ShFlags = SHF_ALLOC; | |
| 328 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, | |
| 329 ShAddralign, ShEntsize); | |
| 330 Section->setFileOffset(alignFileOffset(ShAddralign)); | |
| 331 RODataSections.push_back(Section); | |
| 332 RelSection = createRelocationSection(IsELF64, Section); | |
| 333 RelRODataSections.push_back(RelSection); | |
| 334 break; | |
| 335 } | |
| 336 case SectionType::Data: { | |
| 337 SectionName = ".data"; | |
| 338 assert(DataSections.empty()); | |
| 339 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; | |
| 340 Section = createSection<ELFDataSection>(SectionName, SHT_PROGBITS, ShFlags, | |
| 341 ShAddralign, ShEntsize); | |
| 342 Section->setFileOffset(alignFileOffset(ShAddralign)); | |
| 343 DataSections.push_back(Section); | |
| 344 RelSection = createRelocationSection(IsELF64, Section); | |
| 345 RelDataSections.push_back(RelSection); | |
| 346 break; | |
| 347 } | |
| 348 case SectionType::BSS: { | |
| 349 SectionName = ".bss"; | |
| 350 assert(BSSSections.empty()); | |
| 351 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_WRITE; | |
| 352 Section = createSection<ELFDataSection>(SectionName, SHT_NOBITS, ShFlags, | |
| 353 ShAddralign, ShEntsize); | |
| 354 Section->setFileOffset(alignFileOffset(ShAddralign)); | |
| 355 BSSSections.push_back(Section); | |
| 356 break; | |
| 357 } | |
| 358 case SectionType::NumSectionTypes: | |
| 359 llvm::report_fatal_error("Unknown SectionType"); | |
| 360 break; | |
| 361 } | |
| 362 | |
| 363 const uint8_t SymbolType = STT_OBJECT; | |
| 364 for (auto *Var : Vars) { | |
|
Jim Stichnoth
2015/01/28 20:35:08
auto --> VariableDeclaration
jvoung (off chromium)
2015/01/28 23:37:53
Done.
| |
| 365 Elf64_Xword Align = Var->getAlignment(); | |
| 366 Section->padToAlignment(Str, Align); | |
| 367 SizeT SymbolSize = Var->getNumBytes(); | |
| 368 bool IsExternal = Var->isExternal() || Ctx.getFlags().DisableInternal; | |
| 369 const uint8_t SymbolBinding = IsExternal ? STB_GLOBAL : STB_LOCAL; | |
| 370 IceString MangledName = Var->mangleName(&Ctx); | |
| 371 SymTab->createDefinedSym(MangledName, SymbolType, SymbolBinding, Section, | |
| 372 Section->getCurrentSize(), SymbolSize); | |
| 373 StrTab->add(MangledName); | |
| 374 if (!Var->hasNonzeroInitializer()) { | |
| 375 assert(SectionType == SectionType::BSS || | |
| 376 SectionType == SectionType::ROData); | |
| 377 if (SectionType == SectionType::ROData) | |
| 378 Section->appendZeros(Str, SymbolSize); | |
| 379 else | |
| 380 Section->setSize(Section->getCurrentSize() + SymbolSize); | |
| 381 } else { | |
| 382 assert(SectionType != SectionType::BSS); | |
| 383 for (VariableDeclaration::Initializer *Init : Var->getInitializers()) { | |
| 384 switch (Init->getKind()) { | |
| 385 case VariableDeclaration::Initializer::DataInitializerKind: { | |
| 386 const auto Data = llvm::cast<VariableDeclaration::DataInitializer>( | |
| 387 Init)->getContents(); | |
| 388 Section->appendData(Str, llvm::StringRef(Data.data(), Data.size())); | |
| 389 break; | |
| 390 } | |
| 391 case VariableDeclaration::Initializer::ZeroInitializerKind: | |
| 392 Section->appendZeros(Str, Init->getNumBytes()); | |
| 393 break; | |
| 394 case VariableDeclaration::Initializer::RelocInitializerKind: { | |
| 395 const auto Reloc = | |
| 396 llvm::cast<VariableDeclaration::RelocInitializer>(Init); | |
| 397 AssemblerFixup NewFixup; | |
| 398 NewFixup.set_position(Section->getCurrentSize()); | |
| 399 NewFixup.set_kind(RelocationKind); | |
| 400 const bool SuppressMangling = true; | |
| 401 NewFixup.set_value(Ctx.getConstantSym( | |
| 402 Reloc->getOffset(), Reloc->getDeclaration()->mangleName(&Ctx), | |
| 403 SuppressMangling)); | |
| 404 RelSection->addRelocation(NewFixup); | |
| 405 Section->appendRelocationOffset(Str, RelSection->isRela(), | |
| 406 Reloc->getOffset()); | |
| 407 break; | |
| 408 } | |
| 409 } | |
| 410 } | |
| 411 } | |
| 412 } | |
| 265 } | 413 } |
| 266 | 414 |
| 267 void ELFObjectWriter::writeInitialELFHeader() { | 415 void ELFObjectWriter::writeInitialELFHeader() { |
| 268 assert(!SectionNumbersAssigned); | 416 assert(!SectionNumbersAssigned); |
| 269 const Elf64_Off DummySHOffset = 0; | 417 const Elf64_Off DummySHOffset = 0; |
| 270 const SizeT DummySHStrIndex = 0; | 418 const SizeT DummySHStrIndex = 0; |
| 271 const SizeT DummyNumSections = 0; | 419 const SizeT DummyNumSections = 0; |
| 272 if (isELF64(Ctx.getTargetArch())) { | 420 if (isELF64(Ctx.getTargetArch())) { |
| 273 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, | 421 writeELFHeaderInternal<true>(DummySHOffset, DummySHStrIndex, |
| 274 DummyNumSections); | 422 DummyNumSections); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 // between entries. | 486 // between entries. |
| 339 assert(WriteAmt % Align == 0); | 487 assert(WriteAmt % Align == 0); |
| 340 // Check that we write the full PrimType. | 488 // Check that we write the full PrimType. |
| 341 assert(WriteAmt == sizeof(typename ConstType::PrimType)); | 489 assert(WriteAmt == sizeof(typename ConstType::PrimType)); |
| 342 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; | 490 const Elf64_Xword ShFlags = SHF_ALLOC | SHF_MERGE; |
| 343 std::string SecBuffer; | 491 std::string SecBuffer; |
| 344 llvm::raw_string_ostream SecStrBuf(SecBuffer); | 492 llvm::raw_string_ostream SecStrBuf(SecBuffer); |
| 345 SecStrBuf << ".rodata.cst" << WriteAmt; | 493 SecStrBuf << ".rodata.cst" << WriteAmt; |
| 346 ELFDataSection *Section = createSection<ELFDataSection>( | 494 ELFDataSection *Section = createSection<ELFDataSection>( |
| 347 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); | 495 SecStrBuf.str(), SHT_PROGBITS, ShFlags, Align, WriteAmt); |
| 348 RoDataSections.push_back(Section); | 496 RODataSections.push_back(Section); |
| 349 SizeT OffsetInSection = 0; | 497 SizeT OffsetInSection = 0; |
| 350 // The symbol table entry doesn't need to know the defined symbol's | 498 // 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. | 499 // size since this is in a section with a fixed Entry Size. |
| 352 const SizeT SymbolSize = 0; | 500 const SizeT SymbolSize = 0; |
| 353 Section->setFileOffset(alignFileOffset(Align)); | 501 Section->setFileOffset(alignFileOffset(Align)); |
| 354 | 502 |
| 355 // Write the data. | 503 // Write the data. |
| 356 for (Constant *C : Pool) { | 504 for (Constant *C : Pool) { |
| 357 auto Const = llvm::cast<ConstType>(C); | 505 auto Const = llvm::cast<ConstType>(C); |
| 358 std::string SymBuffer; | 506 std::string SymBuffer; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 375 // We may need to instantiate constant pools for integers as well | 523 // We may need to instantiate constant pools for integers as well |
| 376 // if we do constant-pooling of large integers to remove them | 524 // if we do constant-pooling of large integers to remove them |
| 377 // from the instruction stream (fewer bytes controlled by an attacker). | 525 // from the instruction stream (fewer bytes controlled by an attacker). |
| 378 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); | 526 template void ELFObjectWriter::writeConstantPool<ConstantFloat>(Type Ty); |
| 379 | 527 |
| 380 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); | 528 template void ELFObjectWriter::writeConstantPool<ConstantDouble>(Type Ty); |
| 381 | 529 |
| 382 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { | 530 void ELFObjectWriter::writeAllRelocationSections(bool IsELF64) { |
| 383 writeRelocationSections(IsELF64, RelTextSections); | 531 writeRelocationSections(IsELF64, RelTextSections); |
| 384 writeRelocationSections(IsELF64, RelDataSections); | 532 writeRelocationSections(IsELF64, RelDataSections); |
| 385 writeRelocationSections(IsELF64, RelRoDataSections); | 533 writeRelocationSections(IsELF64, RelRODataSections); |
| 386 } | 534 } |
| 387 | 535 |
| 388 void ELFObjectWriter::writeRelocationSections(bool IsELF64, | 536 void ELFObjectWriter::writeRelocationSections(bool IsELF64, |
| 389 RelSectionList &RelSections) { | 537 RelSectionList &RelSections) { |
| 390 for (ELFRelocationSection *RelSec : RelSections) { | 538 for (ELFRelocationSection *RelSec : RelSections) { |
| 391 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); | 539 Elf64_Off Offset = alignFileOffset(RelSec->getSectionAlign()); |
| 392 RelSec->setFileOffset(Offset); | 540 RelSec->setFileOffset(Offset); |
| 393 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab)); | 541 RelSec->setSize(RelSec->getSectionDataSize(Ctx, SymTab)); |
| 394 if (IsELF64) { | 542 if (IsELF64) { |
| 395 RelSec->writeData<true>(Ctx, Str, SymTab); | 543 RelSec->writeData<true>(Ctx, Str, SymTab); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 444 if (IsELF64) { | 592 if (IsELF64) { |
| 445 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), | 593 writeELFHeaderInternal<true>(ShOffset, ShStrTab->getNumber(), |
| 446 AllSections.size()); | 594 AllSections.size()); |
| 447 } else { | 595 } else { |
| 448 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), | 596 writeELFHeaderInternal<false>(ShOffset, ShStrTab->getNumber(), |
| 449 AllSections.size()); | 597 AllSections.size()); |
| 450 } | 598 } |
| 451 } | 599 } |
| 452 | 600 |
| 453 } // end of namespace Ice | 601 } // end of namespace Ice |
| OLD | NEW |