From 52d0851446afe2ae923fc7e7ee56aa4c9d61c1e1 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Wed, 5 Aug 2009 06:57:03 +0000 Subject: [PATCH] - Remove custom handling of jumptables by the elf writter (this was a dirty hack and isn't need anymore since the last x86 code emitter patch) - Add a target-dependent modifier to addend calculation - Use R_X86_64_32S relocation for X86::reloc_absolute_word_sext - Use getELFSectionFlags whenever possible - fix getTextSection to use TLOF and emit the right text section - Handle global emission for static ctors, dtors and Type::PointerTyID - Some minor fixes git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78176 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetELFWriterInfo.h | 11 +- lib/CodeGen/ELF.h | 12 ++ lib/CodeGen/ELFCodeEmitter.cpp | 30 +-- lib/CodeGen/ELFWriter.cpp | 240 ++++++++++++++-------- lib/CodeGen/ELFWriter.h | 33 +-- lib/CodeGen/ObjectCodeEmitter.cpp | 5 +- lib/Target/X86/X86ELFWriterInfo.cpp | 15 +- lib/Target/X86/X86ELFWriterInfo.h | 13 +- 8 files changed, 223 insertions(+), 136 deletions(-) diff --git a/include/llvm/Target/TargetELFWriterInfo.h b/include/llvm/Target/TargetELFWriterInfo.h index 37e903c29e1..7cb693155c2 100644 --- a/include/llvm/Target/TargetELFWriterInfo.h +++ b/include/llvm/Target/TargetELFWriterInfo.h @@ -89,14 +89,6 @@ namespace llvm { : (hasRelocationAddend() ? 12 : 8); } - /// hasCustomJumpTableIndexRelTy - Returns true if the target has a - /// specific relocation type for a jump table index. - virtual bool hasCustomJumpTableIndexRelTy() const { return false; } - - /// getJumpTableIndexRelTy - Returns the target specific relocation type - /// for a jump table index. - virtual unsigned getJumpTableIndexRelTy() const { return 0; } - /// getRelocationType - Returns the target specific ELF Relocation type. /// 'MachineRelTy' contains the object code independent relocation type virtual unsigned getRelocationType(unsigned MachineRelTy) const = 0; @@ -107,7 +99,8 @@ namespace llvm { /// getDefaultAddendForRelTy - Gets the default addend value for a /// relocation entry based on the target ELF relocation type. - virtual long int getDefaultAddendForRelTy(unsigned RelTy) const = 0; + virtual long int getDefaultAddendForRelTy(unsigned RelTy, + long int Modifier = 0) const = 0; /// getRelTySize - Returns the size of relocatable field in bits virtual unsigned getRelocationTySize(unsigned RelTy) const = 0; diff --git a/lib/CodeGen/ELF.h b/lib/CodeGen/ELF.h index d21b90eeba7..499af10c79e 100644 --- a/lib/CodeGen/ELF.h +++ b/lib/CodeGen/ELF.h @@ -136,6 +136,18 @@ namespace llvm { return Sym; } + // getFileSym - Returns a elf symbol to represent the module identifier + static ELFSym *getUndefGV(const GlobalValue *GV) { + ELFSym *Sym = new ELFSym(); + Sym->Source.GV = GV; + Sym->setBind(STB_GLOBAL); + Sym->setType(STT_NOTYPE); + Sym->setVisibility(STV_DEFAULT); + Sym->SectionIdx = 0; //ELFSection::SHN_UNDEF; + Sym->SourceType = isGV; + return Sym; + } + // ELF specific fields unsigned NameIdx; // Index in .strtab of name, once emitted. uint64_t Value; diff --git a/lib/CodeGen/ELFCodeEmitter.cpp b/lib/CodeGen/ELFCodeEmitter.cpp index d363adbe0d0..61a9d5a57b3 100644 --- a/lib/CodeGen/ELFCodeEmitter.cpp +++ b/lib/CodeGen/ELFCodeEmitter.cpp @@ -40,7 +40,7 @@ void ELFCodeEmitter::startFunction(MachineFunction &MF) { << MF.getFunction()->getName() << "\n"); // Get the ELF Section that this function belongs in. - ES = &EW.getTextSection(); + ES = &EW.getTextSection(MF.getFunction()); // Set the desired binary object to be used by the code emitters setBinaryObject(ES); @@ -52,7 +52,7 @@ void ELFCodeEmitter::startFunction(MachineFunction &MF) { ES->emitAlignment(Align); // Update the section alignment if needed. - if (ES->Align < Align) ES->Align = Align; + ES->Align = std::max(ES->Align, Align); // Record the function start offset FnStartOff = ES->getCurrentPCOffset(); @@ -73,7 +73,7 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) { EW.getGlobalELFVisibility(F)); FnSym->SectionIdx = ES->SectionIdx; FnSym->Size = ES->getCurrentPCOffset()-FnStartOff; - EW.addGlobalSymbol(F); + EW.addGlobalSymbol(F, true); // Offset from start of Section FnSym->Value = FnStartOff; @@ -83,22 +83,21 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) { // Patch up Jump Table Section relocations to use the real MBBs offsets // now that the MBB label offsets inside the function are known. - ELFSection &JTSection = EW.getJumpTableSection(); - for (std::vector::iterator MRI = JTRelocations.begin(), - MRE = JTRelocations.end(); MRI != MRE; ++MRI) { - MachineRelocation &MR = *MRI; - unsigned MBBOffset = getMachineBasicBlockAddress(MR.getBasicBlock()); - MR.setResultPointer((void*)MBBOffset); - MR.setConstantVal(ES->SectionIdx); - JTSection.addRelocation(MR); + if (!MF.getJumpTableInfo()->isEmpty()) { + ELFSection &JTSection = EW.getJumpTableSection(); + for (std::vector::iterator MRI = JTRelocations.begin(), + MRE = JTRelocations.end(); MRI != MRE; ++MRI) { + MachineRelocation &MR = *MRI; + unsigned MBBOffset = getMachineBasicBlockAddress(MR.getBasicBlock()); + MR.setResultPointer((void*)MBBOffset); + MR.setConstantVal(ES->SectionIdx); + JTSection.addRelocation(MR); + } } - // Relocations - // ----------- // If we have emitted any relocations to function-specific objects such as // basic blocks, constant pools entries, or jump tables, record their - // addresses now so that we can rewrite them with the correct addresses - // later. + // addresses now so that we can rewrite them with the correct addresses later for (unsigned i = 0, e = Relocations.size(); i != e; ++i) { MachineRelocation &MR = Relocations[i]; intptr_t Addr; @@ -115,6 +114,7 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) { MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]); MR.setResultPointer((void*)Addr); } else if (MR.isJumpTableIndex()) { + ELFSection &JTSection = EW.getJumpTableSection(); Addr = getJumpTableEntryAddress(MR.getJumpTableIndex()); MR.setConstantVal(JTSection.SectionIdx); MR.setResultPointer((void*)Addr); diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index 31225642695..93e84154162 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/lib/CodeGen/ELFWriter.cpp @@ -76,6 +76,7 @@ ObjectCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM, ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm) : MachineFunctionPass(&ID), O(o), TM(tm), OutContext(*new MCContext()), + TLOF(TM.getTargetLowering()->getObjFileLowering()), is64Bit(TM.getTargetData()->getPointerSizeInBits() == 64), isLittleEndian(TM.getTargetData()->isLittleEndian()), ElfHdr(isLittleEndian, is64Bit) { @@ -99,8 +100,6 @@ ELFWriter::~ELFWriter() { // the module to the ELF file. bool ELFWriter::doInitialization(Module &M) { // Initialize TargetLoweringObjectFile. - const TargetLoweringObjectFile &TLOF = - TM.getTargetLowering()->getObjFileLowering(); const_cast(TLOF).Initialize(OutContext, TM); Mang = new Mangler(M); @@ -160,11 +159,13 @@ bool ELFWriter::doInitialization(Module &M) { return false; } -// addGlobalSymbol - Add a global to be processed and to the -// global symbol lookup, use a zero index for non private symbols -// because the table index will be determined later. -void ELFWriter::addGlobalSymbol(const GlobalValue *GV) { +// addGlobalSymbol - Add a global to be processed and to the global symbol +// lookup, use a zero index because the table index will be determined later. +void ELFWriter::addGlobalSymbol(const GlobalValue *GV, + bool AddToLookup /* = false */) { PendingGlobals.insert(GV); + if (AddToLookup) + GblSymLookup[GV] = 0; } // addExternalSymbol - Add the external to be processed and to the @@ -175,20 +176,39 @@ void ELFWriter::addExternalSymbol(const char *External) { ExtSymLookup[External] = 0; } -// Get jump table section on the section name returned by TAI -ELFSection &ELFWriter::getJumpTableSection() { - unsigned Align = TM.getTargetData()->getPointerABIAlignment(); - - const TargetLoweringObjectFile &TLOF = - TM.getTargetLowering()->getObjFileLowering(); - - return getSection(TLOF.getSectionForConstant(SectionKind::getReadOnly()) - ->getName(), - ELFSection::SHT_PROGBITS, - ELFSection::SHF_ALLOC, Align); +// getCtorSection - Get the static constructor section +ELFSection &ELFWriter::getCtorSection() { + const MCSection *Ctor = TLOF.getStaticCtorSection(); + return getSection(Ctor->getName(), ELFSection::SHT_PROGBITS, + getElfSectionFlags(Ctor->getKind())); } -// Get a constant pool section based on the section name returned by TAI +// getDtorSection - Get the static destructor section +ELFSection &ELFWriter::getDtorSection() { + const MCSection *Dtor = TLOF.getStaticDtorSection(); + return getSection(Dtor->getName(), ELFSection::SHT_PROGBITS, + getElfSectionFlags(Dtor->getKind())); +} + +// getTextSection - Get the text section for the specified function +ELFSection &ELFWriter::getTextSection(Function *F) { + const MCSection *Text = TLOF.SectionForGlobal(F, Mang, TM); + return getSection(Text->getName(), ELFSection::SHT_PROGBITS, + getElfSectionFlags(Text->getKind())); +} + +// getJumpTableSection - Get a read only section for constants when +// emitting jump tables. TODO: add PIC support +ELFSection &ELFWriter::getJumpTableSection() { + const MCSection *JT = TLOF.getSectionForConstant(SectionKind::getReadOnly()); + return getSection(JT->getName(), + ELFSection::SHT_PROGBITS, + getElfSectionFlags(JT->getKind()), + TM.getTargetData()->getPointerABIAlignment()); +} + +// getConstantPoolSection - Get a constant pool section based on the machine +// constant pool entry type and relocation info. ELFSection &ELFWriter::getConstantPoolSection(MachineConstantPoolEntry &CPE) { SectionKind Kind; switch (CPE.getRelocationInfo()) { @@ -206,17 +226,14 @@ ELFSection &ELFWriter::getConstantPoolSection(MachineConstantPoolEntry &CPE) { } } - const TargetLoweringObjectFile &TLOF = - TM.getTargetLowering()->getObjFileLowering(); - return getSection(TLOF.getSectionForConstant(Kind)->getName(), ELFSection::SHT_PROGBITS, - ELFSection::SHF_MERGE | ELFSection::SHF_ALLOC, + getElfSectionFlags(Kind), CPE.getAlignment()); } -// Return the relocation section of section 'S'. 'RelA' is true -// if the relocation section contains entries with addends. +// getRelocSection - Return the relocation section of section 'S'. 'RelA' +// is true if the relocation section contains entries with addends. ELFSection &ELFWriter::getRelocSection(ELFSection &S) { unsigned SectionHeaderTy = TEW->hasRelocationAddend() ? ELFSection::SHT_RELA : ELFSection::SHT_REL; @@ -248,7 +265,7 @@ unsigned ELFWriter::getGlobalELFBinding(const GlobalValue *GV) { if (GV->hasInternalLinkage()) return ELFSym::STB_LOCAL; - if (GV->hasWeakLinkage()) + if (GV->isWeakForLinker()) return ELFSym::STB_WEAK; return ELFSym::STB_GLOBAL; @@ -267,9 +284,11 @@ unsigned ELFWriter::getGlobalELFType(const GlobalValue *GV) { // getElfSectionFlags - Get the ELF Section Header flags based // on the flags defined in SectionKind.h. -unsigned ELFWriter::getElfSectionFlags(SectionKind Kind) { - unsigned ElfSectionFlags = ELFSection::SHF_ALLOC; - +unsigned ELFWriter::getElfSectionFlags(SectionKind Kind, bool IsAlloc) { + unsigned ElfSectionFlags = 0; + + if (IsAlloc) + ElfSectionFlags |= ELFSection::SHF_ALLOC; if (Kind.isText()) ElfSectionFlags |= ELFSection::SHF_EXECINSTR; if (Kind.isWriteable()) @@ -287,7 +306,8 @@ unsigned ELFWriter::getElfSectionFlags(SectionKind Kind) { // isELFUndefSym - the symbol has no section and must be placed in // the symbol table with a reference to the null section. static bool isELFUndefSym(const GlobalValue *GV) { - return GV->isDeclaration(); + // Functions which make up until this point references are an undef symbol + return GV->isDeclaration() || (isa(GV)); } // isELFBssSym - for an undef or null value, the symbol must go to a bss @@ -305,7 +325,7 @@ static bool isELFCommonSym(const GlobalVariable *GV) { } // isELFDataSym - if the symbol is an initialized but no null constant -// it must go to some kind of data section gathered from TAI +// it must go to some kind of data section static bool isELFDataSym(const Constant *CV) { return (!(CV->isNullValue() || isa(CV))); } @@ -317,27 +337,22 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) { if (GblSymLookup.find(GV) != GblSymLookup.end()) return; - // If the global is a function already emited in the text section - // just add it to the global symbol lookup with a zero index to be - // patched up later. - if (isa(GV) && !GV->isDeclaration()) { - GblSymLookup[GV] = 0; - return; - } - // Handle ELF Bind, Visibility and Type for the current symbol unsigned SymBind = getGlobalELFBinding(GV); - ELFSym *GblSym = ELFSym::getGV(GV, SymBind, getGlobalELFType(GV), - getGlobalELFVisibility(GV)); + unsigned SymType = getGlobalELFType(GV); - if (isELFUndefSym(GV)) { - GblSym->SectionIdx = ELFSection::SHN_UNDEF; - } else { + // All undef symbols have the same binding, type and visibily and + // are classified regardless of their type. + ELFSym *GblSym = isELFUndefSym(GV) ? ELFSym::getUndefGV(GV) + : ELFSym::getGV(GV, SymBind, SymType, getGlobalELFVisibility(GV)); + + if (!isELFUndefSym(GV)) { assert(isa(GV) && "GV not a global variable!"); const GlobalVariable *GVar = dyn_cast(GV); - const TargetLoweringObjectFile &TLOF = - TM.getTargetLowering()->getObjFileLowering(); + // Handle special llvm globals + if (EmitSpecialLLVMGlobal(GVar)) + return; // Get the ELF section where this global belongs from TLOF const MCSection *S = TLOF.SectionForGlobal(GV, Mang, TM); @@ -474,39 +489,106 @@ void ELFWriter::EmitGlobalConstant(const Constant *CV, ELFSection &GblS) { for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I) EmitGlobalConstant(CP->getOperand(I), GblS); return; - } else if (const GlobalValue *GV = dyn_cast(CV)) { - // This is a constant address for a global variable or function and - // therefore must be referenced using a relocation entry. - - // Check if the referenced symbol is already emitted - if (GblSymLookup.find(GV) == GblSymLookup.end()) - EmitGlobal(GV); - - // Create the relocation entry for the global value - MachineRelocation MR = - MachineRelocation::getGV(GblS.getCurrentPCOffset(), - TEW->getAbsoluteLabelMachineRelTy(), - const_cast(GV)); - - // Fill the data entry with zeros - for (unsigned i=0; i < Size; ++i) - GblS.emitByte(0); - - // Add the relocation entry for the current data section - GblS.addRelocation(MR); - return; } else if (const ConstantExpr *CE = dyn_cast(CV)) { if (CE->getOpcode() == Instruction::BitCast) { EmitGlobalConstant(CE->getOperand(0), GblS); return; } - // See AsmPrinter::EmitConstantValueOnly for other ConstantExpr types - llvm_unreachable("Unsupported ConstantExpr type"); + std::string msg(CE->getOpcodeName()); + raw_string_ostream ErrorMsg(msg); + ErrorMsg << ": Unsupported ConstantExpr type"; + llvm_report_error(ErrorMsg.str()); + } else if (CV->getType()->getTypeID() == Type::PointerTyID) { + // Fill the data entry with zeros or emit a relocation entry + if (isa(CV)) { + for (unsigned i=0; i < Size; ++i) + GblS.emitByte(0); + } else { + emitGlobalDataRelocation(cast(CV), + TD->getPointerSize(), GblS); + } + return; + } else if (const GlobalValue *GV = dyn_cast(CV)) { + // This is a constant address for a global variable or function and + // therefore must be referenced using a relocation entry. + emitGlobalDataRelocation(GV, Size, GblS); + return; } - llvm_unreachable("Unknown global constant type"); + std::string msg; + raw_string_ostream ErrorMsg(msg); + ErrorMsg << "Constant unimp for type: " << *CV->getType(); + llvm_report_error(ErrorMsg.str()); } +void ELFWriter::emitGlobalDataRelocation(const GlobalValue *GV, unsigned Size, + ELFSection &GblS) { + // Create the relocation entry for the global value + MachineRelocation MR = + MachineRelocation::getGV(GblS.getCurrentPCOffset(), + TEW->getAbsoluteLabelMachineRelTy(), + const_cast(GV)); + + // Fill the data entry with zeros + for (unsigned i=0; i < Size; ++i) + GblS.emitByte(0); + + // Add the relocation entry for the current data section + GblS.addRelocation(MR); +} + +/// EmitSpecialLLVMGlobal - Check to see if the specified global is a +/// special global used by LLVM. If so, emit it and return true, otherwise +/// do nothing and return false. +bool ELFWriter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { + if (GV->getName() == "llvm.used") + llvm_unreachable("not implemented yet"); + + // Ignore debug and non-emitted data. This handles llvm.compiler.used. + if (GV->getSection() == "llvm.metadata" || + GV->hasAvailableExternallyLinkage()) + return true; + + if (!GV->hasAppendingLinkage()) return false; + + assert(GV->hasInitializer() && "Not a special LLVM global!"); + + const TargetData *TD = TM.getTargetData(); + unsigned Align = TD->getPointerPrefAlignment(); + if (GV->getName() == "llvm.global_ctors") { + ELFSection &Ctor = getCtorSection(); + Ctor.emitAlignment(Align); + EmitXXStructorList(GV->getInitializer(), Ctor); + return true; + } + + if (GV->getName() == "llvm.global_dtors") { + ELFSection &Dtor = getDtorSection(); + Dtor.emitAlignment(Align); + EmitXXStructorList(GV->getInitializer(), Dtor); + return true; + } + + return false; +} + +/// EmitXXStructorList - Emit the ctor or dtor list. This just emits out the +/// function pointers, ignoring the init priority. +void ELFWriter::EmitXXStructorList(Constant *List, ELFSection &Xtor) { + // Should be an array of '{ int, void ()* }' structs. The first value is the + // init priority, which we ignore. + if (!isa(List)) return; + ConstantArray *InitList = cast(List); + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) + if (ConstantStruct *CS = dyn_cast(InitList->getOperand(i))){ + if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. + + if (CS->getOperand(1)->isNullValue()) + return; // Found a null terminator, exit printing. + // Emit the function pointer. + EmitGlobalConstant(CS->getOperand(1), Xtor); + } +} bool ELFWriter::runOnMachineFunction(MachineFunction &MF) { // Nothing to do here, this is all done through the ElfCE object above. @@ -638,7 +720,8 @@ void ELFWriter::EmitRelocations() { Addend = PrivateSyms[SymIdx]->Value; SymIdx = SectionList[SectionIdx]->getSymbolTableIndex(); } else { - Addend = TEW->getDefaultAddendForRelTy(RelType); + int64_t GlobalOffset = MR.getConstantVal(); + Addend = TEW->getDefaultAddendForRelTy(RelType, GlobalOffset); } } else if (MR.isExternalSymbol()) { const char *ExtSym = MR.getExternalSymbol(); @@ -648,29 +731,26 @@ void ELFWriter::EmitRelocations() { // Get the symbol index for the section symbol unsigned SectionIdx = MR.getConstantVal(); SymIdx = SectionList[SectionIdx]->getSymbolTableIndex(); - Addend = (uint64_t)MR.getResultPointer(); + + // The symbol offset inside the section + int64_t SymOffset = (int64_t)MR.getResultPointer(); // For pc relative relocations where symbols are defined in the same // section they are referenced, ignore the relocation entry and patch // the relocatable field with the symbol offset directly. if (S.SectionIdx == SectionIdx && TEW->isPCRelativeRel(RelType)) { - int64_t Value = TEW->computeRelocation(Addend, RelOffset, RelType); + int64_t Value = TEW->computeRelocation(SymOffset, RelOffset, RelType); RelocateField(S, RelOffset, Value, RelTySize); continue; } - // Handle Jump Table Index relocation - if ((SectionIdx == getJumpTableSection().SectionIdx) && - TEW->hasCustomJumpTableIndexRelTy()) { - RelType = TEW->getJumpTableIndexRelTy(); - RelTySize = TEW->getRelocationTySize(RelType); - } + Addend = TEW->getDefaultAddendForRelTy(RelType, SymOffset); } // The target without addend on the relocation symbol must be // patched in the relocation place itself to contain the addend - if (!HasRelA) - RelocateField(S, RelOffset, Addend, RelTySize); + // otherwise write zeros to make sure there is no garbage there + RelocateField(S, RelOffset, HasRelA ? 0 : Addend, RelTySize); // Get the relocation entry and emit to the relocation section ELFRelocation Rel(RelOffset, SymIdx, RelType, HasRelA, Addend); diff --git a/lib/CodeGen/ELFWriter.h b/lib/CodeGen/ELFWriter.h index ebcfe35ebaa..fe726524d32 100644 --- a/lib/CodeGen/ELFWriter.h +++ b/lib/CodeGen/ELFWriter.h @@ -33,6 +33,7 @@ namespace llvm { class ObjectCodeEmitter; class TargetAsmInfo; class TargetELFWriterInfo; + class TargetLoweringObjectFile; class raw_ostream; class SectionKind; class MCContext; @@ -66,6 +67,7 @@ namespace llvm { /// Target machine description. TargetMachine &TM; + /// Context object for machine code objects. MCContext &OutContext; /// Target Elf Writer description. @@ -78,6 +80,10 @@ namespace llvm { /// code for functions to the .o file. ELFCodeEmitter *ElfCE; + /// TLOF - Target Lowering Object File, provide section names for globals + /// and other object file specific stuff + const TargetLoweringObjectFile &TLOF; + /// TAI - Target Asm Info, provide information about section names for /// globals and other target specific stuff. const TargetAsmInfo *TAI; @@ -176,13 +182,6 @@ namespace llvm { return *SN; } - /// TODO: support mangled names here to emit the right .text section - /// for c++ object files. - ELFSection &getTextSection() { - return getSection(".text", ELFSection::SHT_PROGBITS, - ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC); - } - ELFSection &getNonExecStackSection() { return getSection(".note.GNU-stack", ELFSection::SHT_PROGBITS, 0, 1); } @@ -213,21 +212,24 @@ namespace llvm { return getSection("", ELFSection::SHT_NULL, 0); } + ELFSection &getCtorSection(); + ELFSection &getDtorSection(); ELFSection &getJumpTableSection(); ELFSection &getConstantPoolSection(MachineConstantPoolEntry &CPE); + ELFSection &getTextSection(Function *F); ELFSection &getRelocSection(ELFSection &S); // Helpers for obtaining ELF specific info. unsigned getGlobalELFBinding(const GlobalValue *GV); unsigned getGlobalELFType(const GlobalValue *GV); unsigned getGlobalELFVisibility(const GlobalValue *GV); - unsigned getElfSectionFlags(SectionKind Kind); - - // addGlobalSymbol - Add a global to be processed and to the - // global symbol lookup, use a zero index for non private symbols - // because the table index will be determined later. - void addGlobalSymbol(const GlobalValue *GV); + unsigned getElfSectionFlags(SectionKind Kind, bool IsAlloc = true); + // addGlobalSymbol - Add a global to be processed and to + // the global symbol lookup, use a zero index because the table + // index will be determined later. + void addGlobalSymbol(const GlobalValue *GV, bool AddToLookup = false); + // addExternalSymbol - Add the external to be processed and to the // external symbol lookup, use a zero index because the symbol // table index will be determined later @@ -246,7 +248,10 @@ namespace llvm { void EmitGlobalConstant(const Constant *C, ELFSection &GblS); void EmitGlobalConstantStruct(const ConstantStruct *CVS, ELFSection &GblS); - ELFSection &getGlobalSymELFSection(const GlobalVariable *GV, ELFSym &Sym); + void emitGlobalDataRelocation(const GlobalValue *GV, unsigned Size, + ELFSection &GblS); + bool EmitSpecialLLVMGlobal(const GlobalVariable *GV); + void EmitXXStructorList(Constant *List, ELFSection &Xtor); void EmitRelocations(); void EmitRelocation(BinaryObject &RelSec, ELFRelocation &Rel, bool HasRelA); void EmitSectionHeader(BinaryObject &SHdrTab, const ELFSection &SHdr); diff --git a/lib/CodeGen/ObjectCodeEmitter.cpp b/lib/CodeGen/ObjectCodeEmitter.cpp index 10448566b58..6f763404f53 100644 --- a/lib/CodeGen/ObjectCodeEmitter.cpp +++ b/lib/CodeGen/ObjectCodeEmitter.cpp @@ -55,8 +55,7 @@ void ObjectCodeEmitter::emitDWordBE(uint64_t W) { BO->emitDWordBE(W); } -/// emitAlignment - Move the CurBufferPtr pointer up the the specified -/// alignment (saturated to BufferEnd of course). +/// emitAlignment - Align 'BO' to the necessary alignment boundary. void ObjectCodeEmitter::emitAlignment(unsigned Alignment /* 0 */, uint8_t fill /* 0 */) { BO->emitAlignment(Alignment, fill); @@ -138,5 +137,7 @@ uintptr_t ObjectCodeEmitter::getConstantPoolEntrySection(unsigned Index) const { return CPSections[Index]; } +/// getNoopSize - Returns the size of the no operation instruction + } // end namespace llvm diff --git a/lib/Target/X86/X86ELFWriterInfo.cpp b/lib/Target/X86/X86ELFWriterInfo.cpp index 096c00ee305..1597d2b31d2 100644 --- a/lib/Target/X86/X86ELFWriterInfo.cpp +++ b/lib/Target/X86/X86ELFWriterInfo.cpp @@ -39,6 +39,8 @@ unsigned X86ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { return R_X86_64_PC32; case X86::reloc_absolute_word: return R_X86_64_32; + case X86::reloc_absolute_word_sext: + return R_X86_64_32S; case X86::reloc_absolute_dword: return R_X86_64_64; case X86::reloc_picrel_word: @@ -51,6 +53,7 @@ unsigned X86ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { return R_386_PC32; case X86::reloc_absolute_word: return R_386_32; + case X86::reloc_absolute_word_sext: case X86::reloc_absolute_dword: case X86::reloc_picrel_word: default: @@ -60,20 +63,22 @@ unsigned X86ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { return 0; } -long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy) const { +long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, + long int Modifier) const { if (is64Bit) { switch(RelTy) { - case R_X86_64_PC32: return -4; + case R_X86_64_PC32: return Modifier - 4; case R_X86_64_32: + case R_X86_64_32S: case R_X86_64_64: - return 0; + return Modifier; default: llvm_unreachable("unknown x86_64 relocation type"); } } else { switch(RelTy) { - case R_386_PC32: return -4; - case R_386_32: return 0; + case R_386_PC32: return Modifier - 4; + case R_386_32: return Modifier; default: llvm_unreachable("unknown x86 relocation type"); } diff --git a/lib/Target/X86/X86ELFWriterInfo.h b/lib/Target/X86/X86ELFWriterInfo.h index e882a0c84b6..342e6e627d2 100644 --- a/lib/Target/X86/X86ELFWriterInfo.h +++ b/lib/Target/X86/X86ELFWriterInfo.h @@ -49,19 +49,10 @@ namespace llvm { /// ELF relocation entry. virtual bool hasRelocationAddend() const { return is64Bit ? true : false; } - /// hasCustomJumpTableIndexRelTy - Returns true if the target has a - /// specific relocation type for a jump table index. - virtual bool hasCustomJumpTableIndexRelTy() const { - return is64Bit ? true : false; - } - - /// getJumpTableIndexRelTy - Returns the target specific relocation type - /// for a jump table index. - virtual unsigned getJumpTableIndexRelTy() const { return R_X86_64_32S; } - /// getDefaultAddendForRelTy - Gets the default addend value for a /// relocation entry based on the target ELF relocation type. - virtual long int getDefaultAddendForRelTy(unsigned RelTy) const; + virtual long int getDefaultAddendForRelTy(unsigned RelTy, + long int Modifier = 0) const; /// getRelTySize - Returns the size of relocatable field in bits virtual unsigned getRelocationTySize(unsigned RelTy) const;