Handle multiple functions, properly mangle symbols, and fix support for
authorNate Begeman <natebegeman@mac.com>
Fri, 26 Jan 2007 22:39:48 +0000 (22:39 +0000)
committerNate Begeman <natebegeman@mac.com>
Fri, 26 Jan 2007 22:39:48 +0000 (22:39 +0000)
scattered relocations.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33555 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachOWriter.h
lib/CodeGen/MachOWriter.cpp
lib/Target/PowerPC/PPCMachOWriter.cpp

index 5ec4f503318272dd034968340d1fca4a06f97014..0d13c909a94cd79664e20ec2858f38bff9cc25df 100644 (file)
@@ -307,16 +307,25 @@ namespace llvm {
       uint8_t  r_length;    // length = 2 ^ r_length
       bool     r_extern;    // 
       uint8_t  r_type;      // if not 0, machine-specific relocation type.
+      bool     r_scattered; // 1 = scattered, 0 = non-scattered
+      int32_t  r_value;     // the value the item to be relocated is referring
+                            // to.
       
-      uint32_t getPackedFields() { 
-        return (r_symbolnum << 8) | (r_pcrel << 7) | ((r_length & 3) << 5) |
-               (r_extern << 4) | (r_type & 15);
+      uint32_t getPackedFields() {
+        if (r_scattered)
+          return (1 << 31) | (r_pcrel << 30) | ((r_length & 3) << 28) | 
+                 ((r_type & 15) << 24) | (r_address & 0x00FFFFFF);
+        else
+          return (r_symbolnum << 8) | (r_pcrel << 7) | ((r_length & 3) << 5) |
+                 (r_extern << 4) | (r_type & 15);
       }
+      uint32_t getAddress() { return r_scattered ? r_value : r_address; }
       
       MachORelocation(uint32_t addr, uint32_t index, bool pcrel, uint8_t len,
-                      bool ext, uint8_t type) : r_address(addr),
-        r_symbolnum(index), r_pcrel(pcrel), r_length(len), r_extern(ext),
-        r_type(type) {}
+                      bool ext, uint8_t type, bool scattered = false, 
+                      int32_t value = 0) : 
+        r_address(addr), r_symbolnum(index), r_pcrel(pcrel), r_length(len),
+        r_extern(ext), r_type(type), r_scattered(scattered), r_value(value) {}
     };
 
     /// MachOSection - This struct contains information about each section in a 
@@ -621,7 +630,7 @@ namespace llvm {
       return TM.getMachOWriterInfo()->GetJTRelocation(Offset, MBB);
     }
     virtual void GetTargetRelocation(MachineRelocation &MR, MachOSection &From,
-                                     MachOSection &To) = 0;
+                                     MachOSection &To, bool Scattered) = 0;
   };
 }
 
index bc54728f58baacd8fde934c487c8ad6e3fdd3f03..63f1ad4da8f849835400d77e8bcfd2d1e5b105c5 100644 (file)
@@ -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;
   }
 }
index c3cc74e156a826b95a5f5854d24ced713f09a95b..9a1a608db10d3680188aa2b5782be868bfee45d7 100644 (file)
@@ -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);