diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2010-08-17 18:20:28 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2010-08-17 18:20:28 +0000 |
commit | e5b57347e9485b59dd8d70f8f90d7794f473147a (patch) | |
tree | e7b35b32817dfc3ca936095ad3e0885b7c28c26b /lib/MC/ELFObjectWriter.cpp | |
parent | 4bb862d179486008406ec5025f925bac5493ad0d (diff) | |
download | external_llvm-e5b57347e9485b59dd8d70f8f90d7794f473147a.zip external_llvm-e5b57347e9485b59dd8d70f8f90d7794f473147a.tar.gz external_llvm-e5b57347e9485b59dd8d70f8f90d7794f473147a.tar.bz2 |
Sketch i386 relocations handling, from Roman Divacky.
Hello world builds & runs now on i386/ELF with -integrated-as.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111264 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/ELFObjectWriter.cpp')
-rw-r--r-- | lib/MC/ELFObjectWriter.cpp | 69 |
1 files changed, 45 insertions, 24 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 23c2dd5..9b98b8f 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -487,7 +487,7 @@ void ELFObjectWriterImpl::WriteSymbolTable(MCDataFragment *F, } } -// FIXME: this is currently X86_64 only +// FIXME: this is currently X86/X86_64 only void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, @@ -495,8 +495,6 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm, MCValue Target, uint64_t &FixedValue) { unsigned IsPCRel = isFixupKindX86PCRel(Fixup.getKind()); - ELFRelocationEntry ERE; - struct ELF::Elf64_Rela ERE64; uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); @@ -508,7 +506,7 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm, Value = Target.getConstant(); if (Target.isAbsolute()) { - Type = ELF::R_X86_64_NONE; + Type = Is64Bit ? ELF::R_X86_64_NONE : ELF::R_386_NONE; Index = 0; } else { const MCSymbol *Symbol = &Target.getSymA()->getSymbol(); @@ -540,34 +538,57 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm, } // determine the type of the relocation - if (IsPCRel) { - Type = ELF::R_X86_64_PC32; + if (Is64Bit) { + if (IsPCRel) { + Type = ELF::R_X86_64_PC32; + } else { + switch ((unsigned)Fixup.getKind()) { + default: llvm_unreachable("invalid fixup kind!"); + case FK_Data_8: Type = ELF::R_X86_64_64; break; + case X86::reloc_pcrel_4byte: + case FK_Data_4: + // check that the offset fits within a signed long + if (isInt<32>(Target.getConstant())) + Type = ELF::R_X86_64_32S; + else + Type = ELF::R_X86_64_32; + break; + case FK_Data_2: Type = ELF::R_X86_64_16; break; + case X86::reloc_pcrel_1byte: + case FK_Data_1: Type = ELF::R_X86_64_8; break; + } + } } else { - switch ((unsigned)Fixup.getKind()) { - default: llvm_unreachable("invalid fixup kind!"); - case FK_Data_8: Type = ELF::R_X86_64_64; break; - case X86::reloc_pcrel_4byte: - case FK_Data_4: - // check that the offset fits within a signed long - if (isInt<32>(Target.getConstant())) - Type = ELF::R_X86_64_32S; - else - Type = ELF::R_X86_64_32; - break; - case FK_Data_2: Type = ELF::R_X86_64_16; break; - case X86::reloc_pcrel_1byte: - case FK_Data_1: - Type = ELF::R_X86_64_8; - break; + if (IsPCRel) { + Type = ELF::R_386_PC32; + } else { + switch ((unsigned)Fixup.getKind()) { + default: llvm_unreachable("invalid fixup kind!"); + case X86::reloc_pcrel_4byte: + case FK_Data_4: Type = ELF::R_386_32; break; + case FK_Data_2: Type = ELF::R_386_16; break; + case X86::reloc_pcrel_1byte: + case FK_Data_1: Type = ELF::R_386_8; break; + } } } FixedValue = Value; - ERE64.setSymbolAndType(Index, Type); + ELFRelocationEntry ERE; + + if (Is64Bit) { + struct ELF::Elf64_Rela ERE64; + ERE64.setSymbolAndType(Index, Type); + ERE.r_info = ERE64.r_info; + } else { + struct ELF::Elf32_Rela ERE32; + ERE32.setSymbolAndType(Index, Type); + ERE.r_info = ERE32.r_info; + } ERE.r_offset = FixupOffset; - ERE.r_info = ERE64.r_info; + if (HasRelocationAddend) ERE.r_addend = Addend; else |