mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	More Mach-O writer improvements.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34740 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -100,7 +100,8 @@ namespace llvm { | ||||
|                                          unsigned ToIdx, | ||||
|                                          OutputBuffer &RelocOut, | ||||
|                                          OutputBuffer &SecOut, | ||||
|                                          bool Scattered) const { return 0; } | ||||
|                                          bool Scattered, | ||||
|                                          bool Extern) const { return 0; } | ||||
|  | ||||
|     uint32_t getCPUType() const { return CPUType; } | ||||
|     uint32_t getCPUSubType() const { return CPUSubType; } | ||||
|   | ||||
| @@ -107,7 +107,7 @@ namespace llvm { | ||||
|      | ||||
|     virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const { | ||||
|       assert(CPLocations.size() > Index && "CP not emitted!"); | ||||
|       return CPLocations[Index]; | ||||
|       return CPLocations[Index];\ | ||||
|     } | ||||
|     virtual intptr_t getJumpTableEntryAddress(unsigned Index) const { | ||||
|       assert(JTLocations.size() > Index && "JT not emitted!"); | ||||
| @@ -225,7 +225,10 @@ bool MachOCodeEmitter::finishFunction(MachineFunction &MF) { | ||||
|       Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex()); | ||||
|       MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]); | ||||
|       MR.setResultPointer((void*)Addr); | ||||
|     } else if (!MR.isGlobalValue()) { | ||||
|     } else if (MR.isGlobalValue()) { | ||||
|       // FIXME: This should be a set or something that uniques | ||||
|       MOW.PendingGlobals.push_back(MR.getGlobalValue()); | ||||
|     } else { | ||||
|       assert(0 && "Unhandled relocation type"); | ||||
|     } | ||||
|     MOS->Relocations.push_back(MR); | ||||
| @@ -334,8 +337,6 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) { | ||||
|   if (Align == 0) | ||||
|     Align = TM.getTargetData()->getPrefTypeAlignment(Ty); | ||||
|    | ||||
|   MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM); | ||||
|    | ||||
|   // Reserve space in the .bss section for this symbol while maintaining the | ||||
|   // desired section alignment, which must be at least as much as required by | ||||
|   // this symbol. | ||||
| @@ -353,11 +354,16 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) { | ||||
|     for (unsigned i = 0; i < AlignedSize; ++i) | ||||
|       SecDataOut.outbyte(0); | ||||
|   } | ||||
|   // Globals without external linkage apparently do not go in the symbol table. | ||||
|   if (GV->getLinkage() != GlobalValue::InternalLinkage) { | ||||
|     MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM); | ||||
|     Sym.n_value = Sec->size; | ||||
|     SymbolTable.push_back(Sym); | ||||
|   } | ||||
|  | ||||
|   // Record the offset of the symbol, and then allocate space for it. | ||||
|   // FIXME: remove when we have unified size + output buffer | ||||
|   Sym.n_value = Sec->size; | ||||
|   Sec->size += Size; | ||||
|   SymbolTable.push_back(Sym); | ||||
|    | ||||
|   // Now that we know what section the GlovalVariable is going to be emitted  | ||||
|   // into, update our mappings. | ||||
| @@ -387,12 +393,9 @@ void MachOWriter::EmitGlobal(GlobalVariable *GV) { | ||||
|       // For undefined (N_UNDF) external (N_EXT) types, n_value is the size in | ||||
|       // bytes of the symbol. | ||||
|       ExtOrCommonSym.n_value = Size; | ||||
|       // If the symbol is external, we'll put it on a list of symbols whose | ||||
|       // addition to the symbol table is being pended until we find a reference | ||||
|       if (NoInit) | ||||
|         PendingSyms.push_back(ExtOrCommonSym); | ||||
|       else | ||||
|       SymbolTable.push_back(ExtOrCommonSym); | ||||
|       // Remember that we've seen this symbol | ||||
|       GVOffset[GV] = Size; | ||||
|       return; | ||||
|     } | ||||
|     // Otherwise, this symbol is part of the .bss section. | ||||
| @@ -526,7 +529,13 @@ void MachOWriter::EmitHeaderAndLoadCommands() { | ||||
|     currentAddr += MOS->size; | ||||
|   } | ||||
|    | ||||
|   // Step #6: Calculate the number of relocations for each section and write out | ||||
|   // Step #6: Emit the symbol table to temporary buffers, so that we know the | ||||
|   // size of the string table when we write the next load command.  This also | ||||
|   // sorts and assigns indices to each of the symbols, which is necessary for | ||||
|   // emitting relocations to externally-defined objects. | ||||
|   BufferSymbolAndStringTable(); | ||||
|    | ||||
|   // Step #7: Calculate the number of relocations for each section and write out | ||||
|   // the section commands for each section | ||||
|   currentAddr += SEG.fileoff; | ||||
|   for (std::vector<MachOSection*>::iterator I = SectionList.begin(), | ||||
| @@ -554,10 +563,6 @@ void MachOWriter::EmitHeaderAndLoadCommands() { | ||||
|       FHOut.outword(MOS->reserved3); | ||||
|   } | ||||
|    | ||||
|   // Step #7: Emit the symbol table to temporary buffers, so that we know the | ||||
|   // size of the string table when we write the next load command. | ||||
|   BufferSymbolAndStringTable(); | ||||
|    | ||||
|   // Step #8: Emit LC_SYMTAB/LC_DYSYMTAB load commands | ||||
|   SymTab.symoff  = currentAddr; | ||||
|   SymTab.nsyms   = SymbolTable.size(); | ||||
| @@ -632,6 +637,17 @@ void MachOWriter::BufferSymbolAndStringTable() { | ||||
|   // 2. defined external symbols (sorted by name) | ||||
|   // 3. undefined external symbols (sorted by name) | ||||
|    | ||||
|   // Before sorting the symbols, check the PendingGlobals for any undefined | ||||
|   // globals that need to be put in the symbol table. | ||||
|   for (std::vector<GlobalValue*>::iterator I = PendingGlobals.begin(), | ||||
|          E = PendingGlobals.end(); I != E; ++I) { | ||||
|     if (GVOffset[*I] == 0 && GVSection[*I] == 0) { | ||||
|       MachOSym UndfSym(*I, Mang->getValueName(*I), MachOSym::NO_SECT, TM); | ||||
|       SymbolTable.push_back(UndfSym); | ||||
|       GVOffset[*I] = -1; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   // Sort the symbols by name, so that when we partition the symbols by scope | ||||
|   // of definition, we won't have to sort by name within each partition. | ||||
|   std::sort(SymbolTable.begin(), SymbolTable.end(), MachOSymCmp()); | ||||
| @@ -690,14 +706,17 @@ void MachOWriter::BufferSymbolAndStringTable() { | ||||
|  | ||||
|   OutputBuffer SymTOut(SymT, is64Bit, isLittleEndian); | ||||
|  | ||||
|   unsigned index = 0; | ||||
|   for (std::vector<MachOSym>::iterator I = SymbolTable.begin(), | ||||
|          E = SymbolTable.end(); I != E; ++I) { | ||||
|          E = SymbolTable.end(); I != E; ++I, ++index) { | ||||
|     // Add the section base address to the section offset in the n_value field | ||||
|     // to calculate the full address. | ||||
|     // FIXME: handle symbols where the n_value field is not the address | ||||
|     GlobalValue *GV = const_cast<GlobalValue*>(I->GV); | ||||
|     if (GV && GVSection[GV]) | ||||
|       I->n_value += GVSection[GV]->addr; | ||||
|     if (GV && (GVOffset[GV] == -1)) | ||||
|       GVOffset[GV] = index; | ||||
|           | ||||
|     // Emit nlist to buffer | ||||
|     SymTOut.outword(I->n_strx); | ||||
| @@ -717,10 +736,13 @@ 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(); | ||||
|     unsigned TargetAddr; | ||||
|     unsigned TargetIndex; | ||||
|  | ||||
|     // This is a scattered relocation entry if it points to a global value with | ||||
|     // a non-zero offset. | ||||
|     bool Scattered = false; | ||||
|     bool Extern = 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 | ||||
| @@ -729,24 +751,29 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) { | ||||
|       GlobalValue *GV = MR.getGlobalValue(); | ||||
|       MachOSection *MOSPtr = GVSection[GV]; | ||||
|       intptr_t Offset = GVOffset[GV]; | ||||
|       Scattered = TargetSection != 0; | ||||
|        | ||||
|       // If we have never seen the global before, it must be to a symbol | ||||
|       // defined in another module (N_UNDF). | ||||
|       if (!MOSPtr) { | ||||
|         cerr << "Trying to relocate unknown global " << *GV << '\n'; | ||||
|         continue; | ||||
|         //abort(); | ||||
|       } | ||||
|        | ||||
|         // FIXME: need to append stub suffix | ||||
|         Extern = true; | ||||
|         TargetAddr = 0; | ||||
|         TargetIndex = GVOffset[GV]; | ||||
|       } else { | ||||
|         Scattered = TargetSection != 0; | ||||
|         TargetSection = MOSPtr->Index; | ||||
|         MachOSection &To = *SectionList[TargetSection - 1]; | ||||
|         TargetAddr = To.addr; | ||||
|         TargetIndex = To.Index; | ||||
|       } | ||||
|       MR.setResultPointer((void*)Offset); | ||||
|     } | ||||
|  | ||||
|     OutputBuffer RelocOut(MOS.RelocBuffer, is64Bit, isLittleEndian); | ||||
|     OutputBuffer SecOut(MOS.SectionData, is64Bit, isLittleEndian); | ||||
|     MachOSection &To = *SectionList[TargetSection - 1]; | ||||
|      | ||||
|     MOS.nreloc += GetTargetRelocation(MR, MOS.Index, To.addr, To.Index, | ||||
|                                       RelocOut, SecOut, Scattered); | ||||
|     MOS.nreloc += GetTargetRelocation(MR, MOS.Index, TargetAddr, TargetIndex, | ||||
|                                       RelocOut, SecOut, Scattered, Extern); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -583,7 +583,7 @@ namespace llvm { | ||||
|     /// PendingSyms - This is a list of externally defined symbols that we have | ||||
|     /// been asked to emit, but have not seen a reference to.  When a reference | ||||
|     /// is seen, the symbol will move from this list to the SymbolTable. | ||||
|     std::vector<MachOSym> PendingSyms; | ||||
|     std::vector<GlobalValue*> PendingGlobals; | ||||
|      | ||||
|     /// DynamicSymbolTable - This is just a vector of indices into | ||||
|     /// SymbolTable to aid in emitting the DYSYMTAB load command. | ||||
| @@ -613,10 +613,12 @@ namespace llvm { | ||||
|                                  unsigned ToIndex, | ||||
|                                  OutputBuffer &RelocOut, | ||||
|                                  OutputBuffer &SecOut, | ||||
|                                  bool Scattered) { | ||||
|                                  bool Scattered, | ||||
|                                  bool Extern) { | ||||
|       return TM.getMachOWriterInfo()->GetTargetRelocation(MR, FromIdx, ToAddr, | ||||
|                                                           ToIndex, RelocOut, | ||||
|                                                           SecOut, Scattered); | ||||
|                                                           SecOut, Scattered, | ||||
|                                                           Extern); | ||||
|     } | ||||
|   }; | ||||
| } | ||||
|   | ||||
| @@ -35,13 +35,11 @@ unsigned PPCMachOWriterInfo::GetTargetRelocation(MachineRelocation &MR, | ||||
|                                                  unsigned ToIdx, | ||||
|                                                  OutputBuffer &RelocOut, | ||||
|                                                  OutputBuffer &SecOut, | ||||
|                                                  bool Scattered) const { | ||||
|                                                  bool Scattered, | ||||
|                                                  bool isExtern) const { | ||||
|   unsigned NumRelocs = 0; | ||||
|   uint64_t Addr = 0; | ||||
|  | ||||
|   // Keep track of whether or not this is an externally defined relocation. | ||||
|   bool     isExtern = false; | ||||
|  | ||||
|   // Get the address of whatever it is we're relocating, if possible. | ||||
|   if (!isExtern) | ||||
|     Addr = (uintptr_t)MR.getResultPointer() + ToAddr; | ||||
| @@ -83,12 +81,24 @@ unsigned PPCMachOWriterInfo::GetTargetRelocation(MachineRelocation &MR, | ||||
|     break; | ||||
|   case PPC::reloc_pcrel_bx: | ||||
|     { | ||||
|       // FIXME: Presumably someday we will need to branch to other, non-extern | ||||
|       // functions too.  Need to figure out some way to distinguish between | ||||
|       // target is BB and target is function. | ||||
|       if (isExtern) { | ||||
|         MachORelocation BR24(MR.getMachineCodeOffset(), ToIdx, true, 2,  | ||||
|                              isExtern, PPC_RELOC_BR24, Scattered,  | ||||
|                              (intptr_t)MR.getMachineCodeOffset()); | ||||
|         RelocOut.outword(BR24.getAddress()); | ||||
|         RelocOut.outword(BR24.getPackedFields()); | ||||
|         ++NumRelocs; | ||||
|       } | ||||
|  | ||||
|       Addr -= MR.getMachineCodeOffset(); | ||||
|       Addr >>= 2; | ||||
|       Addr &= 0xFFFFFF; | ||||
|       Addr <<= 2; | ||||
|       Addr |= (SecOut[MR.getMachineCodeOffset()] << 24); | ||||
|  | ||||
|       Addr |= (SecOut[MR.getMachineCodeOffset()+3] & 0x3); | ||||
|       SecOut.fixword(Addr, MR.getMachineCodeOffset()); | ||||
|       break; | ||||
|     } | ||||
|   | ||||
| @@ -34,7 +34,7 @@ namespace llvm { | ||||
|                                          unsigned ToIdx, | ||||
|                                          OutputBuffer &RelocOut, | ||||
|                                          OutputBuffer &SecOut, | ||||
|                                          bool Scattered) const; | ||||
|                                          bool Scattered, bool Extern) const; | ||||
|  | ||||
|     // Constants for the relocation r_type field. | ||||
|     // See <mach-o/ppc/reloc.h> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user