| OLD | NEW |
| 1 //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===// | 1 //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===// |
| 2 // | 2 // |
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
| 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 implements ELF object file writer information. | 10 // This file implements ELF object file writer information. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 case MCSymbolRefExpr::VK_INDNTPOFF: | 91 case MCSymbolRefExpr::VK_INDNTPOFF: |
| 92 case MCSymbolRefExpr::VK_NTPOFF: | 92 case MCSymbolRefExpr::VK_NTPOFF: |
| 93 case MCSymbolRefExpr::VK_GOTNTPOFF: | 93 case MCSymbolRefExpr::VK_GOTNTPOFF: |
| 94 case MCSymbolRefExpr::VK_TLSLDM: | 94 case MCSymbolRefExpr::VK_TLSLDM: |
| 95 case MCSymbolRefExpr::VK_DTPOFF: | 95 case MCSymbolRefExpr::VK_DTPOFF: |
| 96 case MCSymbolRefExpr::VK_TLSLD: | 96 case MCSymbolRefExpr::VK_TLSLD: |
| 97 return true; | 97 return true; |
| 98 } | 98 } |
| 99 } | 99 } |
| 100 | 100 |
| 101 namespace { | 101 //===- ELFObjectWriter -------------------===// |
| 102 ELFObjectWriter::~ELFObjectWriter() |
| 103 {} |
| 102 | 104 |
| 103 class ELFObjectWriterImpl { | 105 void ELFObjectWriter::String8(MCDataFragment &F, uint8_t Value) { |
| 104 /*static bool isFixupKindX86RIPRel(unsigned Kind) { | 106 char buf[1]; |
| 105 return Kind == X86::reloc_riprel_4byte || | 107 buf[0] = Value; |
| 106 Kind == X86::reloc_riprel_4byte_movq_load; | 108 F.getContents() += StringRef(buf, 1); |
| 107 }*/ | 109 } |
| 110 |
| 111 void ELFObjectWriter::String16(MCDataFragment &F, uint16_t Value) { |
| 112 char buf[2]; |
| 113 if (isLittleEndian()) |
| 114 StringLE16(buf, Value); |
| 115 else |
| 116 StringBE16(buf, Value); |
| 117 F.getContents() += StringRef(buf, 2); |
| 118 } |
| 119 |
| 120 void ELFObjectWriter::String32(MCDataFragment &F, uint32_t Value) { |
| 121 char buf[4]; |
| 122 if (isLittleEndian()) |
| 123 StringLE32(buf, Value); |
| 124 else |
| 125 StringBE32(buf, Value); |
| 126 F.getContents() += StringRef(buf, 4); |
| 127 } |
| 128 |
| 129 void ELFObjectWriter::String64(MCDataFragment &F, uint64_t Value) { |
| 130 char buf[8]; |
| 131 if (isLittleEndian()) |
| 132 StringLE64(buf, Value); |
| 133 else |
| 134 StringBE64(buf, Value); |
| 135 F.getContents() += StringRef(buf, 8); |
| 136 } |
| 108 | 137 |
| 109 | 138 |
| 110 /// ELFSymbolData - Helper struct for containing some precomputed informatio
n | |
| 111 /// on symbols. | |
| 112 struct ELFSymbolData { | |
| 113 MCSymbolData *SymbolData; | |
| 114 uint64_t StringIndex; | |
| 115 uint32_t SectionIndex; | |
| 116 | |
| 117 // Support lexicographic sorting. | |
| 118 bool operator<(const ELFSymbolData &RHS) const { | |
| 119 if (GetType(*SymbolData) == ELF::STT_FILE) | |
| 120 return true; | |
| 121 if (GetType(*RHS.SymbolData) == ELF::STT_FILE) | |
| 122 return false; | |
| 123 return SymbolData->getSymbol().getName() < | |
| 124 RHS.SymbolData->getSymbol().getName(); | |
| 125 } | |
| 126 }; | |
| 127 | |
| 128 /// @name Relocation Data | |
| 129 /// @{ | |
| 130 | |
| 131 struct ELFRelocationEntry { | |
| 132 // Make these big enough for both 32-bit and 64-bit | |
| 133 uint64_t r_offset; | |
| 134 int Index; | |
| 135 unsigned Type; | |
| 136 const MCSymbol *Symbol; | |
| 137 uint64_t r_addend; | |
| 138 | |
| 139 // Support lexicographic sorting. | |
| 140 bool operator<(const ELFRelocationEntry &RE) const { | |
| 141 return RE.r_offset < r_offset; | |
| 142 } | |
| 143 }; | |
| 144 | |
| 145 SmallPtrSet<const MCSymbol *, 16> UsedInReloc; | |
| 146 SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; | |
| 147 DenseMap<const MCSymbol *, const MCSymbol *> Renames; | |
| 148 | |
| 149 llvm::DenseMap<const MCSectionData*, | |
| 150 std::vector<ELFRelocationEntry> > Relocations; | |
| 151 DenseMap<const MCSection*, uint64_t> SectionStringTableIndex; | |
| 152 | |
| 153 /// @} | |
| 154 /// @name Symbol Table Data | |
| 155 /// @{ | |
| 156 | |
| 157 SmallString<256> StringTable; | |
| 158 std::vector<ELFSymbolData> LocalSymbolData; | |
| 159 std::vector<ELFSymbolData> ExternalSymbolData; | |
| 160 std::vector<ELFSymbolData> UndefinedSymbolData; | |
| 161 | |
| 162 /// @} | |
| 163 | |
| 164 int NumRegularSections; | |
| 165 | |
| 166 bool NeedsGOT; | |
| 167 | |
| 168 bool NeedsSymtabShndx; | |
| 169 | |
| 170 ELFObjectWriter *Writer; | |
| 171 | |
| 172 raw_ostream &OS; | |
| 173 | |
| 174 unsigned Is64Bit : 1; | |
| 175 | |
| 176 bool HasRelocationAddend; | |
| 177 | |
| 178 Triple::OSType OSType; | |
| 179 | |
| 180 uint16_t EMachine; | |
| 181 | |
| 182 // This holds the symbol table index of the last local symbol. | |
| 183 unsigned LastLocalSymbolIndex; | |
| 184 // This holds the .strtab section index. | |
| 185 unsigned StringTableIndex; | |
| 186 // This holds the .symtab section index. | |
| 187 unsigned SymbolTableIndex; | |
| 188 | |
| 189 unsigned ShstrtabIndex; | |
| 190 | |
| 191 public: | |
| 192 ELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _Is64Bit, | |
| 193 uint16_t _EMachine, bool _HasRelAddend, | |
| 194 Triple::OSType _OSType) | |
| 195 : NeedsGOT(false), NeedsSymtabShndx(false), Writer(_Writer), | |
| 196 OS(Writer->getStream()), | |
| 197 Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelAddend), | |
| 198 OSType(_OSType), EMachine(_EMachine) { | |
| 199 } | |
| 200 | |
| 201 void Write8(uint8_t Value) { Writer->Write8(Value); } | |
| 202 void Write16(uint16_t Value) { Writer->Write16(Value); } | |
| 203 void Write32(uint32_t Value) { Writer->Write32(Value); } | |
| 204 //void Write64(uint64_t Value) { Writer->Write64(Value); } | |
| 205 void WriteZeros(unsigned N) { Writer->WriteZeros(N); } | |
| 206 //void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { | |
| 207 // Writer->WriteBytes(Str, ZeroFillSize); | |
| 208 //} | |
| 209 | |
| 210 void WriteWord(uint64_t W) { | |
| 211 if (Is64Bit) | |
| 212 Writer->Write64(W); | |
| 213 else | |
| 214 Writer->Write32(W); | |
| 215 } | |
| 216 | |
| 217 void StringLE16(char *buf, uint16_t Value) { | |
| 218 buf[0] = char(Value >> 0); | |
| 219 buf[1] = char(Value >> 8); | |
| 220 } | |
| 221 | |
| 222 void StringLE32(char *buf, uint32_t Value) { | |
| 223 StringLE16(buf, uint16_t(Value >> 0)); | |
| 224 StringLE16(buf + 2, uint16_t(Value >> 16)); | |
| 225 } | |
| 226 | |
| 227 void StringLE64(char *buf, uint64_t Value) { | |
| 228 StringLE32(buf, uint32_t(Value >> 0)); | |
| 229 StringLE32(buf + 4, uint32_t(Value >> 32)); | |
| 230 } | |
| 231 | |
| 232 void StringBE16(char *buf ,uint16_t Value) { | |
| 233 buf[0] = char(Value >> 8); | |
| 234 buf[1] = char(Value >> 0); | |
| 235 } | |
| 236 | |
| 237 void StringBE32(char *buf, uint32_t Value) { | |
| 238 StringBE16(buf, uint16_t(Value >> 16)); | |
| 239 StringBE16(buf + 2, uint16_t(Value >> 0)); | |
| 240 } | |
| 241 | |
| 242 void StringBE64(char *buf, uint64_t Value) { | |
| 243 StringBE32(buf, uint32_t(Value >> 32)); | |
| 244 StringBE32(buf + 4, uint32_t(Value >> 0)); | |
| 245 } | |
| 246 | |
| 247 void String8(MCDataFragment &F, uint8_t Value) { | |
| 248 char buf[1]; | |
| 249 buf[0] = Value; | |
| 250 F.getContents() += StringRef(buf, 1); | |
| 251 } | |
| 252 | |
| 253 void String16(MCDataFragment &F, uint16_t Value) { | |
| 254 char buf[2]; | |
| 255 if (Writer->isLittleEndian()) | |
| 256 StringLE16(buf, Value); | |
| 257 else | |
| 258 StringBE16(buf, Value); | |
| 259 F.getContents() += StringRef(buf, 2); | |
| 260 } | |
| 261 | |
| 262 void String32(MCDataFragment &F, uint32_t Value) { | |
| 263 char buf[4]; | |
| 264 if (Writer->isLittleEndian()) | |
| 265 StringLE32(buf, Value); | |
| 266 else | |
| 267 StringBE32(buf, Value); | |
| 268 F.getContents() += StringRef(buf, 4); | |
| 269 } | |
| 270 | |
| 271 void String64(MCDataFragment &F, uint64_t Value) { | |
| 272 char buf[8]; | |
| 273 if (Writer->isLittleEndian()) | |
| 274 StringLE64(buf, Value); | |
| 275 else | |
| 276 StringBE64(buf, Value); | |
| 277 F.getContents() += StringRef(buf, 8); | |
| 278 } | |
| 279 | |
| 280 void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections); | |
| 281 | |
| 282 void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *ShndxF, | |
| 283 uint64_t name, uint8_t info, | |
| 284 uint64_t value, uint64_t size, | |
| 285 uint8_t other, uint32_t shndx, | |
| 286 bool Reserved); | |
| 287 | |
| 288 void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF, | |
| 289 ELFSymbolData &MSD, | |
| 290 const MCAsmLayout &Layout); | |
| 291 | |
| 292 typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy; | |
| 293 void WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *ShndxF, | |
| 294 const MCAssembler &Asm, | |
| 295 const MCAsmLayout &Layout, | |
| 296 const SectionIndexMapTy &SectionIndexMap); | |
| 297 | |
| 298 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, | |
| 299 const MCFragment *Fragment, const MCFixup &Fixup, | |
| 300 MCValue Target, uint64_t &FixedValue); | |
| 301 | |
| 302 uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, | |
| 303 const MCSymbol *S); | |
| 304 | |
| 305 /// ComputeSymbolTable - Compute the symbol table data | |
| 306 /// | |
| 307 /// \param StringTable [out] - The string table data. | |
| 308 /// \param StringIndexMap [out] - Map from symbol names to offsets in the | |
| 309 /// string table. | |
| 310 void ComputeSymbolTable(MCAssembler &Asm, | |
| 311 const SectionIndexMapTy &SectionIndexMap); | |
| 312 | |
| 313 void ComputeIndexMap(MCAssembler &Asm, | |
| 314 SectionIndexMapTy &SectionIndexMap); | |
| 315 | |
| 316 void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, | |
| 317 const MCSectionData &SD); | |
| 318 | |
| 319 void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) { | |
| 320 for (MCAssembler::const_iterator it = Asm.begin(), | |
| 321 ie = Asm.end(); it != ie; ++it) { | |
| 322 WriteRelocation(Asm, Layout, *it); | |
| 323 } | |
| 324 } | |
| 325 | |
| 326 void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, | |
| 327 const SectionIndexMapTy &SectionIndexMap); | |
| 328 | |
| 329 // Map from a group section to the signature symbol | |
| 330 typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy; | |
| 331 void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout, | |
| 332 GroupMapTy &GroupMap); | |
| 333 | |
| 334 void ExecutePostLayoutBinding(MCAssembler &Asm); | |
| 335 | |
| 336 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, | |
| 337 uint64_t Address, uint64_t Offset, | |
| 338 uint64_t Size, uint32_t Link, uint32_t Info, | |
| 339 uint64_t Alignment, uint64_t EntrySize); | |
| 340 | |
| 341 void WriteRelocationsFragment(const MCAssembler &Asm, MCDataFragment *F, | |
| 342 const MCSectionData *SD); | |
| 343 | |
| 344 bool IsFixupFullyResolved(const MCAssembler &Asm, | |
| 345 const MCValue Target, | |
| 346 bool IsPCRel, | |
| 347 const MCFragment *DF) const; | |
| 348 | |
| 349 void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); | |
| 350 void WriteSection(MCAssembler &Asm, | |
| 351 const SectionIndexMapTy &SectionIndexMap, | |
| 352 uint32_t GroupSymbolIndex, | |
| 353 uint64_t Offset, uint64_t Size, uint64_t Alignment, | |
| 354 const MCSectionELF &Section); | |
| 355 }; | |
| 356 | |
| 357 } | |
| 358 | |
| 359 // Emit the ELF header. | 139 // Emit the ELF header. |
| 360 void ELFObjectWriterImpl::WriteHeader(uint64_t SectionDataSize, | 140 void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, |
| 361 unsigned NumberOfSections) { | 141 unsigned NumberOfSections) { |
| 362 // ELF Header | 142 // ELF Header |
| 363 // ---------- | 143 // ---------- |
| 364 // | 144 // |
| 365 // Note | 145 // Note |
| 366 // ---- | 146 // ---- |
| 367 // emitWord method behaves differently for ELF32 and ELF64, writing | 147 // emitWord method behaves differently for ELF32 and ELF64, writing |
| 368 // 4 bytes in the former and 8 in the latter. | 148 // 4 bytes in the former and 8 in the latter. |
| 369 | 149 |
| 370 Write8(0x7f); // e_ident[EI_MAG0] | 150 Write8(0x7f); // e_ident[EI_MAG0] |
| 371 Write8('E'); // e_ident[EI_MAG1] | 151 Write8('E'); // e_ident[EI_MAG1] |
| 372 Write8('L'); // e_ident[EI_MAG2] | 152 Write8('L'); // e_ident[EI_MAG2] |
| 373 Write8('F'); // e_ident[EI_MAG3] | 153 Write8('F'); // e_ident[EI_MAG3] |
| 374 | 154 |
| 375 Write8(Is64Bit ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] | 155 Write8(Is64Bit ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] |
| 376 | 156 |
| 377 // e_ident[EI_DATA] | 157 // e_ident[EI_DATA] |
| 378 Write8(Writer->isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); | 158 Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); |
| 379 | 159 |
| 380 Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] | 160 Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] |
| 381 // e_ident[EI_OSABI] | 161 // e_ident[EI_OSABI] |
| 382 switch (OSType) { | 162 switch (OSType) { |
| 383 case Triple::FreeBSD: Write8(ELF::ELFOSABI_FREEBSD); break; | 163 case Triple::FreeBSD: Write8(ELF::ELFOSABI_FREEBSD); break; |
| 384 case Triple::Linux: Write8(ELF::ELFOSABI_LINUX); break; | 164 case Triple::Linux: Write8(ELF::ELFOSABI_LINUX); break; |
| 385 default: Write8(ELF::ELFOSABI_NONE); break; | 165 default: Write8(ELF::ELFOSABI_NONE); break; |
| 386 } | 166 } |
| 387 Write8(0); // e_ident[EI_ABIVERSION] | 167 Write8(0); // e_ident[EI_ABIVERSION] |
| 388 | 168 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 416 else | 196 else |
| 417 Write16(NumberOfSections); | 197 Write16(NumberOfSections); |
| 418 | 198 |
| 419 // e_shstrndx = Section # of '.shstrtab' | 199 // e_shstrndx = Section # of '.shstrtab' |
| 420 if (NumberOfSections >= ELF::SHN_LORESERVE) | 200 if (NumberOfSections >= ELF::SHN_LORESERVE) |
| 421 Write16(ELF::SHN_XINDEX); | 201 Write16(ELF::SHN_XINDEX); |
| 422 else | 202 else |
| 423 Write16(ShstrtabIndex); | 203 Write16(ShstrtabIndex); |
| 424 } | 204 } |
| 425 | 205 |
| 426 void ELFObjectWriterImpl::WriteSymbolEntry(MCDataFragment *SymtabF, | 206 void ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, |
| 427 MCDataFragment *ShndxF, | 207 MCDataFragment *ShndxF, |
| 428 uint64_t name, | 208 uint64_t name, |
| 429 uint8_t info, uint64_t value, | 209 uint8_t info, uint64_t value, |
| 430 uint64_t size, uint8_t other, | 210 uint64_t size, uint8_t other, |
| 431 uint32_t shndx, | 211 uint32_t shndx, |
| 432 bool Reserved) { | 212 bool Reserved) { |
| 433 if (ShndxF) { | 213 if (ShndxF) { |
| 434 if (shndx >= ELF::SHN_LORESERVE && !Reserved) | 214 if (shndx >= ELF::SHN_LORESERVE && !Reserved) |
| 435 String32(*ShndxF, shndx); | 215 String32(*ShndxF, shndx); |
| 436 else | 216 else |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 S = &Res.getSymA()->getSymbol(); | 270 S = &Res.getSymA()->getSymbol(); |
| 491 break; | 271 break; |
| 492 } | 272 } |
| 493 default: | 273 default: |
| 494 return *S; | 274 return *S; |
| 495 } | 275 } |
| 496 } | 276 } |
| 497 return *S; | 277 return *S; |
| 498 } | 278 } |
| 499 | 279 |
| 500 void ELFObjectWriterImpl::ExecutePostLayoutBinding(MCAssembler &Asm) { | 280 |
| 281 // Helper routines |
| 282 |
| 283 bool ELFObjectWriter::ELFSymbolData::operator<(const ELFSymbolData &RHS) const { |
| 284 if (GetType(*SymbolData) == ELF::STT_FILE) |
| 285 return true; |
| 286 if (GetType(*RHS.SymbolData) == ELF::STT_FILE) |
| 287 return false; |
| 288 return SymbolData->getSymbol().getName() < |
| 289 RHS.SymbolData->getSymbol().getName(); |
| 290 } |
| 291 |
| 292 |
| 293 bool ELFObjectWriter::ELFRelocationEntry::operator<(const ELFRelocationEntry &RE
) const { |
| 294 return RE.r_offset < r_offset; |
| 295 } |
| 296 |
| 297 |
| 298 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) { |
| 501 // The presence of symbol versions causes undefined symbols and | 299 // The presence of symbol versions causes undefined symbols and |
| 502 // versions declared with @@@ to be renamed. | 300 // versions declared with @@@ to be renamed. |
| 503 | 301 |
| 504 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), | 302 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), |
| 505 ie = Asm.symbol_end(); it != ie; ++it) { | 303 ie = Asm.symbol_end(); it != ie; ++it) { |
| 506 const MCSymbol &Alias = it->getSymbol(); | 304 const MCSymbol &Alias = it->getSymbol(); |
| 507 const MCSymbol &Symbol = AliasedSymbol(Alias); | 305 const MCSymbol &Symbol = AliasedSymbol(Alias); |
| 508 MCSymbolData &SD = Asm.getSymbolData(Symbol); | 306 MCSymbolData &SD = Asm.getSymbolData(Symbol); |
| 509 | 307 |
| 510 // Undefined symbols are global, but this is the first place we | 308 // Undefined symbols are global, but this is the first place we |
| (...skipping 25 matching lines...) Expand all Loading... |
| 536 | 334 |
| 537 // FIXME: produce a better error message. | 335 // FIXME: produce a better error message. |
| 538 if (Symbol.isUndefined() && Rest.startswith("@@") && | 336 if (Symbol.isUndefined() && Rest.startswith("@@") && |
| 539 !Rest.startswith("@@@")) | 337 !Rest.startswith("@@@")) |
| 540 report_fatal_error("A @@ version cannot be undefined"); | 338 report_fatal_error("A @@ version cannot be undefined"); |
| 541 | 339 |
| 542 Renames.insert(std::make_pair(&Symbol, &Alias)); | 340 Renames.insert(std::make_pair(&Symbol, &Alias)); |
| 543 } | 341 } |
| 544 } | 342 } |
| 545 | 343 |
| 546 void ELFObjectWriterImpl::WriteSymbol(MCDataFragment *SymtabF, | 344 void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, |
| 547 MCDataFragment *ShndxF, | 345 MCDataFragment *ShndxF, |
| 548 ELFSymbolData &MSD, | 346 ELFSymbolData &MSD, |
| 549 const MCAsmLayout &Layout) { | 347 const MCAsmLayout &Layout) { |
| 550 MCSymbolData &OrigData = *MSD.SymbolData; | 348 MCSymbolData &OrigData = *MSD.SymbolData; |
| 551 MCSymbolData &Data = | 349 MCSymbolData &Data = |
| 552 Layout.getAssembler().getSymbolData(AliasedSymbol(OrigData.getSymbol())); | 350 Layout.getAssembler().getSymbolData(AliasedSymbol(OrigData.getSymbol())); |
| 553 | 351 |
| 554 bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || | 352 bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || |
| 555 Data.getSymbol().isVariable(); | 353 Data.getSymbol().isVariable(); |
| 556 | 354 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 583 } else { | 381 } else { |
| 584 assert(0 && "Unsupported size expression"); | 382 assert(0 && "Unsupported size expression"); |
| 585 } | 383 } |
| 586 } | 384 } |
| 587 | 385 |
| 588 // Write out the symbol table entry | 386 // Write out the symbol table entry |
| 589 WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, | 387 WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, |
| 590 Size, Other, MSD.SectionIndex, IsReserved); | 388 Size, Other, MSD.SectionIndex, IsReserved); |
| 591 } | 389 } |
| 592 | 390 |
| 593 void ELFObjectWriterImpl::WriteSymbolTable(MCDataFragment *SymtabF, | 391 void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, |
| 594 MCDataFragment *ShndxF, | 392 MCDataFragment *ShndxF, |
| 595 const MCAssembler &Asm, | 393 const MCAssembler &Asm, |
| 596 const MCAsmLayout &Layout, | 394 const MCAsmLayout &Layout, |
| 597 const SectionIndexMapTy &SectionIndexMap) { | 395 const SectionIndexMapTy &SectionIndexMap) { |
| 598 // The string table must be emitted first because we need the index | 396 // The string table must be emitted first because we need the index |
| 599 // into the string table for all the symbol names. | 397 // into the string table for all the symbol names. |
| 600 assert(StringTable.size() && "Missing string table"); | 398 assert(StringTable.size() && "Missing string table"); |
| 601 | 399 |
| 602 // FIXME: Make sure the start of the symbol table is aligned. | 400 // FIXME: Make sure the start of the symbol table is aligned. |
| 603 | 401 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 Kind == MCSymbolRefExpr::VK_GOTPCREL || | 469 Kind == MCSymbolRefExpr::VK_GOTPCREL || |
| 672 Kind == MCSymbolRefExpr::VK_GOTOFF)) | 470 Kind == MCSymbolRefExpr::VK_GOTOFF)) |
| 673 return true; | 471 return true; |
| 674 | 472 |
| 675 if (Section.getFlags() & MCSectionELF::SHF_MERGE) | 473 if (Section.getFlags() & MCSectionELF::SHF_MERGE) |
| 676 return Target.getConstant() != 0; | 474 return Target.getConstant() != 0; |
| 677 | 475 |
| 678 return false; | 476 return false; |
| 679 } | 477 } |
| 680 | 478 |
| 681 // FIXME: this is currently X86/X86_64 only | |
| 682 void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm, | |
| 683 const MCAsmLayout &Layout, | |
| 684 const MCFragment *Fragment, | |
| 685 const MCFixup &Fixup, | |
| 686 MCValue Target, | |
| 687 uint64_t &FixedValue) { | |
| 688 int64_t Addend = 0; | |
| 689 int Index = 0; | |
| 690 int64_t Value = Target.getConstant(); | |
| 691 const MCSymbol &Symbol = Target.getSymA()->getSymbol(); | |
| 692 const MCSymbol &ASymbol = AliasedSymbol(Symbol); | |
| 693 const MCSymbol *RenamedP = Renames.lookup(&Symbol); | |
| 694 if (!RenamedP) | |
| 695 RenamedP = &ASymbol; | |
| 696 const MCSymbol &Renamed = *RenamedP; | |
| 697 | |
| 698 bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind()); | |
| 699 if (!Target.isAbsolute()) { | |
| 700 MCSymbolData &SD = Asm.getSymbolData(Symbol); | |
| 701 MCFragment *F = SD.getFragment(); | |
| 702 | |
| 703 if (const MCSymbolRefExpr *RefB = Target.getSymB()) { | |
| 704 const MCSymbol &SymbolB = RefB->getSymbol(); | |
| 705 MCSymbolData &SDB = Asm.getSymbolData(SymbolB); | |
| 706 IsPCRel = true; | |
| 707 MCSectionData *Sec = Fragment->getParent(); | |
| 708 | |
| 709 // Offset of the symbol in the section | |
| 710 int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec); | |
| 711 | |
| 712 // Ofeset of the relocation in the section | |
| 713 int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); | |
| 714 Value += b - a; | |
| 715 } | |
| 716 | |
| 717 bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target, *Fragment); | |
| 718 if (!RelocOnSymbol) { | |
| 719 Index = F->getParent()->getOrdinal(); | |
| 720 | |
| 721 MCSectionData *FSD = F->getParent(); | |
| 722 // Offset of the symbol in the section | |
| 723 Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD); | |
| 724 } else { | |
| 725 if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) | |
| 726 WeakrefUsedInReloc.insert(&Renamed); | |
| 727 else | |
| 728 UsedInReloc.insert(&Renamed); | |
| 729 Index = -1; | |
| 730 } | |
| 731 Addend = Value; | |
| 732 // Compensate for the addend on i386. | |
| 733 if (Is64Bit) | |
| 734 Value = 0; | |
| 735 } | |
| 736 | |
| 737 FixedValue = Value; | |
| 738 | |
| 739 // determine the type of the relocation | |
| 740 | |
| 741 MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind(); | |
| 742 unsigned Type; | |
| 743 if (Is64Bit) { | |
| 744 if (IsPCRel) { | |
| 745 switch (Modifier) { | |
| 746 default: | |
| 747 llvm_unreachable("Unimplemented"); | |
| 748 case MCSymbolRefExpr::VK_None: | |
| 749 Type = ELF::R_X86_64_PC32; | |
| 750 break; | |
| 751 case MCSymbolRefExpr::VK_PLT: | |
| 752 Type = ELF::R_X86_64_PLT32; | |
| 753 break; | |
| 754 case MCSymbolRefExpr::VK_GOTPCREL: | |
| 755 Type = ELF::R_X86_64_GOTPCREL; | |
| 756 break; | |
| 757 case MCSymbolRefExpr::VK_GOTTPOFF: | |
| 758 Type = ELF::R_X86_64_GOTTPOFF; | |
| 759 break; | |
| 760 case MCSymbolRefExpr::VK_TLSGD: | |
| 761 Type = ELF::R_X86_64_TLSGD; | |
| 762 break; | |
| 763 case MCSymbolRefExpr::VK_TLSLD: | |
| 764 Type = ELF::R_X86_64_TLSLD; | |
| 765 break; | |
| 766 } | |
| 767 } else { | |
| 768 switch ((unsigned)Fixup.getKind()) { | |
| 769 default: llvm_unreachable("invalid fixup kind!"); | |
| 770 case FK_Data_8: Type = ELF::R_X86_64_64; break; | |
| 771 case X86::reloc_signed_4byte: | |
| 772 case X86::reloc_pcrel_4byte: | |
| 773 assert(isInt<32>(Target.getConstant())); | |
| 774 switch (Modifier) { | |
| 775 default: | |
| 776 llvm_unreachable("Unimplemented"); | |
| 777 case MCSymbolRefExpr::VK_None: | |
| 778 Type = ELF::R_X86_64_32S; | |
| 779 break; | |
| 780 case MCSymbolRefExpr::VK_GOT: | |
| 781 Type = ELF::R_X86_64_GOT32; | |
| 782 break; | |
| 783 case MCSymbolRefExpr::VK_GOTPCREL: | |
| 784 Type = ELF::R_X86_64_GOTPCREL; | |
| 785 break; | |
| 786 case MCSymbolRefExpr::VK_TPOFF: | |
| 787 Type = ELF::R_X86_64_TPOFF32; | |
| 788 break; | |
| 789 case MCSymbolRefExpr::VK_DTPOFF: | |
| 790 Type = ELF::R_X86_64_DTPOFF32; | |
| 791 break; | |
| 792 } | |
| 793 break; | |
| 794 case FK_Data_4: | |
| 795 Type = ELF::R_X86_64_32; | |
| 796 break; | |
| 797 case FK_Data_2: Type = ELF::R_X86_64_16; break; | |
| 798 case X86::reloc_pcrel_1byte: | |
| 799 case FK_Data_1: Type = ELF::R_X86_64_8; break; | |
| 800 } | |
| 801 } | |
| 802 } else { | |
| 803 if (IsPCRel) { | |
| 804 switch (Modifier) { | |
| 805 default: | |
| 806 llvm_unreachable("Unimplemented"); | |
| 807 case MCSymbolRefExpr::VK_None: | |
| 808 Type = ELF::R_386_PC32; | |
| 809 break; | |
| 810 case MCSymbolRefExpr::VK_PLT: | |
| 811 Type = ELF::R_386_PLT32; | |
| 812 break; | |
| 813 } | |
| 814 } else { | |
| 815 switch ((unsigned)Fixup.getKind()) { | |
| 816 default: llvm_unreachable("invalid fixup kind!"); | |
| 817 | |
| 818 case X86::reloc_global_offset_table: | |
| 819 Type = ELF::R_386_GOTPC; | |
| 820 break; | |
| 821 | |
| 822 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode | |
| 823 // instead? | |
| 824 case X86::reloc_signed_4byte: | |
| 825 case X86::reloc_pcrel_4byte: | |
| 826 case FK_Data_4: | |
| 827 switch (Modifier) { | |
| 828 default: | |
| 829 llvm_unreachable("Unimplemented"); | |
| 830 case MCSymbolRefExpr::VK_None: | |
| 831 Type = ELF::R_386_32; | |
| 832 break; | |
| 833 case MCSymbolRefExpr::VK_GOT: | |
| 834 Type = ELF::R_386_GOT32; | |
| 835 break; | |
| 836 case MCSymbolRefExpr::VK_GOTOFF: | |
| 837 Type = ELF::R_386_GOTOFF; | |
| 838 break; | |
| 839 case MCSymbolRefExpr::VK_TLSGD: | |
| 840 Type = ELF::R_386_TLS_GD; | |
| 841 break; | |
| 842 case MCSymbolRefExpr::VK_TPOFF: | |
| 843 Type = ELF::R_386_TLS_LE_32; | |
| 844 break; | |
| 845 case MCSymbolRefExpr::VK_INDNTPOFF: | |
| 846 Type = ELF::R_386_TLS_IE; | |
| 847 break; | |
| 848 case MCSymbolRefExpr::VK_NTPOFF: | |
| 849 Type = ELF::R_386_TLS_LE; | |
| 850 break; | |
| 851 case MCSymbolRefExpr::VK_GOTNTPOFF: | |
| 852 Type = ELF::R_386_TLS_GOTIE; | |
| 853 break; | |
| 854 case MCSymbolRefExpr::VK_TLSLDM: | |
| 855 Type = ELF::R_386_TLS_LDM; | |
| 856 break; | |
| 857 case MCSymbolRefExpr::VK_DTPOFF: | |
| 858 Type = ELF::R_386_TLS_LDO_32; | |
| 859 break; | |
| 860 } | |
| 861 break; | |
| 862 case FK_Data_2: Type = ELF::R_386_16; break; | |
| 863 case X86::reloc_pcrel_1byte: | |
| 864 case FK_Data_1: Type = ELF::R_386_8; break; | |
| 865 } | |
| 866 } | |
| 867 } | |
| 868 | |
| 869 if (RelocNeedsGOT(Modifier)) | |
| 870 NeedsGOT = true; | |
| 871 | |
| 872 ELFRelocationEntry ERE; | |
| 873 | |
| 874 ERE.Index = Index; | |
| 875 ERE.Type = Type; | |
| 876 ERE.Symbol = &Renamed; | |
| 877 | |
| 878 ERE.r_offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); | |
| 879 | |
| 880 if (HasRelocationAddend) | |
| 881 ERE.r_addend = Addend; | |
| 882 else | |
| 883 ERE.r_addend = 0; // Silence compiler warning. | |
| 884 | |
| 885 Relocations[Fragment->getParent()].push_back(ERE); | |
| 886 } | |
| 887 | 479 |
| 888 uint64_t | 480 uint64_t |
| 889 ELFObjectWriterImpl::getSymbolIndexInSymbolTable(const MCAssembler &Asm, | 481 ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, |
| 890 const MCSymbol *S) { | 482 const MCSymbol *S) { |
| 891 MCSymbolData &SD = Asm.getSymbolData(*S); | 483 MCSymbolData &SD = Asm.getSymbolData(*S); |
| 892 | 484 |
| 893 // Local symbol. | 485 // Local symbol. |
| 894 if (!SD.isExternal() && !S->isUndefined()) | 486 if (!SD.isExternal() && !S->isUndefined()) |
| 895 return SD.getIndex() + /* empty symbol */ 1; | 487 return SD.getIndex() + /* empty symbol */ 1; |
| 896 | 488 |
| 897 // External or undefined symbol. | 489 // External or undefined symbol. |
| 898 return SD.getIndex() + NumRegularSections + /* empty symbol */ 1; | 490 return SD.getIndex() + NumRegularSections + /* empty symbol */ 1; |
| 899 } | 491 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 if (Data.isExternal()) | 523 if (Data.isExternal()) |
| 932 return false; | 524 return false; |
| 933 | 525 |
| 934 const MCSymbol &Symbol = Data.getSymbol(); | 526 const MCSymbol &Symbol = Data.getSymbol(); |
| 935 if (Symbol.isUndefined() && !Symbol.isVariable()) | 527 if (Symbol.isUndefined() && !Symbol.isVariable()) |
| 936 return false; | 528 return false; |
| 937 | 529 |
| 938 return true; | 530 return true; |
| 939 } | 531 } |
| 940 | 532 |
| 941 void ELFObjectWriterImpl::ComputeIndexMap(MCAssembler &Asm, | 533 void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, |
| 942 SectionIndexMapTy &SectionIndexMap) { | 534 SectionIndexMapTy &SectionIndexMap) { |
| 943 unsigned Index = 1; | 535 unsigned Index = 1; |
| 944 for (MCAssembler::iterator it = Asm.begin(), | 536 for (MCAssembler::iterator it = Asm.begin(), |
| 945 ie = Asm.end(); it != ie; ++it) { | 537 ie = Asm.end(); it != ie; ++it) { |
| 946 const MCSectionELF &Section = | 538 const MCSectionELF &Section = |
| 947 static_cast<const MCSectionELF &>(it->getSection()); | 539 static_cast<const MCSectionELF &>(it->getSection()); |
| 948 if (Section.getType() != ELF::SHT_GROUP) | 540 if (Section.getType() != ELF::SHT_GROUP) |
| 949 continue; | 541 continue; |
| 950 SectionIndexMap[&Section] = Index++; | 542 SectionIndexMap[&Section] = Index++; |
| 951 } | 543 } |
| 952 | 544 |
| 953 for (MCAssembler::iterator it = Asm.begin(), | 545 for (MCAssembler::iterator it = Asm.begin(), |
| 954 ie = Asm.end(); it != ie; ++it) { | 546 ie = Asm.end(); it != ie; ++it) { |
| 955 const MCSectionELF &Section = | 547 const MCSectionELF &Section = |
| 956 static_cast<const MCSectionELF &>(it->getSection()); | 548 static_cast<const MCSectionELF &>(it->getSection()); |
| 957 if (Section.getType() == ELF::SHT_GROUP) | 549 if (Section.getType() == ELF::SHT_GROUP) |
| 958 continue; | 550 continue; |
| 959 SectionIndexMap[&Section] = Index++; | 551 SectionIndexMap[&Section] = Index++; |
| 960 } | 552 } |
| 961 } | 553 } |
| 962 | 554 |
| 963 void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm, | 555 void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, |
| 964 const SectionIndexMapTy &SectionIndexMap) { | 556 const SectionIndexMapTy &SectionIndexMap) { |
| 965 // FIXME: Is this the correct place to do this? | 557 // FIXME: Is this the correct place to do this? |
| 966 if (NeedsGOT) { | 558 if (NeedsGOT) { |
| 967 llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; | 559 llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; |
| 968 MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); | 560 MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); |
| 969 MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); | 561 MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); |
| 970 Data.setExternal(true); | 562 Data.setExternal(true); |
| 971 SetBinding(Data, ELF::STB_GLOBAL); | 563 SetBinding(Data, ELF::STB_GLOBAL); |
| 972 } | 564 } |
| 973 | 565 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 // symbols with non-local bindings. | 643 // symbols with non-local bindings. |
| 1052 unsigned Index = 0; | 644 unsigned Index = 0; |
| 1053 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) | 645 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) |
| 1054 LocalSymbolData[i].SymbolData->setIndex(Index++); | 646 LocalSymbolData[i].SymbolData->setIndex(Index++); |
| 1055 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) | 647 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) |
| 1056 ExternalSymbolData[i].SymbolData->setIndex(Index++); | 648 ExternalSymbolData[i].SymbolData->setIndex(Index++); |
| 1057 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) | 649 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) |
| 1058 UndefinedSymbolData[i].SymbolData->setIndex(Index++); | 650 UndefinedSymbolData[i].SymbolData->setIndex(Index++); |
| 1059 } | 651 } |
| 1060 | 652 |
| 1061 void ELFObjectWriterImpl::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, | 653 void ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, |
| 1062 const MCSectionData &SD) { | 654 const MCSectionData &SD) { |
| 1063 if (!Relocations[&SD].empty()) { | 655 if (!Relocations[&SD].empty()) { |
| 1064 MCContext &Ctx = Asm.getContext(); | 656 MCContext &Ctx = Asm.getContext(); |
| 1065 const MCSectionELF *RelaSection; | 657 const MCSectionELF *RelaSection; |
| 1066 const MCSectionELF &Section = | 658 const MCSectionELF &Section = |
| 1067 static_cast<const MCSectionELF&>(SD.getSection()); | 659 static_cast<const MCSectionELF&>(SD.getSection()); |
| 1068 | 660 |
| 1069 const StringRef SectionName = Section.getSectionName(); | 661 const StringRef SectionName = Section.getSectionName(); |
| 1070 std::string RelaSectionName = HasRelocationAddend ? ".rela" : ".rel"; | 662 std::string RelaSectionName = HasRelocationAddend ? ".rela" : ".rel"; |
| 1071 RelaSectionName += SectionName; | 663 RelaSectionName += SectionName; |
| 1072 | 664 |
| 1073 unsigned EntrySize; | 665 unsigned EntrySize; |
| 1074 if (HasRelocationAddend) | 666 if (HasRelocationAddend) |
| 1075 EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); | 667 EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); |
| 1076 else | 668 else |
| 1077 EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); | 669 EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); |
| 1078 | 670 |
| 1079 RelaSection = Ctx.getELFSection(RelaSectionName, HasRelocationAddend ? | 671 RelaSection = Ctx.getELFSection(RelaSectionName, HasRelocationAddend ? |
| 1080 ELF::SHT_RELA : ELF::SHT_REL, 0, | 672 ELF::SHT_RELA : ELF::SHT_REL, 0, |
| 1081 SectionKind::getReadOnly(), | 673 SectionKind::getReadOnly(), |
| 1082 EntrySize, ""); | 674 EntrySize, ""); |
| 1083 | 675 |
| 1084 MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); | 676 MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); |
| 1085 RelaSD.setAlignment(Is64Bit ? 8 : 4); | 677 RelaSD.setAlignment(Is64Bit ? 8 : 4); |
| 1086 | 678 |
| 1087 MCDataFragment *F = new MCDataFragment(&RelaSD); | 679 MCDataFragment *F = new MCDataFragment(&RelaSD); |
| 1088 | 680 |
| 1089 WriteRelocationsFragment(Asm, F, &SD); | 681 WriteRelocationsFragment(Asm, F, &SD); |
| 1090 | 682 |
| 1091 Asm.AddSectionToTheEnd(*Writer, RelaSD, Layout); | 683 Asm.AddSectionToTheEnd(*this, RelaSD, Layout); |
| 1092 } | 684 } |
| 1093 } | 685 } |
| 1094 | 686 |
| 1095 void ELFObjectWriterImpl::WriteSecHdrEntry(uint32_t Name, uint32_t Type, | 687 |
| 688 void ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) { |
| 689 for (MCAssembler::const_iterator it = Asm.begin(), |
| 690 ie = Asm.end(); it != ie; ++it) { |
| 691 WriteRelocation(Asm, Layout, *it); |
| 692 } |
| 693 } |
| 694 |
| 695 |
| 696 void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, |
| 1096 uint64_t Flags, uint64_t Address, | 697 uint64_t Flags, uint64_t Address, |
| 1097 uint64_t Offset, uint64_t Size, | 698 uint64_t Offset, uint64_t Size, |
| 1098 uint32_t Link, uint32_t Info, | 699 uint32_t Link, uint32_t Info, |
| 1099 uint64_t Alignment, | 700 uint64_t Alignment, |
| 1100 uint64_t EntrySize) { | 701 uint64_t EntrySize) { |
| 1101 Write32(Name); // sh_name: index into string table | 702 Write32(Name); // sh_name: index into string table |
| 1102 Write32(Type); // sh_type | 703 Write32(Type); // sh_type |
| 1103 WriteWord(Flags); // sh_flags | 704 WriteWord(Flags); // sh_flags |
| 1104 WriteWord(Address); // sh_addr | 705 WriteWord(Address); // sh_addr |
| 1105 WriteWord(Offset); // sh_offset | 706 WriteWord(Offset); // sh_offset |
| 1106 WriteWord(Size); // sh_size | 707 WriteWord(Size); // sh_size |
| 1107 Write32(Link); // sh_link | 708 Write32(Link); // sh_link |
| 1108 Write32(Info); // sh_info | 709 Write32(Info); // sh_info |
| 1109 WriteWord(Alignment); // sh_addralign | 710 WriteWord(Alignment); // sh_addralign |
| 1110 WriteWord(EntrySize); // sh_entsize | 711 WriteWord(EntrySize); // sh_entsize |
| 1111 } | 712 } |
| 1112 | 713 |
| 1113 void ELFObjectWriterImpl::WriteRelocationsFragment(const MCAssembler &Asm, | 714 void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, |
| 1114 MCDataFragment *F, | 715 MCDataFragment *F, |
| 1115 const MCSectionData *SD) { | 716 const MCSectionData *SD) { |
| 1116 std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; | 717 std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; |
| 1117 // sort by the r_offset just like gnu as does | 718 // sort by the r_offset just like gnu as does |
| 1118 array_pod_sort(Relocs.begin(), Relocs.end()); | 719 array_pod_sort(Relocs.begin(), Relocs.end()); |
| 1119 | 720 |
| 1120 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { | 721 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { |
| 1121 ELFRelocationEntry entry = Relocs[e - i - 1]; | 722 ELFRelocationEntry entry = Relocs[e - i - 1]; |
| 1122 | 723 |
| 1123 if (entry.Index < 0) | 724 if (entry.Index < 0) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1139 struct ELF::Elf32_Rela ERE32; | 740 struct ELF::Elf32_Rela ERE32; |
| 1140 ERE32.setSymbolAndType(entry.Index, entry.Type); | 741 ERE32.setSymbolAndType(entry.Index, entry.Type); |
| 1141 String32(*F, ERE32.r_info); | 742 String32(*F, ERE32.r_info); |
| 1142 | 743 |
| 1143 if (HasRelocationAddend) | 744 if (HasRelocationAddend) |
| 1144 String32(*F, entry.r_addend); | 745 String32(*F, entry.r_addend); |
| 1145 } | 746 } |
| 1146 } | 747 } |
| 1147 } | 748 } |
| 1148 | 749 |
| 1149 void ELFObjectWriterImpl::CreateMetadataSections(MCAssembler &Asm, | 750 void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, |
| 1150 MCAsmLayout &Layout, | 751 MCAsmLayout &Layout, |
| 1151 const SectionIndexMapTy &SectionIndexMap) { | 752 const SectionIndexMapTy &SectionIndexMap) { |
| 1152 MCContext &Ctx = Asm.getContext(); | 753 MCContext &Ctx = Asm.getContext(); |
| 1153 MCDataFragment *F; | 754 MCDataFragment *F; |
| 1154 | 755 |
| 1155 unsigned EntrySize = Is64Bit ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; | 756 unsigned EntrySize = Is64Bit ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; |
| 1156 | 757 |
| 1157 // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. | 758 // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. |
| 1158 const MCSectionELF *ShstrtabSection = | 759 const MCSectionELF *ShstrtabSection = |
| 1159 Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, | 760 Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1187 StrtabSD.setAlignment(1); | 788 StrtabSD.setAlignment(1); |
| 1188 StringTableIndex = Asm.size(); | 789 StringTableIndex = Asm.size(); |
| 1189 | 790 |
| 1190 WriteRelocations(Asm, Layout); | 791 WriteRelocations(Asm, Layout); |
| 1191 | 792 |
| 1192 // Symbol table | 793 // Symbol table |
| 1193 F = new MCDataFragment(&SymtabSD); | 794 F = new MCDataFragment(&SymtabSD); |
| 1194 MCDataFragment *ShndxF = NULL; | 795 MCDataFragment *ShndxF = NULL; |
| 1195 if (NeedsSymtabShndx) { | 796 if (NeedsSymtabShndx) { |
| 1196 ShndxF = new MCDataFragment(SymtabShndxSD); | 797 ShndxF = new MCDataFragment(SymtabShndxSD); |
| 1197 Asm.AddSectionToTheEnd(*Writer, *SymtabShndxSD, Layout); | 798 Asm.AddSectionToTheEnd(*this, *SymtabShndxSD, Layout); |
| 1198 } | 799 } |
| 1199 WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); | 800 WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); |
| 1200 Asm.AddSectionToTheEnd(*Writer, SymtabSD, Layout); | 801 Asm.AddSectionToTheEnd(*this, SymtabSD, Layout); |
| 1201 | 802 |
| 1202 F = new MCDataFragment(&StrtabSD); | 803 F = new MCDataFragment(&StrtabSD); |
| 1203 F->getContents().append(StringTable.begin(), StringTable.end()); | 804 F->getContents().append(StringTable.begin(), StringTable.end()); |
| 1204 Asm.AddSectionToTheEnd(*Writer, StrtabSD, Layout); | 805 Asm.AddSectionToTheEnd(*this, StrtabSD, Layout); |
| 1205 | 806 |
| 1206 F = new MCDataFragment(&ShstrtabSD); | 807 F = new MCDataFragment(&ShstrtabSD); |
| 1207 | 808 |
| 1208 // Section header string table. | 809 // Section header string table. |
| 1209 // | 810 // |
| 1210 // The first entry of a string table holds a null character so skip | 811 // The first entry of a string table holds a null character so skip |
| 1211 // section 0. | 812 // section 0. |
| 1212 uint64_t Index = 1; | 813 uint64_t Index = 1; |
| 1213 F->getContents() += '\x00'; | 814 F->getContents() += '\x00'; |
| 1214 | 815 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1227 // Remember the index into the string table so we can write it | 828 // Remember the index into the string table so we can write it |
| 1228 // into the sh_name field of the section header table. | 829 // into the sh_name field of the section header table. |
| 1229 SectionStringTableIndex[&Section] = Index; | 830 SectionStringTableIndex[&Section] = Index; |
| 1230 SecStringMap[Name] = Index; | 831 SecStringMap[Name] = Index; |
| 1231 | 832 |
| 1232 Index += Name.size() + 1; | 833 Index += Name.size() + 1; |
| 1233 F->getContents() += Name; | 834 F->getContents() += Name; |
| 1234 F->getContents() += '\x00'; | 835 F->getContents() += '\x00'; |
| 1235 } | 836 } |
| 1236 | 837 |
| 1237 Asm.AddSectionToTheEnd(*Writer, ShstrtabSD, Layout); | 838 Asm.AddSectionToTheEnd(*this, ShstrtabSD, Layout); |
| 1238 } | 839 } |
| 1239 | 840 |
| 1240 bool ELFObjectWriterImpl::IsFixupFullyResolved(const MCAssembler &Asm, | 841 bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, |
| 1241 const MCValue Target, | 842 const MCValue Target, |
| 1242 bool IsPCRel, | 843 bool IsPCRel, |
| 1243 const MCFragment *DF) const { | 844 const MCFragment *DF) const { |
| 1244 // If this is a PCrel relocation, find the section this fixup value is | 845 // If this is a PCrel relocation, find the section this fixup value is |
| 1245 // relative to. | 846 // relative to. |
| 1246 const MCSection *BaseSection = 0; | 847 const MCSection *BaseSection = 0; |
| 1247 if (IsPCRel) { | 848 if (IsPCRel) { |
| 1248 BaseSection = &DF->getParent()->getSection(); | 849 BaseSection = &DF->getParent()->getSection(); |
| 1249 assert(BaseSection); | 850 assert(BaseSection); |
| 1250 } | 851 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1264 if (!BaseSection) | 865 if (!BaseSection) |
| 1265 return SectionA == SectionB; | 866 return SectionA == SectionB; |
| 1266 | 867 |
| 1267 const MCSymbolData &DataA = Asm.getSymbolData(*SymbolA); | 868 const MCSymbolData &DataA = Asm.getSymbolData(*SymbolA); |
| 1268 if (DataA.isExternal()) | 869 if (DataA.isExternal()) |
| 1269 return false; | 870 return false; |
| 1270 | 871 |
| 1271 return !SectionB && BaseSection == SectionA; | 872 return !SectionB && BaseSection == SectionA; |
| 1272 } | 873 } |
| 1273 | 874 |
| 1274 void ELFObjectWriterImpl::CreateGroupSections(MCAssembler &Asm, | 875 void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm, |
| 1275 MCAsmLayout &Layout, | 876 MCAsmLayout &Layout, |
| 1276 GroupMapTy &GroupMap) { | 877 GroupMapTy &GroupMap) { |
| 1277 typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy; | 878 typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy; |
| 1278 // Build the groups | 879 // Build the groups |
| 1279 RevGroupMapTy Groups; | 880 RevGroupMapTy Groups; |
| 1280 for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); | 881 for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); |
| 1281 it != ie; ++it) { | 882 it != ie; ++it) { |
| 1282 const MCSectionELF &Section = | 883 const MCSectionELF &Section = |
| 1283 static_cast<const MCSectionELF&>(it->getSection()); | 884 static_cast<const MCSectionELF&>(it->getSection()); |
| 1284 if (!(Section.getFlags() & MCSectionELF::SHF_GROUP)) | 885 if (!(Section.getFlags() & MCSectionELF::SHF_GROUP)) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1310 MCSectionData &Data = Asm.getOrCreateSectionData(*Group); | 911 MCSectionData &Data = Asm.getOrCreateSectionData(*Group); |
| 1311 // FIXME: we could use the previous fragment | 912 // FIXME: we could use the previous fragment |
| 1312 MCDataFragment *F = new MCDataFragment(&Data); | 913 MCDataFragment *F = new MCDataFragment(&Data); |
| 1313 String32(*F, NumGroups + Index); | 914 String32(*F, NumGroups + Index); |
| 1314 } | 915 } |
| 1315 | 916 |
| 1316 for (RevGroupMapTy::const_iterator i = Groups.begin(), e = Groups.end(); | 917 for (RevGroupMapTy::const_iterator i = Groups.begin(), e = Groups.end(); |
| 1317 i != e; ++i) { | 918 i != e; ++i) { |
| 1318 const MCSectionELF *Group = i->second; | 919 const MCSectionELF *Group = i->second; |
| 1319 MCSectionData &Data = Asm.getOrCreateSectionData(*Group); | 920 MCSectionData &Data = Asm.getOrCreateSectionData(*Group); |
| 1320 Asm.AddSectionToTheEnd(*Writer, Data, Layout); | 921 Asm.AddSectionToTheEnd(*this, Data, Layout); |
| 1321 } | 922 } |
| 1322 } | 923 } |
| 1323 | 924 |
| 1324 void ELFObjectWriterImpl::WriteSection(MCAssembler &Asm, | 925 void ELFObjectWriter::WriteSection(MCAssembler &Asm, |
| 1325 const SectionIndexMapTy &SectionIndexMap, | 926 const SectionIndexMapTy &SectionIndexMap, |
| 1326 uint32_t GroupSymbolIndex, | 927 uint32_t GroupSymbolIndex, |
| 1327 uint64_t Offset, uint64_t Size, | 928 uint64_t Offset, uint64_t Size, |
| 1328 uint64_t Alignment, | 929 uint64_t Alignment, |
| 1329 const MCSectionELF &Section) { | 930 const MCSectionELF &Section) { |
| 1330 uint64_t sh_link = 0; | 931 uint64_t sh_link = 0; |
| 1331 uint64_t sh_info = 0; | 932 uint64_t sh_info = 0; |
| 1332 | 933 |
| 1333 switch(Section.getType()) { | 934 switch(Section.getType()) { |
| 1334 case ELF::SHT_DYNAMIC: | 935 case ELF::SHT_DYNAMIC: |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1384 default: | 985 default: |
| 1385 assert(0 && "FIXME: sh_type value not supported!"); | 986 assert(0 && "FIXME: sh_type value not supported!"); |
| 1386 break; | 987 break; |
| 1387 } | 988 } |
| 1388 | 989 |
| 1389 WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), | 990 WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), |
| 1390 Section.getFlags(), 0, Offset, Size, sh_link, sh_info, | 991 Section.getFlags(), 0, Offset, Size, sh_link, sh_info, |
| 1391 Alignment, Section.getEntrySize()); | 992 Alignment, Section.getEntrySize()); |
| 1392 } | 993 } |
| 1393 | 994 |
| 1394 void ELFObjectWriterImpl::WriteObject(MCAssembler &Asm, | 995 void ELFObjectWriter::WriteObject(MCAssembler &Asm, |
| 1395 const MCAsmLayout &Layout) { | 996 const MCAsmLayout &Layout) { |
| 1396 | 997 |
| 1397 GroupMapTy GroupMap; | 998 GroupMapTy GroupMap; |
| 1398 CreateGroupSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap); | 999 CreateGroupSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap); |
| 1399 | 1000 |
| 1400 SectionIndexMapTy SectionIndexMap; | 1001 SectionIndexMapTy SectionIndexMap; |
| 1401 | 1002 |
| 1402 ComputeIndexMap(Asm, SectionIndexMap); | 1003 ComputeIndexMap(Asm, SectionIndexMap); |
| 1403 | 1004 |
| 1404 // Compute symbol table information. | 1005 // Compute symbol table information. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1454 | 1055 |
| 1455 uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); | 1056 uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); |
| 1456 WriteZeros(Padding); | 1057 WriteZeros(Padding); |
| 1457 FileOff += Padding; | 1058 FileOff += Padding; |
| 1458 | 1059 |
| 1459 // Remember the offset into the file for this section. | 1060 // Remember the offset into the file for this section. |
| 1460 SectionOffsetMap[&Section] = FileOff; | 1061 SectionOffsetMap[&Section] = FileOff; |
| 1461 | 1062 |
| 1462 FileOff += Layout.getSectionFileSize(&SD); | 1063 FileOff += Layout.getSectionFileSize(&SD); |
| 1463 | 1064 |
| 1464 Asm.WriteSectionData(&SD, Layout, Writer); | 1065 Asm.WriteSectionData(&SD, Layout, this); |
| 1465 } | 1066 } |
| 1466 | 1067 |
| 1467 uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); | 1068 uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); |
| 1468 WriteZeros(Padding); | 1069 WriteZeros(Padding); |
| 1469 FileOff += Padding; | 1070 FileOff += Padding; |
| 1470 | 1071 |
| 1471 // ... and then the section header table. | 1072 // ... and then the section header table. |
| 1472 // Should we align the section header table? | 1073 // Should we align the section header table? |
| 1473 // | 1074 // |
| 1474 // Null section first. | 1075 // Null section first. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1486 GroupSymbolIndex = 0; | 1087 GroupSymbolIndex = 0; |
| 1487 else | 1088 else |
| 1488 GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]); | 1089 GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]); |
| 1489 | 1090 |
| 1490 WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, | 1091 WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, |
| 1491 SectionOffsetMap[&Section], Layout.getSectionSize(&SD), | 1092 SectionOffsetMap[&Section], Layout.getSectionSize(&SD), |
| 1492 SD.getAlignment(), Section); | 1093 SD.getAlignment(), Section); |
| 1493 } | 1094 } |
| 1494 } | 1095 } |
| 1495 | 1096 |
| 1496 ELFObjectWriter::ELFObjectWriter(raw_ostream &OS, | 1097 ELFObjectWriter::ELFObjectWriter(raw_ostream &_OS, |
| 1497 bool Is64Bit, | 1098 bool _Is64Bit, |
| 1498 Triple::OSType OSType, | 1099 Triple::OSType _OSType, |
| 1499 uint16_t EMachine, | 1100 uint16_t _EMachine, |
| 1500 bool IsLittleEndian, | 1101 bool _IsLittleEndian, |
| 1501 bool HasRelocationAddend) | 1102 bool _HasRelocationAddend) |
| 1502 : MCObjectWriter(OS, IsLittleEndian) | 1103 : MCObjectWriter(_OS, _IsLittleEndian), |
| 1104 NeedsGOT(false), NeedsSymtabShndx(false), |
| 1105 Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelocationAddend), |
| 1106 OSType(_OSType), EMachine(_EMachine) |
| 1503 { | 1107 { |
| 1504 Impl = new ELFObjectWriterImpl(this, Is64Bit, EMachine, | 1108 // Impl = new ELFObjectWriterImpl(this, Is64Bit, EMachine, |
| 1505 HasRelocationAddend, OSType); | 1109 // HasRelocationAddend, OSType); |
| 1506 } | 1110 } |
| 1507 | 1111 |
| 1508 ELFObjectWriter::~ELFObjectWriter() { | 1112 //===- ARMELFObjectWriter -------------------------------------------===// |
| 1509 delete (ELFObjectWriterImpl*) Impl; | 1113 |
| 1510 } | 1114 ARMELFObjectWriter::ARMELFObjectWriter(raw_ostream &OS, bool Is64Bit, |
| 1511 | 1115 Triple::OSType OSType, |
| 1512 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) { | 1116 uint16_t EMachine, bool IsLittleEndian, |
| 1513 ((ELFObjectWriterImpl*) Impl)->ExecutePostLayoutBinding(Asm); | 1117 bool HasRelocationAddend) |
| 1514 } | 1118 : ELFObjectWriter(OS, Is64Bit, OSType, EMachine, IsLittleEndian, |
| 1515 | 1119 HasRelocationAddend) |
| 1516 void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, | 1120 {} |
| 1517 const MCAsmLayout &Layout, | 1121 |
| 1518 const MCFragment *Fragment, | 1122 ARMELFObjectWriter::~ARMELFObjectWriter() |
| 1519 const MCFixup &Fixup, MCValue Target, | 1123 {} |
| 1520 uint64_t &FixedValue) { | 1124 |
| 1521 ((ELFObjectWriterImpl*) Impl)->RecordRelocation(Asm, Layout, Fragment, Fixup, | 1125 void ARMELFObjectWriter::RecordRelocation(const MCAssembler &Asm, |
| 1522 Target, FixedValue); | 1126 const MCAsmLayout &Layout, |
| 1523 } | 1127 const MCFragment *Fragment, |
| 1524 | 1128 const MCFixup &Fixup, |
| 1525 bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, | 1129 MCValue Target, |
| 1526 const MCValue Target, | 1130 uint64_t &FixedValue) { |
| 1527 bool IsPCRel, | 1131 assert(0 && "ARMELFObjectWriter::RecordRelocation() unimplemented"); |
| 1528 const MCFragment *DF) const { | 1132 } |
| 1529 return ((ELFObjectWriterImpl*) Impl)->IsFixupFullyResolved(Asm, Target, | 1133 |
| 1530 IsPCRel, DF); | 1134 |
| 1531 } | 1135 |
| 1532 | 1136 //===- X86ELFObjectWriter -------------------------------------------===// |
| 1533 void ELFObjectWriter::WriteObject(MCAssembler &Asm, | 1137 |
| 1534 const MCAsmLayout &Layout) { | 1138 |
| 1535 ((ELFObjectWriterImpl*) Impl)->WriteObject(Asm, Layout); | 1139 X86ELFObjectWriter::X86ELFObjectWriter(raw_ostream &OS, bool Is64Bit, |
| 1536 } | 1140 Triple::OSType OSType, |
| 1141 uint16_t EMachine, bool IsLittleEndian, |
| 1142 bool HasRelocationAddend) |
| 1143 : ELFObjectWriter(OS, Is64Bit, OSType, EMachine, IsLittleEndian, |
| 1144 HasRelocationAddend) |
| 1145 {} |
| 1146 |
| 1147 X86ELFObjectWriter::~X86ELFObjectWriter() |
| 1148 {} |
| 1149 |
| 1150 void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, |
| 1151 const MCAsmLayout &Layout, |
| 1152 const MCFragment *Fragment, |
| 1153 const MCFixup &Fixup, |
| 1154 MCValue Target, |
| 1155 uint64_t &FixedValue) { |
| 1156 int64_t Addend = 0; |
| 1157 int Index = 0; |
| 1158 int64_t Value = Target.getConstant(); |
| 1159 const MCSymbol &Symbol = Target.getSymA()->getSymbol(); |
| 1160 const MCSymbol &ASymbol = AliasedSymbol(Symbol); |
| 1161 const MCSymbol *RenamedP = Renames.lookup(&Symbol); |
| 1162 if (!RenamedP) |
| 1163 RenamedP = &ASymbol; |
| 1164 const MCSymbol &Renamed = *RenamedP; |
| 1165 |
| 1166 bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind()); |
| 1167 if (!Target.isAbsolute()) { |
| 1168 MCSymbolData &SD = Asm.getSymbolData(Symbol); |
| 1169 MCFragment *F = SD.getFragment(); |
| 1170 |
| 1171 if (const MCSymbolRefExpr *RefB = Target.getSymB()) { |
| 1172 const MCSymbol &SymbolB = RefB->getSymbol(); |
| 1173 MCSymbolData &SDB = Asm.getSymbolData(SymbolB); |
| 1174 IsPCRel = true; |
| 1175 MCSectionData *Sec = Fragment->getParent(); |
| 1176 |
| 1177 // Offset of the symbol in the section |
| 1178 int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec); |
| 1179 |
| 1180 // Ofeset of the relocation in the section |
| 1181 int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); |
| 1182 Value += b - a; |
| 1183 } |
| 1184 |
| 1185 bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target, *Fragment); |
| 1186 if (!RelocOnSymbol) { |
| 1187 Index = F->getParent()->getOrdinal(); |
| 1188 |
| 1189 MCSectionData *FSD = F->getParent(); |
| 1190 // Offset of the symbol in the section |
| 1191 Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD); |
| 1192 } else { |
| 1193 if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) |
| 1194 WeakrefUsedInReloc.insert(&Renamed); |
| 1195 else |
| 1196 UsedInReloc.insert(&Renamed); |
| 1197 Index = -1; |
| 1198 } |
| 1199 Addend = Value; |
| 1200 // Compensate for the addend on i386. |
| 1201 if (Is64Bit) |
| 1202 Value = 0; |
| 1203 } |
| 1204 |
| 1205 FixedValue = Value; |
| 1206 |
| 1207 // determine the type of the relocation |
| 1208 |
| 1209 MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind(); |
| 1210 unsigned Type; |
| 1211 if (Is64Bit) { |
| 1212 if (IsPCRel) { |
| 1213 switch (Modifier) { |
| 1214 default: |
| 1215 llvm_unreachable("Unimplemented"); |
| 1216 case MCSymbolRefExpr::VK_None: |
| 1217 Type = ELF::R_X86_64_PC32; |
| 1218 break; |
| 1219 case MCSymbolRefExpr::VK_PLT: |
| 1220 Type = ELF::R_X86_64_PLT32; |
| 1221 break; |
| 1222 case MCSymbolRefExpr::VK_GOTPCREL: |
| 1223 Type = ELF::R_X86_64_GOTPCREL; |
| 1224 break; |
| 1225 case MCSymbolRefExpr::VK_GOTTPOFF: |
| 1226 Type = ELF::R_X86_64_GOTTPOFF; |
| 1227 break; |
| 1228 case MCSymbolRefExpr::VK_TLSGD: |
| 1229 Type = ELF::R_X86_64_TLSGD; |
| 1230 break; |
| 1231 case MCSymbolRefExpr::VK_TLSLD: |
| 1232 Type = ELF::R_X86_64_TLSLD; |
| 1233 break; |
| 1234 } |
| 1235 } else { |
| 1236 switch ((unsigned)Fixup.getKind()) { |
| 1237 default: llvm_unreachable("invalid fixup kind!"); |
| 1238 case FK_Data_8: Type = ELF::R_X86_64_64; break; |
| 1239 case X86::reloc_signed_4byte: |
| 1240 case X86::reloc_pcrel_4byte: |
| 1241 assert(isInt<32>(Target.getConstant())); |
| 1242 switch (Modifier) { |
| 1243 default: |
| 1244 llvm_unreachable("Unimplemented"); |
| 1245 case MCSymbolRefExpr::VK_None: |
| 1246 Type = ELF::R_X86_64_32S; |
| 1247 break; |
| 1248 case MCSymbolRefExpr::VK_GOT: |
| 1249 Type = ELF::R_X86_64_GOT32; |
| 1250 break; |
| 1251 case MCSymbolRefExpr::VK_GOTPCREL: |
| 1252 Type = ELF::R_X86_64_GOTPCREL; |
| 1253 break; |
| 1254 case MCSymbolRefExpr::VK_TPOFF: |
| 1255 Type = ELF::R_X86_64_TPOFF32; |
| 1256 break; |
| 1257 case MCSymbolRefExpr::VK_DTPOFF: |
| 1258 Type = ELF::R_X86_64_DTPOFF32; |
| 1259 break; |
| 1260 } |
| 1261 break; |
| 1262 case FK_Data_4: |
| 1263 Type = ELF::R_X86_64_32; |
| 1264 break; |
| 1265 case FK_Data_2: Type = ELF::R_X86_64_16; break; |
| 1266 case X86::reloc_pcrel_1byte: |
| 1267 case FK_Data_1: Type = ELF::R_X86_64_8; break; |
| 1268 } |
| 1269 } |
| 1270 } else { |
| 1271 if (IsPCRel) { |
| 1272 switch (Modifier) { |
| 1273 default: |
| 1274 llvm_unreachable("Unimplemented"); |
| 1275 case MCSymbolRefExpr::VK_None: |
| 1276 Type = ELF::R_386_PC32; |
| 1277 break; |
| 1278 case MCSymbolRefExpr::VK_PLT: |
| 1279 Type = ELF::R_386_PLT32; |
| 1280 break; |
| 1281 } |
| 1282 } else { |
| 1283 switch ((unsigned)Fixup.getKind()) { |
| 1284 default: llvm_unreachable("invalid fixup kind!"); |
| 1285 |
| 1286 case X86::reloc_global_offset_table: |
| 1287 Type = ELF::R_386_GOTPC; |
| 1288 break; |
| 1289 |
| 1290 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode |
| 1291 // instead? |
| 1292 case X86::reloc_signed_4byte: |
| 1293 case X86::reloc_pcrel_4byte: |
| 1294 case FK_Data_4: |
| 1295 switch (Modifier) { |
| 1296 default: |
| 1297 llvm_unreachable("Unimplemented"); |
| 1298 case MCSymbolRefExpr::VK_None: |
| 1299 Type = ELF::R_386_32; |
| 1300 break; |
| 1301 case MCSymbolRefExpr::VK_GOT: |
| 1302 Type = ELF::R_386_GOT32; |
| 1303 break; |
| 1304 case MCSymbolRefExpr::VK_GOTOFF: |
| 1305 Type = ELF::R_386_GOTOFF; |
| 1306 break; |
| 1307 case MCSymbolRefExpr::VK_TLSGD: |
| 1308 Type = ELF::R_386_TLS_GD; |
| 1309 break; |
| 1310 case MCSymbolRefExpr::VK_TPOFF: |
| 1311 Type = ELF::R_386_TLS_LE_32; |
| 1312 break; |
| 1313 case MCSymbolRefExpr::VK_INDNTPOFF: |
| 1314 Type = ELF::R_386_TLS_IE; |
| 1315 break; |
| 1316 case MCSymbolRefExpr::VK_NTPOFF: |
| 1317 Type = ELF::R_386_TLS_LE; |
| 1318 break; |
| 1319 case MCSymbolRefExpr::VK_GOTNTPOFF: |
| 1320 Type = ELF::R_386_TLS_GOTIE; |
| 1321 break; |
| 1322 case MCSymbolRefExpr::VK_TLSLDM: |
| 1323 Type = ELF::R_386_TLS_LDM; |
| 1324 break; |
| 1325 case MCSymbolRefExpr::VK_DTPOFF: |
| 1326 Type = ELF::R_386_TLS_LDO_32; |
| 1327 break; |
| 1328 } |
| 1329 break; |
| 1330 case FK_Data_2: Type = ELF::R_386_16; break; |
| 1331 case X86::reloc_pcrel_1byte: |
| 1332 case FK_Data_1: Type = ELF::R_386_8; break; |
| 1333 } |
| 1334 } |
| 1335 } |
| 1336 |
| 1337 if (RelocNeedsGOT(Modifier)) |
| 1338 NeedsGOT = true; |
| 1339 |
| 1340 ELFRelocationEntry ERE; |
| 1341 |
| 1342 ERE.Index = Index; |
| 1343 ERE.Type = Type; |
| 1344 ERE.Symbol = &Renamed; |
| 1345 |
| 1346 ERE.r_offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); |
| 1347 |
| 1348 if (HasRelocationAddend) |
| 1349 ERE.r_addend = Addend; |
| 1350 else |
| 1351 ERE.r_addend = 0; // Silence compiler warning. |
| 1352 |
| 1353 Relocations[Fragment->getParent()].push_back(ERE); |
| 1354 } |
| OLD | NEW |