diff options
author | dim <dim@FreeBSD.org> | 2011-10-20 21:10:27 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-10-20 21:10:27 +0000 |
commit | 7b3392326c40c3c20697816acae597ba7b3144eb (patch) | |
tree | 2cbcf22585e99f8a87d12d5ff94f392c0d266819 /lib/MC/ELFObjectWriter.cpp | |
parent | 1176aa52646fe641a4243a246aa7f960c708a274 (diff) | |
download | FreeBSD-src-7b3392326c40c3c20697816acae597ba7b3144eb.zip FreeBSD-src-7b3392326c40c3c20697816acae597ba7b3144eb.tar.gz |
Vendor import of llvm release_30 branch r142614:
http://llvm.org/svn/llvm-project/llvm/branches/release_30@142614
Diffstat (limited to 'lib/MC/ELFObjectWriter.cpp')
-rw-r--r-- | lib/MC/ELFObjectWriter.cpp | 124 |
1 files changed, 113 insertions, 11 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 59e1b8e..3d16de5 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" @@ -23,13 +24,13 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ELF.h" -#include "llvm/Target/TargetAsmBackend.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/CommandLine.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringSwitch.h" -#include "../Target/X86/X86FixupKinds.h" -#include "../Target/ARM/ARMFixupKinds.h" +#include "../Target/X86/MCTargetDesc/X86FixupKinds.h" +#include "../Target/ARM/MCTargetDesc/ARMFixupKinds.h" +#include "../Target/PowerPC/MCTargetDesc/PPCFixupKinds.h" #include <vector> using namespace llvm; @@ -124,12 +125,12 @@ void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, // e_shnum = # of section header ents if (NumberOfSections >= ELF::SHN_LORESERVE) - Write16(0); + Write16(ELF::SHN_UNDEF); else Write16(NumberOfSections); // e_shstrndx = Section # of '.shstrtab' - if (NumberOfSections >= ELF::SHN_LORESERVE) + if (ShstrtabIndex >= ELF::SHN_LORESERVE) Write16(ELF::SHN_XINDEX); else Write16(ShstrtabIndex); @@ -301,7 +302,8 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, if (Section.getType() == ELF::SHT_RELA || Section.getType() == ELF::SHT_REL || Section.getType() == ELF::SHT_STRTAB || - Section.getType() == ELF::SHT_SYMTAB) + Section.getType() == ELF::SHT_SYMTAB || + Section.getType() == ELF::SHT_SYMTAB_SHNDX) continue; WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false); @@ -447,8 +449,16 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); + adjustFixupOffset(Fixup, RelocOffset); + if (!hasRelocationAddend()) Addend = 0; + + if (is64Bit()) + assert(isInt<64>(Addend)); + else + assert(isInt<32>(Addend)); + ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend); Relocations[Fragment->getParent()].push_back(ERE); } @@ -656,6 +666,9 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, ExternalSymbolData[i].SymbolData->setIndex(Index++); for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) UndefinedSymbolData[i].SymbolData->setIndex(Index++); + + if (NumRegularSections > ELF::SHN_LORESERVE) + NeedsSymtabShndx = true; } void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, @@ -992,11 +1005,10 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, // Nothing to do. break; - case ELF::SHT_GROUP: { + case ELF::SHT_GROUP: sh_link = SymbolTableIndex; sh_info = GroupSymbolIndex; break; - } default: assert(0 && "FIXME: sh_type value not supported!"); @@ -1224,7 +1236,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, FileOff = OS.tell(); - // ... and then the remainting sections ... + // ... and then the remaining sections ... for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) WriteDataSectionData(Asm, Layout, *Sections[i]); } @@ -1252,6 +1264,11 @@ MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break; case ELF::EM_MBLAZE: return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break; + case ELF::EM_PPC: + case ELF::EM_PPC64: + return new PPCELFObjectWriter(MOTW, OS, IsLittleEndian); break; + case ELF::EM_MIPS: + return new MipsELFObjectWriter(MOTW, OS, IsLittleEndian); break; default: llvm_unreachable("Unsupported architecture"); break; } } @@ -1503,6 +1520,76 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, return Type; } +//===- PPCELFObjectWriter -------------------------------------------===// + +PPCELFObjectWriter::PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW, + raw_ostream &_OS, + bool IsLittleEndian) + : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { +} + +PPCELFObjectWriter::~PPCELFObjectWriter() { +} + +unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel, + bool IsRelocWithSymbol, + int64_t Addend) { + // determine the type of the relocation + unsigned Type; + if (IsPCRel) { + switch ((unsigned)Fixup.getKind()) { + default: + llvm_unreachable("Unimplemented"); + case PPC::fixup_ppc_br24: + Type = ELF::R_PPC_REL24; + break; + case FK_PCRel_4: + Type = ELF::R_PPC_REL32; + break; + } + } else { + switch ((unsigned)Fixup.getKind()) { + default: llvm_unreachable("invalid fixup kind!"); + case PPC::fixup_ppc_br24: + Type = ELF::R_PPC_ADDR24; + break; + case PPC::fixup_ppc_brcond14: + Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_ + break; + case PPC::fixup_ppc_ha16: + Type = ELF::R_PPC_ADDR16_HA; + break; + case PPC::fixup_ppc_lo16: + Type = ELF::R_PPC_ADDR16_LO; + break; + case PPC::fixup_ppc_lo14: + Type = ELF::R_PPC_ADDR14; + break; + case FK_Data_4: + Type = ELF::R_PPC_ADDR32; + break; + case FK_Data_2: + Type = ELF::R_PPC_ADDR16; + break; + } + } + return Type; +} + +void +PPCELFObjectWriter::adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) { + switch ((unsigned)Fixup.getKind()) { + case PPC::fixup_ppc_ha16: + case PPC::fixup_ppc_lo16: + RelocOffset += 2; + break; + default: + break; + } +} + //===- MBlazeELFObjectWriter -------------------------------------------===// MBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW, @@ -1624,7 +1711,6 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, default: llvm_unreachable("invalid fixup kind!"); case FK_Data_8: Type = ELF::R_X86_64_64; break; case X86::reloc_signed_4byte: - assert(isInt<32>(Target.getConstant())); switch (Modifier) { default: llvm_unreachable("Unimplemented"); @@ -1728,3 +1814,19 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, return Type; } + +MipsELFObjectWriter::MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW, + raw_ostream &_OS, + bool IsLittleEndian) + : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {} + +MipsELFObjectWriter::~MipsELFObjectWriter() {} + +unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel, + bool IsRelocWithSymbol, + int64_t Addend) { + // tbd + return 1; +} |