From: Evan Cheng Date: Tue, 7 Feb 2006 08:38:37 +0000 (+0000) Subject: Darwin ABI issues: weak, linkonce, etc. dynamic-no-pic support is complete. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2338c5cb0e7c102ae2269d9a6b6e3d620ed206da;p=oota-llvm.git Darwin ABI issues: weak, linkonce, etc. dynamic-no-pic support is complete. Also fixed a function stub bug. Added weak and linkonce support for x86 Linux. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26038 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index 353cd5460f9..301bcfe7e2b 100755 --- a/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -33,12 +33,32 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { EmitConstantPool(MF.getConstantPool()); // Print out labels for the function. - SwitchSection("\t.text\n", MF.getFunction()); - EmitAlignment(4); // FIXME: This should be parameterized somewhere. - if (!MF.getFunction()->hasInternalLinkage()) + const Function *F = MF.getFunction(); + switch (F->getLinkage()) { + default: assert(0 && "Unknown linkage type!"); + case Function::InternalLinkage: // Symbols default to internal. + SwitchSection(".text", F); + EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. + break; + case Function::ExternalLinkage: + SwitchSection(".text", F); + EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. O << "\t.globl\t" << CurrentFnName << "\n"; - if (HasDotTypeDotSizeDirective) - O << "\t.type\t" << CurrentFnName << ", @function\n"; + break; + case Function::WeakLinkage: + case Function::LinkOnceLinkage: + if (forDarwin) { + SwitchSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions", + F); + O << "\t.weak_definition\t" << CurrentFnName << "\n"; + } else { + EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. + O << "\t.section\t.llvm.linkonce.t." << CurrentFnName + << ",\"ax\",@progbits\n"; + O << "\t.weak " << CurrentFnName << "\n"; + } + break; + } O << CurrentFnName << ":\n"; // Print out code for the function. @@ -95,27 +115,24 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, return; case MachineOperand::MO_GlobalAddress: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); - // Darwin block shameless ripped from PowerPCAsmPrinter.cpp + bool isMemOp = Modifier && !strcmp(Modifier, "mem"); + // Darwin block shameless ripped from PPCAsmPrinter.cpp if (forDarwin) { - if (!isCallOp) O << '$'; + if (!isMemOp && !isCallOp) O << '$'; GlobalValue *GV = MO.getGlobal(); std::string Name = Mang->getValueName(GV); - - // Dynamically-resolved functions need a stub for the function. Be - // wary however not to output $stub for external functions whose addresses - // are taken. Those should be emitted as $non_lazy_ptr below. - Function *F = dyn_cast(GV); - if (F && isCallOp && F->isExternal()) { - FnStubs.insert(Name); - O << "L" << Name << "$stub"; - } else if (GV->hasLinkOnceLinkage()) { - // Link-once, External, or Weakly-linked global variables need - // non-lazily-resolved stubs - LinkOnceStubs.insert(Name); - O << "L" << Name << "$non_lazy_ptr"; - } else if (GV->isExternal() || GV->hasWeakLinkage()) { - GVStubs.insert(Name); - O << "L" << Name << "$non_lazy_ptr"; + // Link-once, External, or Weakly-linked global variables need + // non-lazily-resolved stubs + if (GV->isExternal() || GV->hasWeakLinkage() || + GV->hasLinkOnceLinkage()) { + // Dynamically-resolved functions need a stub for the function. + if (isCallOp && isa(GV) && cast(GV)->isExternal()) { + FnStubs.insert(Name); + O << "L" << Name << "$stub"; + } else { + GVStubs.insert(Name); + O << "L" << Name << "$non_lazy_ptr"; + } } else { O << Mang->getValueName(GV); } @@ -126,7 +143,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, O << Offset; return; } - if (!isCallOp) O << '$'; + if (!isMemOp && !isCallOp) O << '$'; O << Mang->getValueName(MO.getGlobal()); int Offset = MO.getOffset(); if (Offset > 0) @@ -137,13 +154,14 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, } case MachineOperand::MO_ExternalSymbol: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); + bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (isCallOp && forDarwin) { std::string Name(GlobalPrefix); Name += MO.getSymbolName(); FnStubs.insert(Name); O << "L" << Name << "$stub"; return; } - if (!isCallOp) O << '$'; + if (!isMemOp && !isCallOp) O << '$'; O << GlobalPrefix << MO.getSymbolName(); return; } @@ -197,7 +215,7 @@ void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ } if (DispSpec.isGlobalAddress()) { - printOperand(MI, Op+3, "call"); + printOperand(MI, Op+3, "mem"); } else { int DispVal = DispSpec.getImmedValue(); if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 1e426643d5b..dd19d9fd2a0 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -80,113 +80,93 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { const TargetData &TD = TM.getTargetData(); // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), - E = M.global_end(); I != E; ++I) { + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { if (!I->hasInitializer()) continue; // External global require no code // Check to see if this is a special global used by LLVM, if so, emit it. if (I->hasAppendingLinkage() && EmitSpecialLLVMGlobal(I)) continue; - O << "\n\n"; std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); unsigned Size = TD.getTypeSize(C->getType()); unsigned Align = getPreferredAlignmentLog(I); - switch (I->getLinkage()) { - default: assert(0 && "Unknown linkage type!"); - case GlobalValue::LinkOnceLinkage: - case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. - if (C->isNullValue()) { - O << COMMDirective << name << "," << Size; - if (COMMDirectiveTakesAlignment) - O << "," << (1 << Align); - O << "\t\t" << CommentString << " " << I->getName() << "\n"; - continue; - } - - // Nonnull linkonce -> weak - O << "\t.weak " << name << "\n"; - O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; - SwitchSection("", I); - break; - case GlobalValue::InternalLinkage: - if (C->isNullValue()) { - if (LCOMMDirective) { + if (C->isNullValue() && /* FIXME: Verify correct */ + (I->hasInternalLinkage() || I->hasWeakLinkage() || + I->hasLinkOnceLinkage())) { + if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. + if (forDarwin) { + SwitchSection(".data", I); + if (I->hasInternalLinkage()) O << LCOMMDirective << name << "," << Size << "," << Align; - continue; + else + O << COMMDirective << name << "," << Size; + } else { + SwitchSection(".local", I); + O << COMMDirective << name << "," << Size << "," << Align; + } + O << "\t\t" << CommentString << " '" << I->getName() << "'\n"; + } else { + switch (I->getLinkage()) { + case GlobalValue::LinkOnceLinkage: + case GlobalValue::WeakLinkage: + if (forDarwin) { + O << "\t.globl " << name << '\n' + << "\t.weak_definition " << name << '\n'; + SwitchSection(".section __DATA,__datacoal_nt,coalesced", I); } else { - SwitchSection(".bss", I); - O << "\t.local " << name << "\n"; - O << COMMDirective << name << "," << Size; - if (COMMDirectiveTakesAlignment) - O << "," << (1 << Align); - O << "\t\t# "; - WriteAsOperand(O, I, true, true, &M); - O << "\n"; - continue; + O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; + O << "\t.weak " << name << "\n"; } + break; + case GlobalValue::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of + // their name or something. For now, just emit them as external. + case GlobalValue::ExternalLinkage: + // If external or appending, declare as a global symbol + O << "\t.globl " << name << "\n"; + // FALL THROUGH + case GlobalValue::InternalLinkage: + SwitchSection(".data", I); + break; + default: + assert(0 && "Unknown linkage type!"); } - SwitchSection(".data", I); - break; - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables should go into a section of - // their name or something. For now, just emit them as external. - case GlobalValue::ExternalLinkage: - SwitchSection(C->isNullValue() ? ".bss" : ".data", I); - // If external or appending, declare as a global symbol - O << "\t.globl " << name << "\n"; - break; - } - EmitAlignment(Align); - if (HasDotTypeDotSizeDirective) { - O << "\t.type " << name << ",@object\n"; - O << "\t.size " << name << "," << Size << "\n"; + EmitAlignment(Align, I); + O << name << ":\t\t\t\t" << CommentString << " '" << I->getName() + << "'\n"; + EmitGlobalConstant(C); + O << '\n'; } - O << name << ":\t\t\t" << CommentString << ' ' << I->getName() << '\n'; - EmitGlobalConstant(C); } if (forDarwin) { SwitchSection("", 0); - // Output stubs for external global variables - if (GVStubs.begin() != GVStubs.end()) - O << "\t.non_lazy_symbol_pointer\n"; - for (std::set::iterator i = GVStubs.begin(), e = GVStubs.end(); - i != e; ++i) { - O << "L" << *i << "$non_lazy_ptr:\n"; - O << "\t.indirect_symbol " << *i << "\n"; - O << "\t.long\t0\n"; - } // Output stubs for dynamically-linked functions unsigned j = 1; for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i, ++j) { - O << "\t.symbol_stub\n"; + SwitchSection(".section __IMPORT,__jump_table,symbol_stubs," + "self_modifying_code+pure_instructions,5", 0); O << "L" << *i << "$stub:\n"; O << "\t.indirect_symbol " << *i << "\n"; - O << "\tjmp\t*L" << j << "$lz\n"; - O << "L" << *i << "$stub_binder:\n"; - O << "\tpushl\t$L" << j << "$lz\n"; - O << "\tjmp\tdyld_stub_binding_helper\n"; - O << "\t.section __DATA, __la_sym_ptr3,lazy_symbol_pointers\n"; - O << "L" << j << "$lz:\n"; - O << "\t.indirect_symbol " << *i << "\n"; - O << "\t.long\tL" << *i << "$stub_binder\n"; + O << "\thlt ; hlt ; hlt ; hlt ; hlt\n"; } O << "\n"; - // Output stubs for link-once variables - if (LinkOnceStubs.begin() != LinkOnceStubs.end()) - O << ".data\n.align 2\n"; - for (std::set::iterator i = LinkOnceStubs.begin(), - e = LinkOnceStubs.end(); i != e; ++i) { - O << "L" << *i << "$non_lazy_ptr:\n" - << "\t.long\t" << *i << '\n'; + // Output stubs for external and common global variables. + if (GVStubs.begin() != GVStubs.end()) + SwitchSection(".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0); + for (std::set::iterator i = GVStubs.begin(), e = GVStubs.end(); + i != e; ++i) { + O << "L" << *i << "$non_lazy_ptr:\n"; + O << "\t.indirect_symbol " << *i << "\n"; + O << "\t.long\t0\n"; } } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index def4f570170..1c6a8b35f97 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1876,11 +1876,13 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { // the GlobalAddress must be in the base or index register of the address, // not the GV offset field. if (getTargetMachine(). - getSubtarget().getIndirectExternAndWeakGlobals() && - (GV->hasWeakLinkage() || GV->isExternal())) - Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), - DAG.getTargetGlobalAddress(GV, getPointerTy()), - DAG.getSrcValue(NULL)); + getSubtarget().getIndirectExternAndWeakGlobals()) { + if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || + (GV->isExternal() && !GV->hasNotBeenReadFromBytecode())) + Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), + DAG.getTargetGlobalAddress(GV, getPointerTy()), + DAG.getSrcValue(NULL)); + } return Result; } case ISD::VASTART: { diff --git a/lib/Target/X86/X86IntelAsmPrinter.cpp b/lib/Target/X86/X86IntelAsmPrinter.cpp index 550e081dbdd..fba450bb7f0 100755 --- a/lib/Target/X86/X86IntelAsmPrinter.cpp +++ b/lib/Target/X86/X86IntelAsmPrinter.cpp @@ -109,7 +109,7 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO, abort (); return; case MachineOperand::MO_GlobalAddress: { - if (!Modifier || strcmp(Modifier, "call")) + if (!Modifier || strcmp(Modifier, "call") || strcmp(Modifier, "mem")) O << "OFFSET "; O << Mang->getValueName(MO.getGlobal()); int Offset = MO.getOffset(); @@ -161,7 +161,7 @@ void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ O << "["; bool NeedPlus = false; if (BaseReg.getReg()) { - printOp(BaseReg, "call"); + printOp(BaseReg, "mem"); NeedPlus = true; } @@ -176,7 +176,7 @@ void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ if (DispSpec.isGlobalAddress()) { if (NeedPlus) O << " + "; - printOp(DispSpec, "call"); + printOp(DispSpec, "mem"); } else { int DispVal = DispSpec.getImmedValue(); if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) {