diff options
author | Nate Begeman <natebegeman@mac.com> | 2007-01-26 22:39:48 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2007-01-26 22:39:48 +0000 |
commit | 6635f35cae9d5a5d363d3ba425d4b1f323fc689d (patch) | |
tree | b5e1890f71eaa05fd33f928fd1530a4bcbfe9ca1 /lib | |
parent | ea516cce65e7c9f1c49dd2e0634d73f89bb954a4 (diff) | |
download | external_llvm-6635f35cae9d5a5d363d3ba425d4b1f323fc689d.zip external_llvm-6635f35cae9d5a5d363d3ba425d4b1f323fc689d.tar.gz external_llvm-6635f35cae9d5a5d363d3ba425d4b1f323fc689d.tar.bz2 |
Handle multiple functions, properly mangle symbols, and fix support for
scattered relocations.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33555 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/MachOWriter.cpp | 57 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCMachOWriter.cpp | 35 |
2 files changed, 64 insertions, 28 deletions
diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp index bc54728..63f1ad4 100644 --- a/lib/CodeGen/MachOWriter.cpp +++ b/lib/CodeGen/MachOWriter.cpp @@ -145,6 +145,15 @@ void MachOCodeEmitter::startFunction(MachineFunction &F) { BufferBegin = &MOS->SectionData[0]; BufferEnd = BufferBegin + MOS->SectionData.capacity(); + // Upgrade the section alignment if required. + if (MOS->align < Align) MOS->align = Align; + + // Round the size up to the correct alignment for starting the new function. + if ((MOS->size & ((1 << Align) - 1)) != 0) { + MOS->size += (1 << Align); + MOS->size &= ~((1 << Align) - 1); + } + // FIXME: Using MOS->size directly here instead of calculating it from the // output buffer size (impossible because the code emitter deals only in raw // bytes) forces us to manually synchronize size and write padding zero bytes @@ -154,9 +163,6 @@ void MachOCodeEmitter::startFunction(MachineFunction &F) { // AddSymbolToSection to prevent calling it on the text section. CurBufferPtr = BufferBegin + MOS->size; - // Upgrade the section alignment if required. - if (MOS->align < Align) MOS->align = Align; - // Clear per-function data structures. CPLocations.clear(); CPSections.clear(); @@ -170,12 +176,15 @@ bool MachOCodeEmitter::finishFunction(MachineFunction &F) { // Get the Mach-O Section that this function belongs in. MachOWriter::MachOSection *MOS = MOW.getTextSection(); - MOS->size += CurBufferPtr - BufferBegin; - // Get a symbol for the function to add to the symbol table + // FIXME: it seems like we should call something like AddSymbolToSection + // in startFunction rather than changing the section size and symbol n_value + // here. const GlobalValue *FuncV = F.getFunction(); MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TM); - + FnSym.n_value = MOS->size; + MOS->size = CurBufferPtr - BufferBegin; + // Emit constant pool to appropriate section(s) emitConstantPool(F.getConstantPool()); @@ -635,6 +644,7 @@ void MachOWriter::BufferSymbolAndStringTable() { if (PartitionByLocal(*I)) { ++DySymTab.nlocalsym; ++DySymTab.iextdefsym; + ++DySymTab.iundefsym; } else if (PartitionByDefined(*I)) { ++DySymTab.nextdefsym; ++DySymTab.iundefsym; @@ -692,6 +702,10 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) { for (unsigned i = 0, e = MOS.Relocations.size(); i != e; ++i) { MachineRelocation &MR = MOS.Relocations[i]; unsigned TargetSection = MR.getConstantVal(); + + // This is a scattered relocation entry if it points to a global value with + // a non-zero offset. + bool Scattered = false; // Since we may not have seen the GlobalValue we were interested in yet at // the time we emitted the relocation for it, fix it up now so that it @@ -699,15 +713,16 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) { if (MR.isGlobalValue()) { GlobalValue *GV = MR.getGlobalValue(); MachOSection *MOSPtr = GVSection[GV]; - intptr_t offset = GVOffset[GV]; + intptr_t Offset = GVOffset[GV]; + Scattered = TargetSection != 0; assert(MOSPtr && "Trying to relocate unknown global!"); TargetSection = MOSPtr->Index; - MR.setResultPointer((void*)offset); + MR.setResultPointer((void*)Offset); } - GetTargetRelocation(MR, MOS, *SectionList[TargetSection-1]); + GetTargetRelocation(MR, MOS, *SectionList[TargetSection-1], Scattered); } } @@ -721,6 +736,8 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset, WorkList.push_back(CPair(C,(intptr_t)Addr + Offset)); + intptr_t ScatteredOffset = 0; + while (!WorkList.empty()) { const Constant *PC = WorkList.back().first; intptr_t PA = WorkList.back().second; @@ -737,7 +754,13 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset, // FIXME: Handle ConstantExpression. See EE::getConstantValue() // switch (CE->getOpcode()) { - case Instruction::GetElementPtr: + case Instruction::GetElementPtr: { + std::vector<Value*> Indexes(CE->op_begin()+1, CE->op_end()); + ScatteredOffset = TD->getIndexedOffset(CE->getOperand(0)->getType(), + Indexes); + WorkList.push_back(CPair(CE->getOperand(0), PA)); + break; + } case Instruction::Add: default: cerr << "ConstantExpr not handled as global var init: " << *CE << "\n"; @@ -805,14 +828,16 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset, break; } case Type::PointerTyID: - if (isa<ConstantPointerNull>(C)) + if (isa<ConstantPointerNull>(PC)) memset(ptr, 0, TD->getPointerSize()); - else if (const GlobalValue* GV = dyn_cast<GlobalValue>(C)) + else if (const GlobalValue* GV = dyn_cast<GlobalValue>(PC)) { // FIXME: what about function stubs? MRs.push_back(MachineRelocation::getGV(PA-(intptr_t)Addr, MachineRelocation::VANILLA, - const_cast<GlobalValue*>(GV))); - else + const_cast<GlobalValue*>(GV), + ScatteredOffset)); + ScatteredOffset = 0; + } else assert(0 && "Unknown constant pointer type!"); break; default: @@ -853,10 +878,10 @@ MachOSym::MachOSym(const GlobalValue *gv, std::string name, uint8_t sect, assert(!isa<Function>(gv) && "Unexpected linkage type for Function!"); case GlobalValue::ExternalLinkage: GVName = TAI->getGlobalPrefix() + name; - n_type |= N_EXT; + n_type |= GV->hasHiddenVisibility() ? N_PEXT : N_EXT; break; case GlobalValue::InternalLinkage: - GVName = TAI->getPrivateGlobalPrefix() + name; + GVName = TAI->getGlobalPrefix() + name; break; } } diff --git a/lib/Target/PowerPC/PPCMachOWriter.cpp b/lib/Target/PowerPC/PPCMachOWriter.cpp index c3cc74e..9a1a608 100644 --- a/lib/Target/PowerPC/PPCMachOWriter.cpp +++ b/lib/Target/PowerPC/PPCMachOWriter.cpp @@ -27,7 +27,7 @@ namespace { : MachOWriter(O, TM) {} virtual void GetTargetRelocation(MachineRelocation &MR, MachOSection &From, - MachOSection &To); + MachOSection &To, bool Scattered); // Constants for the relocation r_type field. // see <mach-o/ppc/reloc.h> @@ -59,7 +59,8 @@ void llvm::addPPCMachOObjectWriterPass(FunctionPassManager &FPM, /// by that relocation type. void PPCMachOWriter::GetTargetRelocation(MachineRelocation &MR, MachOSection &From, - MachOSection &To) { + MachOSection &To, + bool Scattered) { uint64_t Addr = 0; // Keep track of whether or not this is an externally defined relocation. @@ -77,18 +78,30 @@ void PPCMachOWriter::GetTargetRelocation(MachineRelocation &MR, case PPC::reloc_vanilla: { // FIXME: need to handle 64 bit vanilla relocs - MachORelocation VANILLA(MR.getMachineCodeOffset(), To.Index, false, 2, - isExtern, PPC_RELOC_VANILLA); + MachORelocation VANILLA(MR.getMachineCodeOffset(), To.Index, false, 2, + isExtern, PPC_RELOC_VANILLA, Scattered, + (intptr_t)MR.getResultPointer()); ++From.nreloc; - OutputBuffer RelocOut(From.RelocBuffer, is64Bit, isLittleEndian); - RelocOut.outword(VANILLA.r_address); - RelocOut.outword(VANILLA.getPackedFields()); - OutputBuffer SecOut(From.SectionData, is64Bit, isLittleEndian); - SecOut.fixword(Addr, MR.getMachineCodeOffset()); - break; + + if (Scattered) { + RelocOut.outword(VANILLA.getPackedFields()); + RelocOut.outword(VANILLA.getAddress()); + } else { + RelocOut.outword(VANILLA.getAddress()); + RelocOut.outword(VANILLA.getPackedFields()); + } + + intptr_t SymbolOffset; + if (Scattered) + SymbolOffset = Addr + MR.getConstantVal(); + else + SymbolOffset = Addr; + printf("vanilla fixup: sec_%x[%x] = %x\n", From.Index, unsigned(MR.getMachineCodeOffset()), (unsigned)SymbolOffset); + SecOut.fixword(SymbolOffset, MR.getMachineCodeOffset()); } + break; case PPC::reloc_pcrel_bx: { Addr -= MR.getMachineCodeOffset(); @@ -124,7 +137,6 @@ void PPCMachOWriter::GetTargetRelocation(MachineRelocation &MR, RelocOut.outword(HA16.getPackedFields()); RelocOut.outword(PAIR.r_address); RelocOut.outword(PAIR.getPackedFields()); - printf("ha16: %x\n", (unsigned)Addr); Addr += 0x8000; OutputBuffer SecOut(From.SectionData, is64Bit, isLittleEndian); @@ -145,7 +157,6 @@ void PPCMachOWriter::GetTargetRelocation(MachineRelocation &MR, RelocOut.outword(LO16.getPackedFields()); RelocOut.outword(PAIR.r_address); RelocOut.outword(PAIR.getPackedFields()); - printf("lo16: %x\n", (unsigned)Addr); OutputBuffer SecOut(From.SectionData, is64Bit, isLittleEndian); SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2); |