llvm.org GIT mirror llvm / 6635f35
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 Nate Begeman 13 years ago
3 changed file(s) with 84 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
306306 uint8_t r_length; // length = 2 ^ r_length
307307 bool r_extern; //
308308 uint8_t r_type; // if not 0, machine-specific relocation type.
309
310 uint32_t getPackedFields() {
311 return (r_symbolnum << 8) | (r_pcrel << 7) | ((r_length & 3) << 5) |
312 (r_extern << 4) | (r_type & 15);
309 bool r_scattered; // 1 = scattered, 0 = non-scattered
310 int32_t r_value; // the value the item to be relocated is referring
311 // to.
312
313 uint32_t getPackedFields() {
314 if (r_scattered)
315 return (1 << 31) | (r_pcrel << 30) | ((r_length & 3) << 28) |
316 ((r_type & 15) << 24) | (r_address & 0x00FFFFFF);
317 else
318 return (r_symbolnum << 8) | (r_pcrel << 7) | ((r_length & 3) << 5) |
319 (r_extern << 4) | (r_type & 15);
313320 }
321 uint32_t getAddress() { return r_scattered ? r_value : r_address; }
314322
315323 MachORelocation(uint32_t addr, uint32_t index, bool pcrel, uint8_t len,
316 bool ext, uint8_t type) : r_address(addr),
317 r_symbolnum(index), r_pcrel(pcrel), r_length(len), r_extern(ext),
318 r_type(type) {}
324 bool ext, uint8_t type, bool scattered = false,
325 int32_t value = 0) :
326 r_address(addr), r_symbolnum(index), r_pcrel(pcrel), r_length(len),
327 r_extern(ext), r_type(type), r_scattered(scattered), r_value(value) {}
319328 };
320329
321330 /// MachOSection - This struct contains information about each section in a
620629 return TM.getMachOWriterInfo()->GetJTRelocation(Offset, MBB);
621630 }
622631 virtual void GetTargetRelocation(MachineRelocation &MR, MachOSection &From,
623 MachOSection &To) = 0;
632 MachOSection &To, bool Scattered) = 0;
624633 };
625634 }
626635
144144 BufferBegin = &MOS->SectionData[0];
145145 BufferEnd = BufferBegin + MOS->SectionData.capacity();
146146
147 // Upgrade the section alignment if required.
148 if (MOS->align < Align) MOS->align = Align;
149
150 // Round the size up to the correct alignment for starting the new function.
151 if ((MOS->size & ((1 << Align) - 1)) != 0) {
152 MOS->size += (1 << Align);
153 MOS->size &= ~((1 << Align) - 1);
154 }
155
147156 // FIXME: Using MOS->size directly here instead of calculating it from the
148157 // output buffer size (impossible because the code emitter deals only in raw
149158 // bytes) forces us to manually synchronize size and write padding zero bytes
153162 // AddSymbolToSection to prevent calling it on the text section.
154163 CurBufferPtr = BufferBegin + MOS->size;
155164
156 // Upgrade the section alignment if required.
157 if (MOS->align < Align) MOS->align = Align;
158
159165 // Clear per-function data structures.
160166 CPLocations.clear();
161167 CPSections.clear();
169175 // Get the Mach-O Section that this function belongs in.
170176 MachOWriter::MachOSection *MOS = MOW.getTextSection();
171177
172 MOS->size += CurBufferPtr - BufferBegin;
173
174178 // Get a symbol for the function to add to the symbol table
179 // FIXME: it seems like we should call something like AddSymbolToSection
180 // in startFunction rather than changing the section size and symbol n_value
181 // here.
175182 const GlobalValue *FuncV = F.getFunction();
176183 MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TM);
177
184 FnSym.n_value = MOS->size;
185 MOS->size = CurBufferPtr - BufferBegin;
186
178187 // Emit constant pool to appropriate section(s)
179188 emitConstantPool(F.getConstantPool());
180189
634643 if (PartitionByLocal(*I)) {
635644 ++DySymTab.nlocalsym;
636645 ++DySymTab.iextdefsym;
646 ++DySymTab.iundefsym;
637647 } else if (PartitionByDefined(*I)) {
638648 ++DySymTab.nextdefsym;
639649 ++DySymTab.iundefsym;
691701 for (unsigned i = 0, e = MOS.Relocations.size(); i != e; ++i) {
692702 MachineRelocation &MR = MOS.Relocations[i];
693703 unsigned TargetSection = MR.getConstantVal();
704
705 // This is a scattered relocation entry if it points to a global value with
706 // a non-zero offset.
707 bool Scattered = false;
694708
695709 // Since we may not have seen the GlobalValue we were interested in yet at
696710 // the time we emitted the relocation for it, fix it up now so that it
698712 if (MR.isGlobalValue()) {
699713 GlobalValue *GV = MR.getGlobalValue();
700714 MachOSection *MOSPtr = GVSection[GV];
701 intptr_t offset = GVOffset[GV];
715 intptr_t Offset = GVOffset[GV];
716 Scattered = TargetSection != 0;
702717
703718 assert(MOSPtr && "Trying to relocate unknown global!");
704719
705720 TargetSection = MOSPtr->Index;
706 MR.setResultPointer((void*)offset);
707 }
708
709 GetTargetRelocation(MR, MOS, *SectionList[TargetSection-1]);
721 MR.setResultPointer((void*)Offset);
722 }
723
724 GetTargetRelocation(MR, MOS, *SectionList[TargetSection-1], Scattered);
710725 }
711726 }
712727
719734 std::vector WorkList;
720735
721736 WorkList.push_back(CPair(C,(intptr_t)Addr + Offset));
737
738 intptr_t ScatteredOffset = 0;
722739
723740 while (!WorkList.empty()) {
724741 const Constant *PC = WorkList.back().first;
736753 // FIXME: Handle ConstantExpression. See EE::getConstantValue()
737754 //
738755 switch (CE->getOpcode()) {
739 case Instruction::GetElementPtr:
756 case Instruction::GetElementPtr: {
757 std::vector Indexes(CE->op_begin()+1, CE->op_end());
758 ScatteredOffset = TD->getIndexedOffset(CE->getOperand(0)->getType(),
759 Indexes);
760 WorkList.push_back(CPair(CE->getOperand(0), PA));
761 break;
762 }
740763 case Instruction::Add:
741764 default:
742765 cerr << "ConstantExpr not handled as global var init: " << *CE << "\n";
804827 break;
805828 }
806829 case Type::PointerTyID:
807 if (isa(C))
830 if (isa(PC))
808831 memset(ptr, 0, TD->getPointerSize());
809 else if (const GlobalValue* GV = dyn_cast(C))
832 else if (const GlobalValue* GV = dyn_cast(PC)) {
810833 // FIXME: what about function stubs?
811834 MRs.push_back(MachineRelocation::getGV(PA-(intptr_t)Addr,
812835 MachineRelocation::VANILLA,
813 const_cast(GV)));
814 else
836 const_cast(GV),
837 ScatteredOffset));
838 ScatteredOffset = 0;
839 } else
815840 assert(0 && "Unknown constant pointer type!");
816841 break;
817842 default:
852877 assert(!isa(gv) && "Unexpected linkage type for Function!");
853878 case GlobalValue::ExternalLinkage:
854879 GVName = TAI->getGlobalPrefix() + name;
855 n_type |= N_EXT;
880 n_type |= GV->hasHiddenVisibility() ? N_PEXT : N_EXT;
856881 break;
857882 case GlobalValue::InternalLinkage:
858 GVName = TAI->getPrivateGlobalPrefix() + name;
883 GVName = TAI->getGlobalPrefix() + name;
859884 break;
860885 }
861886 }
2626 : MachOWriter(O, TM) {}
2727
2828 virtual void GetTargetRelocation(MachineRelocation &MR, MachOSection &From,
29 MachOSection &To);
29 MachOSection &To, bool Scattered);
3030
3131 // Constants for the relocation r_type field.
3232 // see
5858 /// by that relocation type.
5959 void PPCMachOWriter::GetTargetRelocation(MachineRelocation &MR,
6060 MachOSection &From,
61 MachOSection &To) {
61 MachOSection &To,
62 bool Scattered) {
6263 uint64_t Addr = 0;
6364
6465 // Keep track of whether or not this is an externally defined relocation.
7677 case PPC::reloc_vanilla:
7778 {
7879 // FIXME: need to handle 64 bit vanilla relocs
79 MachORelocation VANILLA(MR.getMachineCodeOffset(), To.Index, false, 2,
80 isExtern, PPC_RELOC_VANILLA);
80 MachORelocation VANILLA(MR.getMachineCodeOffset(), To.Index, false, 2,
81 isExtern, PPC_RELOC_VANILLA, Scattered,
82 (intptr_t)MR.getResultPointer());
8183 ++From.nreloc;
84 OutputBuffer RelocOut(From.RelocBuffer, is64Bit, isLittleEndian);
85 OutputBuffer SecOut(From.SectionData, is64Bit, isLittleEndian);
8286
83 OutputBuffer RelocOut(From.RelocBuffer, is64Bit, isLittleEndian);
84 RelocOut.outword(VANILLA.r_address);
85 RelocOut.outword(VANILLA.getPackedFields());
86
87 OutputBuffer SecOut(From.SectionData, is64Bit, isLittleEndian);
88 SecOut.fixword(Addr, MR.getMachineCodeOffset());
89 break;
87 if (Scattered) {
88 RelocOut.outword(VANILLA.getPackedFields());
89 RelocOut.outword(VANILLA.getAddress());
90 } else {
91 RelocOut.outword(VANILLA.getAddress());
92 RelocOut.outword(VANILLA.getPackedFields());
93 }
94
95 intptr_t SymbolOffset;
96 if (Scattered)
97 SymbolOffset = Addr + MR.getConstantVal();
98 else
99 SymbolOffset = Addr;
100 printf("vanilla fixup: sec_%x[%x] = %x\n", From.Index, unsigned(MR.getMachineCodeOffset()), (unsigned)SymbolOffset);
101 SecOut.fixword(SymbolOffset, MR.getMachineCodeOffset());
90102 }
103 break;
91104 case PPC::reloc_pcrel_bx:
92105 {
93106 Addr -= MR.getMachineCodeOffset();
123136 RelocOut.outword(HA16.getPackedFields());
124137 RelocOut.outword(PAIR.r_address);
125138 RelocOut.outword(PAIR.getPackedFields());
126 printf("ha16: %x\n", (unsigned)Addr);
127139 Addr += 0x8000;
128140
129141 OutputBuffer SecOut(From.SectionData, is64Bit, isLittleEndian);
144156 RelocOut.outword(LO16.getPackedFields());
145157 RelocOut.outword(PAIR.r_address);
146158 RelocOut.outword(PAIR.getPackedFields());
147 printf("lo16: %x\n", (unsigned)Addr);
148159
149160 OutputBuffer SecOut(From.SectionData, is64Bit, isLittleEndian);
150161 SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2);