From e5b57347e9485b59dd8d70f8f90d7794f473147a Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Tue, 17 Aug 2010 18:20:28 +0000 Subject: [PATCH] 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 --- include/llvm/Support/ELF.h | 21 ++++++++++++ lib/MC/ELFObjectWriter.cpp | 69 +++++++++++++++++++++++++------------- 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index f33aeb4188a..83478b75cbc 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -216,6 +216,27 @@ enum { R_X86_64_TLSDESC = 36 }; +// i386 relocations. +// TODO: this is just a subset +enum { + R_386_NONE = 0, + R_386_32 = 1, + R_386_PC32 = 2, + R_386_GOT32 = 3, + R_386_PLT32 = 4, + R_386_COPY = 5, + R_386_GLOB_DAT = 6, + R_386_JUMP_SLOT = 7, + R_386_RELATIVE = 8, + R_386_GOTOFF = 9, + R_386_GOTPC = 10, + R_386_32PLT = 11, + R_386_16 = 20, + R_386_PC16 = 21, + R_386_8 = 22, + R_386_PC8 = 23 +}; + // Section header. struct Elf32_Shdr { Elf32_Word sh_name; // Section name (index into string table) diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 23c2dd5c207..9b98b8f8957 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 -- 2.34.1