llvm.org GIT mirror llvm / 4b0b8ef
Re-factored RuntimeDyld. Added ExecutionEngine/MCJIT tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153694 91177308-0d34-0410-b5e6-96231b3b80d8 Danil Malyshev 7 years ago
57 changed file(s) with 1845 addition(s) and 1090 deletion(s). Raw diff Collapse all Expand all
4444 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
4545 unsigned SectionID) = 0;
4646
47 // Allocate ActualSize bytes, or more, for the named function. Return
48 // a pointer to the allocated memory and update Size to reflect how much
49 // memory was acutally allocated.
50 virtual uint8_t *startFunctionBody(const char *Name, uintptr_t &Size) = 0;
51
52 // Mark the end of the function, including how much of the allocated
53 // memory was actually used.
54 virtual void endFunctionBody(const char *Name, uint8_t *FunctionStart,
55 uint8_t *FunctionEnd) = 0;
56
57
5847 virtual void *getPointerToNamedFunction(const std::string &Name,
5948 bool AbortOnFailure = true) = 0;
6049 };
3333
3434 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
3535 unsigned SectionID) {
36 return JMM->allocateDataSection(Size, Alignment, SectionID);
36 return JMM->allocateSpace(Size, Alignment);
3737 }
3838
3939 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
4040 unsigned SectionID) {
41 return JMM->allocateCodeSection(Size, Alignment, SectionID);
41 return JMM->allocateSpace(Size, Alignment);
4242 }
4343
4444 virtual void *getPointerToNamedFunction(const std::string &Name,
4646 return JMM->getPointerToNamedFunction(Name, AbortOnFailure);
4747 }
4848
49 // Allocate ActualSize bytes, or more, for the named function. Return
50 // a pointer to the allocated memory and update Size to reflect how much
51 // memory was acutally allocated.
52 uint8_t *startFunctionBody(const char *Name, uintptr_t &Size) {
53 // FIXME: This should really reference the MCAsmInfo to get the global
54 // prefix.
55 if (Name[0] == '_') ++Name;
56 Function *F = M->getFunction(Name);
57 // Some ObjC names have a prefixed \01 in the IR. If we failed to find
58 // the symbol and it's of the ObjC conventions (starts with "-" or
59 // "+"), try prepending a \01 and see if we can find it that way.
60 if (!F && (Name[0] == '-' || Name[0] == '+'))
61 F = M->getFunction((Twine("\1") + Name).str());
62 assert(F && "No matching function in JIT IR Module!");
63 return JMM->startFunctionBody(F, Size);
64 }
65
66 // Mark the end of the function, including how much of the allocated
67 // memory was actually used.
68 void endFunctionBody(const char *Name, uint8_t *FunctionStart,
69 uint8_t *FunctionEnd) {
70 // FIXME: This should really reference the MCAsmInfo to get the global
71 // prefix.
72 if (Name[0] == '_') ++Name;
73 Function *F = M->getFunction(Name);
74 // Some ObjC names have a prefixed \01 in the IR. If we failed to find
75 // the symbol and it's of the ObjC conventions (starts with "-" or
76 // "+"), try prepending a \01 and see if we can find it that way.
77 if (!F && (Name[0] == '-' || Name[0] == '+'))
78 F = M->getFunction((Twine("\1") + Name).str());
79 assert(F && "No matching function in JIT IR Module!");
80 JMM->endFunctionBody(F, FunctionStart, FunctionEnd);
81 }
82
8349 };
8450
8551 } // End llvm namespace
2525
2626 namespace llvm {
2727
28 void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress,
29 uint8_t *EndAddress) {
30 // FIXME: DEPRECATED in favor of by-section allocation.
31 // Allocate memory for the function via the memory manager.
32 uintptr_t Size = EndAddress - StartAddress + 1;
33 uintptr_t AllocSize = Size;
34 uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize);
35 assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) &&
36 "Memory manager failed to allocate enough memory!");
37 // Copy the function payload into the memory block.
38 memcpy(Mem, StartAddress, Size);
39 MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size);
40 // Remember where we put it.
41 unsigned SectionID = Sections.size();
42 Sections.push_back(sys::MemoryBlock(Mem, Size));
43
44 // Default the assigned address for this symbol to wherever this
45 // allocated it.
46 SymbolTable[Name] = SymbolLoc(SectionID, 0);
47 DEBUG(dbgs() << " allocated to [" << Mem << ", " << Mem + Size << "]\n");
48 }
28 namespace {
29 // Helper for extensive error checking in debug builds.
30 error_code Check(error_code Err) {
31 if (Err) {
32 report_fatal_error(Err.message());
33 }
34 return Err;
35 }
36 } // end anonymous namespace
37
4938
5039 // Resolve the relocations for all symbols we currently know about.
5140 void RuntimeDyldImpl::resolveRelocations() {
41 // First, resolve relocations assotiated with external symbols.
42 resolveSymbols();
43
5244 // Just iterate over the sections we have and resolve all the relocations
5345 // in them. Gross overkill, but it gets the job done.
5446 for (int i = 0, e = Sections.size(); i != e; ++i) {
55 reassignSectionAddress(i, SectionLoadAddress[i]);
47 reassignSectionAddress(i, Sections[i].LoadAddress);
5648 }
5749 }
5850
5951 void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress,
6052 uint64_t TargetAddress) {
61 assert(SectionLocalMemToID.count(LocalAddress) &&
62 "Attempting to remap address of unknown section!");
63 unsigned SectionID = SectionLocalMemToID[LocalAddress];
64 reassignSectionAddress(SectionID, TargetAddress);
65 }
53 for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
54 if (Sections[i].Address == LocalAddress) {
55 reassignSectionAddress(i, TargetAddress);
56 return;
57 }
58 }
59 llvm_unreachable("Attempting to remap address of unknown section!");
60 }
61
62 bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
63 // FIXME: ObjectFile don't modify MemoryBuffer.
64 // It should use const MemoryBuffer as parameter.
65 ObjectFile *obj
66 = ObjectFile::createObjectFile(const_cast(InputBuffer));
67
68 Arch = (Triple::ArchType)obj->getArch();
69
70 LocalSymbolMap LocalSymbols; // Functions and data symbols from the
71 // object file.
72 ObjSectionToIDMap LocalSections; // Used sections from the object file
73
74 error_code err;
75 // Parse symbols
76 DEBUG(dbgs() << "Parse symbols:\n");
77 for (symbol_iterator i = obj->begin_symbols(), e = obj->end_symbols();
78 i != e; i.increment(err)) {
79 Check(err);
80 object::SymbolRef::Type SymType;
81 StringRef Name;
82 Check(i->getType(SymType));
83 Check(i->getName(Name));
84
85 if (SymType == object::SymbolRef::ST_Function ||
86 SymType == object::SymbolRef::ST_Data) {
87 uint64_t FileOffset;
88 uint32_t flags;
89 StringRef sData;
90 section_iterator si = obj->end_sections();
91 Check(i->getFileOffset(FileOffset));
92 Check(i->getFlags(flags));
93 Check(i->getSection(si));
94 if (si == obj->end_sections()) continue;
95 Check(si->getContents(sData));
96 const uint8_t* SymPtr = (const uint8_t*)InputBuffer->getBufferStart() +
97 (uintptr_t)FileOffset;
98 uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)sData.begin());
99 unsigned SectionID
100 = findOrEmitSection(*si,
101 SymType == object::SymbolRef::ST_Function,
102 LocalSections);
103 bool isGlobal = flags & SymbolRef::SF_Global;
104 LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset);
105 DEBUG(dbgs() << "\tFileOffset: " << format("%p", (uintptr_t)FileOffset)
106 << " flags: " << flags
107 << " SID: " << SectionID
108 << " Offset: " << format("%p", SectOffset));
109 if (isGlobal)
110 SymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
111 }
112 DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n");
113 }
114
115 // Parse and proccess relocations
116 DEBUG(dbgs() << "Parse relocations:\n");
117 for (section_iterator si = obj->begin_sections(),
118 se = obj->end_sections(); si != se; si.increment(err)) {
119 Check(err);
120 bool isFirstRelocation = true;
121 unsigned SectionID = 0;
122 StubMap Stubs;
123
124 for (relocation_iterator i = si->begin_relocations(),
125 e = si->end_relocations(); i != e; i.increment(err)) {
126 Check(err);
127
128 // If it's first relocation in this section, find its SectionID
129 if (isFirstRelocation) {
130 SectionID = findOrEmitSection(*si, true, LocalSections);
131 DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
132 isFirstRelocation = false;
133 }
134
135 ObjRelocationInfo RI;
136 RI.SectionID = SectionID;
137 Check(i->getAdditionalInfo(RI.AdditionalInfo));
138 Check(i->getOffset(RI.Offset));
139 Check(i->getSymbol(RI.Symbol));
140 Check(i->getType(RI.Type));
141
142 DEBUG(dbgs() << "\t\tAddend: " << RI.AdditionalInfo
143 << " Offset: " << format("%p", (uintptr_t)RI.Offset)
144 << " Type: " << (uint32_t)(RI.Type & 0xffffffffL)
145 << "\n");
146 processRelocationRef(RI, *obj, LocalSections, LocalSymbols, Stubs);
147 }
148 }
149 return false;
150 }
151
152 unsigned RuntimeDyldImpl::emitSection(const SectionRef &Section,
153 bool IsCode) {
154
155 unsigned StubBufSize = 0,
156 StubSize = getMaxStubSize();
157 error_code err;
158 if (StubSize > 0) {
159 for (relocation_iterator i = Section.begin_relocations(),
160 e = Section.end_relocations(); i != e; i.increment(err))
161 StubBufSize += StubSize;
162 }
163 StringRef data;
164 uint64_t Alignment64;
165 Check(Section.getContents(data));
166 Check(Section.getAlignment(Alignment64));
167
168 unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
169 unsigned DataSize = data.size();
170 unsigned Allocate = DataSize + StubBufSize;
171 unsigned SectionID = Sections.size();
172 const char *pData = data.data();
173 uint8_t *Addr = IsCode
174 ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID)
175 : MemMgr->allocateDataSection(Allocate, Alignment, SectionID);
176
177 memcpy(Addr, pData, DataSize);
178 DEBUG(dbgs() << "emitSection SectionID: " << SectionID
179 << " obj addr: " << format("%p", pData)
180 << " new addr: " << format("%p", Addr)
181 << " DataSize: " << DataSize
182 << " StubBufSize: " << StubBufSize
183 << " Allocate: " << Allocate
184 << "\n");
185 Sections.push_back(SectionEntry(Addr, Allocate, DataSize,(uintptr_t)pData));
186 return SectionID;
187 }
188
189 unsigned RuntimeDyldImpl::findOrEmitSection(const SectionRef &Section,
190 bool IsCode,
191 ObjSectionToIDMap &LocalSections) {
192
193 unsigned SectionID = 0;
194 ObjSectionToIDMap::iterator i = LocalSections.find(Section);
195 if (i != LocalSections.end())
196 SectionID = i->second;
197 else {
198 SectionID = emitSection(Section, IsCode);
199 LocalSections[Section] = SectionID;
200 }
201 return SectionID;
202 }
203
204 void RuntimeDyldImpl::AddRelocation(const RelocationValueRef &Value,
205 unsigned SectionID, uintptr_t Offset,
206 uint32_t RelType) {
207 DEBUG(dbgs() << "AddRelocation SymNamePtr: " << format("%p", Value.SymbolName)
208 << " SID: " << Value.SectionID
209 << " Addend: " << format("%p", Value.Addend)
210 << " Offset: " << format("%p", Offset)
211 << " RelType: " << format("%x", RelType)
212 << "\n");
213
214 if (Value.SymbolName == 0) {
215 Relocations[Value.SectionID].push_back(RelocationEntry(
216 SectionID,
217 Offset,
218 RelType,
219 Value.Addend));
220 } else
221 SymbolRelocations[Value.SymbolName].push_back(RelocationEntry(
222 SectionID,
223 Offset,
224 RelType,
225 Value.Addend));
226 }
227
228 uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
229 // TODO: There is only ARM far stub now. We should add the Thumb stub,
230 // and stubs for branches Thumb - ARM and ARM - Thumb.
231 if (Arch == Triple::arm) {
232 uint32_t *StubAddr = (uint32_t*)Addr;
233 *StubAddr = 0xe51ff004; // ldr pc,
234 return (uint8_t*)++StubAddr;
235 }
236 else
237 return Addr;
238 }
239
240 // Assign an address to a symbol name and resolve all the relocations
241 // associated with it.
242 void RuntimeDyldImpl::reassignSectionAddress(unsigned SectionID,
243 uint64_t Addr) {
244 // The address to use for relocation resolution is not
245 // the address of the local section buffer. We must be doing
246 // a remote execution environment of some sort. Re-apply any
247 // relocations referencing this section with the given address.
248 //
249 // Addr is a uint64_t because we can't assume the pointer width
250 // of the target is the same as that of the host. Just use a generic
251 // "big enough" type.
252 Sections[SectionID].LoadAddress = Addr;
253 DEBUG(dbgs() << "Resolving relocations Section #" << SectionID
254 << "\t" << format("%p", (uint8_t *)Addr)
255 << "\n");
256 resolveRelocationList(Relocations[SectionID], Addr);
257 }
258
259 void RuntimeDyldImpl::resolveRelocationEntry(const RelocationEntry &RE,
260 uint64_t Value) {
261 uint8_t *Target = Sections[RE.SectionID].Address + RE.Offset;
262 DEBUG(dbgs() << "\tSectionID: " << RE.SectionID
263 << " + " << RE.Offset << " (" << format("%p", Target) << ")"
264 << " Data: " << RE.Data
265 << " Addend: " << RE.Addend
266 << "\n");
267
268 resolveRelocation(Target, Sections[RE.SectionID].LoadAddress + RE.Offset,
269 Value, RE.Data, RE.Addend);
270 }
271
272 void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
273 uint64_t Value) {
274 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
275 resolveRelocationEntry(Relocs[i], Value);
276 }
277 }
278
279 // resolveSymbols - Resolve any relocations to the specified symbols if
280 // we know where it lives.
281 void RuntimeDyldImpl::resolveSymbols() {
282 StringMap::iterator i = SymbolRelocations.begin(),
283 e = SymbolRelocations.end();
284 for (; i != e; i++) {
285 StringRef Name = i->first();
286 RelocationList &Relocs = i->second;
287 StringMap::const_iterator Loc = SymbolTable.find(Name);
288 if (Loc == SymbolTable.end()) {
289 // This is an external symbol, try to get it address from
290 // MemoryManager.
291 uint8_t *Addr = (uint8_t*) MemMgr->getPointerToNamedFunction(Name.data(),
292 true);
293 DEBUG(dbgs() << "Resolving relocations Name: " << Name
294 << "\t" << format("%p", Addr)
295 << "\n");
296 resolveRelocationList(Relocs, (uintptr_t)Addr);
297 } else {
298 // Change the relocation to be section relative rather than symbol
299 // relative and move it to the resolved relocation list.
300 DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n");
301 for (int i = 0, e = Relocs.size(); i != e; ++i) {
302 RelocationEntry Entry = Relocs[i];
303 Entry.Addend += Loc->second.second;
304 Relocations[Loc->second.first].push_back(Entry);
305 }
306 Relocs.clear();
307 }
308 }
309 }
310
66311
67312 //===----------------------------------------------------------------------===//
68313 // RuntimeDyld class implementation
2424
2525 namespace llvm {
2626
27 namespace {
28
29 // FIXME: this function should probably not live here...
30 //
31 // Returns the name and address of an unrelocated symbol in an ELF section
32 void getSymbolInfo(symbol_iterator Sym, uint64_t &Addr, StringRef &Name) {
33 //FIXME: error checking here required to catch corrupt ELF objects...
34 error_code Err = Sym->getName(Name);
35
36 uint64_t AddrInSection;
37 Err = Sym->getAddress(AddrInSection);
38
39 SectionRef empty_section;
40 section_iterator Section(empty_section);
41 Err = Sym->getSection(Section);
42
43 StringRef SectionContents;
44 Section->getContents(SectionContents);
45
46 Addr = reinterpret_cast(SectionContents.data()) + AddrInSection;
47 }
48
49 }
50
51 bool RuntimeDyldELF::loadObject(MemoryBuffer *InputBuffer) {
52 if (!isCompatibleFormat(InputBuffer))
53 return true;
54
55 OwningPtr Obj(ObjectFile::createELFObjectFile(InputBuffer));
56
57 Arch = Obj->getArch();
58
59 // Map address in the Object file image to function names
60 IntervalMap::Allocator A;
61 IntervalMap FuncMap(A);
62
63 // This is a bit of a hack. The ObjectFile we've just loaded reports
64 // section addresses as 0 and doesn't provide access to the section
65 // offset (from which we could calculate the address. Instead,
66 // we're storing the address when it comes up in the ST_Debug case
67 // below.
68 //
69 StringMap DebugSymbolMap;
70
71 symbol_iterator SymEnd = Obj->end_symbols();
72 error_code Err;
73 for (symbol_iterator Sym = Obj->begin_symbols();
74 Sym != SymEnd; Sym.increment(Err)) {
75 SymbolRef::Type Type;
76 Sym->getType(Type);
77 if (Type == SymbolRef::ST_Function) {
78 StringRef Name;
79 uint64_t Addr;
80 getSymbolInfo(Sym, Addr, Name);
81
82 uint64_t Size;
83 Err = Sym->getSize(Size);
84
85 uint8_t *Start;
86 uint8_t *End;
87 Start = reinterpret_cast(Addr);
88 End = reinterpret_cast(Addr + Size - 1);
89
90 extractFunction(Name, Start, End);
91 FuncMap.insert(Addr, Addr + Size - 1, Name);
92 } else if (Type == SymbolRef::ST_Debug) {
93 // This case helps us find section addresses
94 StringRef Name;
95 uint64_t Addr;
96 getSymbolInfo(Sym, Addr, Name);
97 DebugSymbolMap[Name] = Addr;
98 }
99 }
100
101 // Iterate through the relocations for this object
102 section_iterator SecEnd = Obj->end_sections();
103 for (section_iterator Sec = Obj->begin_sections();
104 Sec != SecEnd; Sec.increment(Err)) {
105 StringRef SecName;
106 uint64_t SecAddr;
107 Sec->getName(SecName);
108 // Ignore sections that aren't in our map
109 if (DebugSymbolMap.find(SecName) == DebugSymbolMap.end()) {
110 continue;
111 }
112 SecAddr = DebugSymbolMap[SecName];
113 relocation_iterator RelEnd = Sec->end_relocations();
114 for (relocation_iterator Rel = Sec->begin_relocations();
115 Rel != RelEnd; Rel.increment(Err)) {
116 uint64_t RelOffset;
117 uint64_t RelType;
118 int64_t RelAddend;
119 SymbolRef RelSym;
120 StringRef SymName;
121 uint64_t SymAddr;
122 uint64_t SymOffset;
123
124 Rel->getAddress(RelOffset);
125 Rel->getType(RelType);
126 Rel->getAdditionalInfo(RelAddend);
127 Rel->getSymbol(RelSym);
128 RelSym.getName(SymName);
129 RelSym.getAddress(SymAddr);
130 RelSym.getFileOffset(SymOffset);
131
132 // If this relocation is inside a function, we want to store the
133 // function name and a function-relative offset
134 IntervalMap::iterator ContainingFunc
135 = FuncMap.find(SecAddr + RelOffset);
136 if (ContainingFunc.valid()) {
137 // Re-base the relocation to make it relative to the target function
138 RelOffset = (SecAddr + RelOffset) - ContainingFunc.start();
139 Relocations[SymName].push_back(RelocationEntry(ContainingFunc.value(),
140 RelOffset,
141 RelType,
142 RelAddend,
143 true));
144 } else {
145 Relocations[SymName].push_back(RelocationEntry(SecName,
146 RelOffset,
147 RelType,
148 RelAddend,
149 false));
150 }
151 }
152 }
153 return false;
154 }
155
156 void RuntimeDyldELF::resolveRelocations() {
157 // FIXME: deprecated. should be changed to use the by-section
158 // allocation and relocation scheme.
159
160 // Just iterate over the symbols in our symbol table and assign their
161 // addresses.
162 StringMap::iterator i = SymbolTable.begin();
163 StringMap::iterator e = SymbolTable.end();
164 for (;i != e; ++i) {
165 assert (i->getValue().second == 0 && "non-zero offset in by-function sym!");
166 reassignSymbolAddress(i->getKey(),
167 (uint8_t*)Sections[i->getValue().first].base());
168 }
169 }
170
171 void RuntimeDyldELF::resolveX86_64Relocation(StringRef Name,
172 uint8_t *Addr,
173 const RelocationEntry &RE) {
174 uint8_t *TargetAddr;
175 if (RE.IsFunctionRelative) {
176 StringMap::const_iterator Loc = SymbolTable.find(RE.Target);
177 assert(Loc != SymbolTable.end() && "Function for relocation not found");
178 TargetAddr =
179 reinterpret_cast(Sections[Loc->second.first].base()) +
180 Loc->second.second + RE.Offset;
181 } else {
182 // FIXME: Get the address of the target section and add that to RE.Offset
183 llvm_unreachable("Non-function relocation not implemented yet!");
184 }
185
186 switch (RE.Type) {
187 default: llvm_unreachable("Relocation type not implemented yet!");
27
28 void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress,
29 uint64_t FinalAddress,
30 uint64_t Value,
31 uint32_t Type,
32 int64_t Addend) {
33 switch (Type) {
34 default:
35 llvm_unreachable("Relocation type not implemented yet!");
36 break;
18837 case ELF::R_X86_64_64: {
189 uint8_t **Target = reinterpret_cast(TargetAddr);
190 *Target = Addr + RE.Addend;
38 uint64_t *Target = (uint64_t*)(LocalAddress);
39 *Target = Value + Addend;
19140 break;
19241 }
19342 case ELF::R_X86_64_32:
19443 case ELF::R_X86_64_32S: {
195 uint64_t Value = reinterpret_cast(Addr) + RE.Addend;
44 Value += Addend;
19645 // FIXME: Handle the possibility of this assertion failing
197 assert((RE.Type == ELF::R_X86_64_32 && !(Value & 0xFFFFFFFF00000000ULL)) ||
198 (RE.Type == ELF::R_X86_64_32S &&
46 assert((Type == ELF::R_X86_64_32 && !(Value & 0xFFFFFFFF00000000ULL)) ||
47 (Type == ELF::R_X86_64_32S &&
19948 (Value & 0xFFFFFFFF00000000ULL) == 0xFFFFFFFF00000000ULL));
20049 uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
201 uint32_t *Target = reinterpret_cast(TargetAddr);
50 uint32_t *Target = reinterpret_cast(LocalAddress);
20251 *Target = TruncatedAddr;
20352 break;
20453 }
20554 case ELF::R_X86_64_PC32: {
206 uint32_t *Placeholder = reinterpret_cast(TargetAddr);
207 uint64_t RealOffset = *Placeholder +
208 reinterpret_cast(Addr) +
209 RE.Addend - reinterpret_cast(TargetAddr);
210 assert((RealOffset & 0xFFFFFFFF) == RealOffset);
211 uint32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
55 uint32_t *Placeholder = reinterpret_cast(LocalAddress);
56 int64_t RealOffset = *Placeholder + Value + Addend - FinalAddress;
57 assert(RealOffset <= 214783647 && RealOffset >= -214783648);
58 int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
21259 *Placeholder = TruncOffset;
21360 break;
21461 }
21562 }
21663 }
21764
218 void RuntimeDyldELF::resolveX86Relocation(StringRef Name,
219 uint8_t *Addr,
220 const RelocationEntry &RE) {
221 uint8_t *TargetAddr;
222 if (RE.IsFunctionRelative) {
223 StringMap::const_iterator Loc = SymbolTable.find(RE.Target);
224 assert(Loc != SymbolTable.end() && "Function for relocation not found");
225 TargetAddr =
226 reinterpret_cast(Sections[Loc->second.first].base()) +
227 Loc->second.second + RE.Offset;
228 } else {
229 // FIXME: Get the address of the target section and add that to RE.Offset
230 llvm_unreachable("Non-function relocation not implemented yet!");
231 }
232
233 switch (RE.Type) {
65 void RuntimeDyldELF::resolveX86Relocation(uint8_t *LocalAddress,
66 uint32_t FinalAddress,
67 uint32_t Value,
68 uint32_t Type,
69 int32_t Addend) {
70 switch (Type) {
23471 case ELF::R_386_32: {
235 uint8_t **Target = reinterpret_cast(TargetAddr);
236 *Target = Addr + RE.Addend;
72 uint32_t *Target = (uint32_t*)(LocalAddress);
73 *Target = Value + Addend;
23774 break;
23875 }
23976 case ELF::R_386_PC32: {
240 uint32_t *Placeholder = reinterpret_cast(TargetAddr);
241 uint32_t RealOffset = *Placeholder + reinterpret_cast(Addr) +
242 RE.Addend - reinterpret_cast(TargetAddr);
77 uint32_t *Placeholder = reinterpret_cast(LocalAddress);
78 uint32_t RealOffset = *Placeholder + Value + Addend - FinalAddress;
24379 *Placeholder = RealOffset;
24480 break;
24581 }
24783 // There are other relocation types, but it appears these are the
24884 // only ones currently used by the LLVM ELF object writer
24985 llvm_unreachable("Relocation type not implemented yet!");
250 }
251 }
252
253 void RuntimeDyldELF::resolveArmRelocation(StringRef Name,
254 uint8_t *Addr,
255 const RelocationEntry &RE) {
256 }
257
258 void RuntimeDyldELF::resolveRelocation(StringRef Name,
259 uint8_t *Addr,
260 const RelocationEntry &RE) {
86 break;
87 }
88 }
89
90 void RuntimeDyldELF::resolveARMRelocation(uint8_t *LocalAddress,
91 uint32_t FinalAddress,
92 uint32_t Value,
93 uint32_t Type,
94 int32_t Addend) {
95 // TODO: Add Thumb relocations.
96 uint32_t* TargetPtr = (uint32_t*)LocalAddress;
97 Value += Addend;
98
99 DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: " << LocalAddress
100 << " FinalAddress: " << format("%p",FinalAddress)
101 << " Value: " << format("%x",Value)
102 << " Type: " << format("%x",Type)
103 << " Addend: " << format("%x",Addend)
104 << "\n");
105
106 switch(Type) {
107 default:
108 llvm_unreachable("Not implemented relocation type!");
109
110 // Just write 32bit value to relocation address
111 case ELF::R_ARM_ABS32 :
112 *TargetPtr = Value;
113 break;
114
115 // Write first 16 bit of 32 bit value to the mov instruction.
116 // Last 4 bit should be shifted.
117 case ELF::R_ARM_MOVW_ABS_NC :
118 Value = Value & 0xFFFF;
119 *TargetPtr |= Value & 0xFFF;
120 *TargetPtr |= ((Value >> 12) & 0xF) << 16;
121 break;
122
123 // Write last 16 bit of 32 bit value to the mov instruction.
124 // Last 4 bit should be shifted.
125 case ELF::R_ARM_MOVT_ABS :
126 Value = (Value >> 16) & 0xFFFF;
127 *TargetPtr |= Value & 0xFFF;
128 *TargetPtr |= ((Value >> 12) & 0xF) << 16;
129 break;
130
131 // Write 24 bit relative value to the branch instruction.
132 case ELF::R_ARM_PC24 : // Fall through.
133 case ELF::R_ARM_CALL : // Fall through.
134 case ELF::R_ARM_JUMP24 :
135 int32_t RelValue = static_cast(Value - FinalAddress - 8);
136 RelValue = (RelValue & 0x03FFFFFC) >> 2;
137 *TargetPtr &= 0xFF000000;
138 *TargetPtr |= RelValue;
139 break;
140 }
141 }
142
143 void RuntimeDyldELF::resolveRelocation(uint8_t *LocalAddress,
144 uint64_t FinalAddress,
145 uint64_t Value,
146 uint32_t Type,
147 int64_t Addend) {
261148 switch (Arch) {
262149 case Triple::x86_64:
263 resolveX86_64Relocation(Name, Addr, RE);
150 resolveX86_64Relocation(LocalAddress, FinalAddress, Value, Type, Addend);
264151 break;
265152 case Triple::x86:
266 resolveX86Relocation(Name, Addr, RE);
267 break;
268 case Triple::arm:
269 resolveArmRelocation(Name, Addr, RE);
153 resolveX86Relocation(LocalAddress, (uint32_t)(FinalAddress & 0xffffffffL),
154 (uint32_t)(Value & 0xffffffffL), Type,
155 (uint32_t)(Addend & 0xffffffffL));
156 break;
157 case Triple::arm: // Fall through.
158 case Triple::thumb:
159 resolveARMRelocation(LocalAddress, (uint32_t)(FinalAddress & 0xffffffffL),
160 (uint32_t)(Value & 0xffffffffL), Type,
161 (uint32_t)(Addend & 0xffffffffL));
270162 break;
271163 default: llvm_unreachable("Unsupported CPU type!");
272164 }
273165 }
274166
275 void RuntimeDyldELF::reassignSymbolAddress(StringRef Name, uint8_t *Addr) {
276 // FIXME: deprecated. switch to reassignSectionAddress() instead.
277 //
278 // Actually moving the symbol address requires by-section mapping.
279 assert(Sections[SymbolTable.lookup(Name).first].base() == (void*)Addr &&
280 "Unable to relocate section in by-function JIT allocation model!");
281
282 RelocationList &Relocs = Relocations[Name];
283 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
284 RelocationEntry &RE = Relocs[i];
285 resolveRelocation(Name, Addr, RE);
286 }
287 }
288
289 // Assign an address to a symbol name and resolve all the relocations
290 // associated with it.
291 void RuntimeDyldELF::reassignSectionAddress(unsigned SectionID, uint64_t Addr) {
292 // The address to use for relocation resolution is not
293 // the address of the local section buffer. We must be doing
294 // a remote execution environment of some sort. Re-apply any
295 // relocations referencing this section with the given address.
296 //
297 // Addr is a uint64_t because we can't assume the pointer width
298 // of the target is the same as that of the host. Just use a generic
299 // "big enough" type.
300 assert(0);
167 void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
168 const ObjectFile &Obj,
169 ObjSectionToIDMap &ObjSectionToID,
170 LocalSymbolMap &Symbols,
171 StubMap &Stubs) {
172
173 uint32_t RelType = (uint32_t)(Rel.Type & 0xffffffffL);
174 intptr_t Addend = (intptr_t)Rel.AdditionalInfo;
175 RelocationValueRef Value;
176 StringRef TargetName;
177 const SymbolRef &Symbol = Rel.Symbol;
178 Symbol.getName(TargetName);
179 DEBUG(dbgs() << "\t\tRelType: " << RelType
180 << " Addend: " << Addend
181 << " TargetName: " << TargetName
182 << "\n");
183 // First look the symbol in object file symbols.
184 LocalSymbolMap::iterator lsi = Symbols.find(TargetName.data());
185 if (lsi != Symbols.end()) {
186 Value.SectionID = lsi->second.first;
187 Value.Addend = lsi->second.second;
188 } else {
189 // Second look the symbol in global symbol table.
190 StringMap::iterator gsi = SymbolTable.find(TargetName.data());
191 if (gsi != SymbolTable.end()) {
192 Value.SectionID = gsi->second.first;
193 Value.Addend = gsi->second.second;
194 } else {
195 SymbolRef::Type SymType;
196 Symbol.getType(SymType);
197 switch (SymType) {
198 case SymbolRef::ST_Debug: {
199 // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously
200 // and can be changed by another developers. Maybe best way is add
201 // a new symbol type ST_Section to SymbolRef and use it.
202 section_iterator si = Obj.end_sections();
203 Symbol.getSection(si);
204 if (si == Obj.end_sections())
205 llvm_unreachable("Symbol section not found, bad object file format!");
206 DEBUG(dbgs() << "\t\tThis is section symbol\n");
207 Value.SectionID = findOrEmitSection((*si), true, ObjSectionToID);
208 Value.Addend = Addend;
209 break;
210 }
211 case SymbolRef::ST_Unknown: {
212 Value.SymbolName = TargetName.data();
213 Value.Addend = Addend;
214 break;
215 }
216 default:
217 llvm_unreachable("Unresolved symbol type!");
218 break;
219 }
220 }
221 }
222 DEBUG(dbgs() << "\t\tRel.SectionID: " << Rel.SectionID
223 << " Rel.Offset: " << Rel.Offset
224 << "\n");
225 if (Arch == Triple::arm &&
226 (RelType == ELF::R_ARM_PC24 ||
227 RelType == ELF::R_ARM_CALL ||
228 RelType == ELF::R_ARM_JUMP24)) {
229 // This is an ARM branch relocation, need to use a stub function.
230 DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.");
231 SectionEntry &Section = Sections[Rel.SectionID];
232 uint8_t *Target = Section.Address + Rel.Offset;
233
234 // Look up for existing stub.
235 StubMap::const_iterator i = Stubs.find(Value);
236 if (i != Stubs.end()) {
237 resolveRelocation(Target, Section.LoadAddress, (uint64_t)Section.Address +
238 i->second, RelType, 0);
239 DEBUG(dbgs() << " Stub function found\n");
240 } else {
241 // Create a new stub function.
242 DEBUG(dbgs() << " Create a new stub function\n");
243 Stubs[Value] = Section.StubOffset;
244 uint8_t *StubTargetAddr = createStubFunction(Section.Address +
245 Section.StubOffset);
246 AddRelocation(Value, Rel.SectionID,
247 StubTargetAddr - Section.Address, ELF::R_ARM_ABS32);
248 resolveRelocation(Target, Section.LoadAddress, (uint64_t)Section.Address +
249 Section.StubOffset, RelType, 0);
250 Section.StubOffset += getMaxStubSize();
251 }
252 } else
253 AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType);
301254 }
302255
303256 bool RuntimeDyldELF::isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
2020
2121 namespace llvm {
2222 class RuntimeDyldELF : public RuntimeDyldImpl {
23 // For each symbol, keep a list of relocations based on it. Anytime
24 // its address is reassigned (the JIT re-compiled the function, e.g.),
25 // the relocations get re-resolved.
26 struct RelocationEntry {
27 // Function or section this relocation is contained in.
28 std::string Target;
29 // Offset into the target function or section for the relocation.
30 uint32_t Offset;
31 // Relocation type
32 uint32_t Type;
33 // Addend encoded in the instruction itself, if any.
34 int32_t Addend;
35 // Has the relocation been recalcuated as an offset within a function?
36 bool IsFunctionRelative;
37 // Has this relocation been resolved previously?
38 bool isResolved;
23 protected:
24 void resolveX86_64Relocation(uint8_t *LocalAddress,
25 uint64_t FinalAddress,
26 uint64_t Value,
27 uint32_t Type,
28 int64_t Addend);
3929
40 RelocationEntry(StringRef t,
41 uint32_t offset,
42 uint32_t type,
43 int32_t addend,
44 bool isFunctionRelative)
45 : Target(t)
46 , Offset(offset)
47 , Type(type)
48 , Addend(addend)
49 , IsFunctionRelative(isFunctionRelative)
50 , isResolved(false) { }
51 };
52 typedef SmallVector RelocationList;
53 StringMap Relocations;
54 unsigned Arch;
30 void resolveX86Relocation(uint8_t *LocalAddress,
31 uint32_t FinalAddress,
32 uint32_t Value,
33 uint32_t Type,
34 int32_t Addend);
5535
56 void resolveRelocations();
36 void resolveARMRelocation(uint8_t *LocalAddress,
37 uint32_t FinalAddress,
38 uint32_t Value,
39 uint32_t Type,
40 int32_t Addend);
5741
58 void resolveX86_64Relocation(StringRef Name,
59 uint8_t *Addr,
60 const RelocationEntry &RE);
42 virtual void resolveRelocation(uint8_t *LocalAddress,
43 uint64_t FinalAddress,
44 uint64_t Value,
45 uint32_t Type,
46 int64_t Addend);
6147
62 void resolveX86Relocation(StringRef Name,
63 uint8_t *Addr,
64 const RelocationEntry &RE);
65
66 void resolveArmRelocation(StringRef Name,
67 uint8_t *Addr,
68 const RelocationEntry &RE);
69
70 void resolveRelocation(StringRef Name,
71 uint8_t *Addr,
72 const RelocationEntry &RE);
48 virtual void processRelocationRef(const ObjRelocationInfo &Rel,
49 const ObjectFile &Obj,
50 ObjSectionToIDMap &ObjSectionToID,
51 LocalSymbolMap &Symbols, StubMap &Stubs);
7352
7453 public:
7554 RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
76
77 bool loadObject(MemoryBuffer *InputBuffer);
78
79 void reassignSymbolAddress(StringRef Name, uint8_t *Addr);
80 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
8155
8256 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
8357 };
8458
8559 } // end namespace llvm
8660
87 #endif
88
89 //===-- RuntimeDyldELF.h - Run-time dynamic linker for MC-JIT ---*- C++ -*-===//
90 //
91 // The LLVM Compiler Infrastructure
92 //
93 // This file is distributed under the University of Illinois Open Source
94 // License. See LICENSE.TXT for details.
95 //
96 //===----------------------------------------------------------------------===//
97 //
98 // ELF support for MC-JIT runtime dynamic linker.
99 //
100 //===----------------------------------------------------------------------===//
101
102 #ifndef LLVM_RUNTIME_DYLD_ELF_H
103 #define LLVM_RUNTIME_DYLD_ELF_H
104
105 #include "RuntimeDyldImpl.h"
106
107 using namespace llvm;
108
109
110 namespace llvm {
111 class RuntimeDyldELF : public RuntimeDyldImpl {
112 // For each symbol, keep a list of relocations based on it. Anytime
113 // its address is reassigned (the JIT re-compiled the function, e.g.),
114 // the relocations get re-resolved.
115 struct RelocationEntry {
116 // Function or section this relocation is contained in.
117 std::string Target;
118 // Offset into the target function or section for the relocation.
119 uint32_t Offset;
120 // Relocation type
121 uint32_t Type;
122 // Addend encoded in the instruction itself, if any.
123 int32_t Addend;
124 // Has the relocation been recalcuated as an offset within a function?
125 bool IsFunctionRelative;
126 // Has this relocation been resolved previously?
127 bool isResolved;
128
129 RelocationEntry(StringRef t,
130 uint32_t offset,
131 uint32_t type,
132 int32_t addend,
133 bool isFunctionRelative)
134 : Target(t)
135 , Offset(offset)
136 , Type(type)
137 , Addend(addend)
138 , IsFunctionRelative(isFunctionRelative)
139 , isResolved(false) { }
140 };
141 typedef SmallVector RelocationList;
142 StringMap Relocations;
143 unsigned Arch;
144
145 void resolveRelocations();
146
147 void resolveX86_64Relocation(StringRef Name,
148 uint8_t *Addr,
149 const RelocationEntry &RE);
150
151 void resolveX86Relocation(StringRef Name,
152 uint8_t *Addr,
153 const RelocationEntry &RE);
154
155 void resolveArmRelocation(StringRef Name,
156 uint8_t *Addr,
157 const RelocationEntry &RE);
158
159 void resolveRelocation(StringRef Name,
160 uint8_t *Addr,
161 const RelocationEntry &RE);
162
163 public:
164 RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
165
166 bool loadObject(MemoryBuffer *InputBuffer);
167
168 void reassignSymbolAddress(StringRef Name, uint8_t *Addr);
169 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
170
171 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
172 };
173
174 } // end namespace llvm
175
176 #endif
177
61 #endif
1414 #define LLVM_RUNTIME_DYLD_IMPL_H
1515
1616 #include "llvm/ExecutionEngine/RuntimeDyld.h"
17 #include "llvm/Object/ObjectFile.h"
1718 #include "llvm/ADT/DenseMap.h"
1819 #include "llvm/ADT/StringMap.h"
1920 #include "llvm/ADT/Twine.h"
2021 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ExecutionEngine/ExecutionEngine.h"
2222 #include "llvm/Support/Memory.h"
2323 #include "llvm/Support/MemoryBuffer.h"
2424 #include "llvm/Support/system_error.h"
2525 #include "llvm/Support/raw_ostream.h"
2626 #include "llvm/Support/Debug.h"
2727 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/ADT/Triple.h"
29 #include
30 #include "llvm/Support/Format.h"
2831
2932 using namespace llvm;
33 using namespace llvm::object;
3034
3135 namespace llvm {
36
37 class SectionEntry {
38 public:
39 uint8_t* Address;
40 size_t Size;
41 uint64_t LoadAddress; // For each section, the address it will be
42 // considered to live at for relocations. The same
43 // as the pointer to the above memory block for
44 // hosted JITs.
45 uintptr_t StubOffset; // It's used for architecturies with stub
46 // functions for far relocations like ARM.
47 uintptr_t ObjAddress; // Section address in object file. It's use for
48 // calculate MachO relocation addend
49 SectionEntry(uint8_t* address, size_t size, uintptr_t stubOffset,
50 uintptr_t objAddress)
51 : Address(address), Size(size), LoadAddress((uintptr_t)address),
52 StubOffset(stubOffset), ObjAddress(objAddress) {}
53 };
54
55 class RelocationEntry {
56 public:
57 unsigned SectionID; // Section the relocation is contained in.
58 uintptr_t Offset; // Offset into the section for the relocation.
59 uint32_t Data; // Relocatino data. Including type of relocation
60 // and another flags and parameners from
61 intptr_t Addend; // Addend encoded in the instruction itself, if any,
62 // plus the offset into the source section for
63 // the symbol once the relocation is resolvable.
64 RelocationEntry(unsigned id, uint64_t offset, uint32_t data, int64_t addend)
65 : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
66 };
67
68 // Raw relocation data from object file
69 class ObjRelocationInfo {
70 public:
71 unsigned SectionID;
72 uint64_t Offset;
73 SymbolRef Symbol;
74 uint64_t Type;
75 int64_t AdditionalInfo;
76 };
77
78 class RelocationValueRef {
79 public:
80 unsigned SectionID;
81 intptr_t Addend;
82 const char *SymbolName;
83 RelocationValueRef(): SectionID(0), Addend(0), SymbolName(0) {}
84
85 inline bool operator==(const RelocationValueRef &Other) const {
86 return std::memcmp(this, &Other, sizeof(RelocationValueRef)) == 0;
87 }
88 inline bool operator <(const RelocationValueRef &Other) const {
89 return std::memcmp(this, &Other, sizeof(RelocationValueRef)) < 0;
90 }
91 };
92
3293 class RuntimeDyldImpl {
3394 protected:
34 unsigned CPUType;
35 unsigned CPUSubtype;
36
3795 // The MemoryManager to load objects into.
3896 RTDyldMemoryManager *MemMgr;
3997
40 // For each section, we have a MemoryBlock of it's data.
41 // Indexed by SectionID.
42 SmallVector Sections;
43 // For each section, the address it will be considered to live at for
44 // relocations. The same as the pointer to the above memory block for hosted
45 // JITs. Indexed by SectionID.
46 SmallVector SectionLoadAddress;
47
48 // Keep a map of starting local address to the SectionID which references it.
49 // Lookup function for when we assign virtual addresses.
50 DenseMap SectionLocalMemToID;
98 // A list of emmitted sections.
99 typedef SmallVector SectionList;
100 SectionList Sections;
101
102 // Keep a map of sections from object file to the SectionID which
103 // references it.
104 typedef std::map ObjSectionToIDMap;
51105
52106 // Master symbol table. As modules are loaded and external symbols are
53107 // resolved, their addresses are stored here as a SectionID/Offset pair.
54 typedef std::pair64_t> SymbolLoc;
108 typedef std::pairptr_t> SymbolLoc;
55109 StringMap SymbolTable;
110 typedef DenseMap LocalSymbolMap;
111
112 // For each symbol, keep a list of relocations based on it. Anytime
113 // its address is reassigned (the JIT re-compiled the function, e.g.),
114 // the relocations get re-resolved.
115 // The symbol (or section) the relocation is sourced from is the Key
116 // in the relocation list where it's stored.
117 typedef SmallVector RelocationList;
118 // Relocations to sections already loaded. Indexed by SectionID which is the
119 // source of the address. The target where the address will be writen is
120 // SectionID/Offset in the relocation itself.
121 DenseMap Relocations;
122 // Relocations to external symbols that are not yet resolved.
123 // Indexed by symbol name.
124 StringMap SymbolRelocations;
125
126 typedef std::map StubMap;
127
128 Triple::ArchType Arch;
129
130 inline unsigned getMaxStubSize() {
131 if (Arch == Triple::arm || Arch == Triple::thumb)
132 return 8; // 32-bit instruction and 32-bit address
133 else
134 return 0;
135 }
56136
57137 bool HasError;
58138 std::string ErrorStr;
65145 }
66146
67147 uint8_t *getSectionAddress(unsigned SectionID) {
68 return (uint8_t*)Sections[SectionID].base();
69 }
70 void extractFunction(StringRef Name, uint8_t *StartAddress,
71 uint8_t *EndAddress);
72
148 return (uint8_t*)Sections[SectionID].Address;
149 }
150
151 /// \brief Emits section data from the object file to the MemoryManager.
152 /// \param IsCode if it's true then allocateCodeSection() will be
153 /// used for emmits, else allocateDataSection() will be used.
154 /// \return SectionID.
155 unsigned emitSection(const SectionRef &Section, bool IsCode);
156
157 /// \brief Find Section in LocalSections. If the secton is not found - emit
158 /// it and store in LocalSections.
159 /// \param IsCode if it's true then allocateCodeSection() will be
160 /// used for emmits, else allocateDataSection() will be used.
161 /// \return SectionID.
162 unsigned findOrEmitSection(const SectionRef &Section, bool IsCode,
163 ObjSectionToIDMap &LocalSections);
164
165 /// \brief If Value.SymbolName is NULL then store relocation to the
166 /// Relocations, else store it in the SymbolRelocations.
167 void AddRelocation(const RelocationValueRef &Value, unsigned SectionID,
168 uintptr_t Offset, uint32_t RelType);
169
170 /// \brief Emits long jump instruction to Addr.
171 /// \return Pointer to the memory area for emitting target address.
172 uint8_t* createStubFunction(uint8_t *Addr);
173
174 /// \brief Resolves relocations from Relocs list with address from Value.
175 void resolveRelocationList(const RelocationList &Relocs, uint64_t Value);
176 void resolveRelocationEntry(const RelocationEntry &RE, uint64_t Value);
177
178 /// \brief A object file specific relocation resolver
179 /// \param Address Address to apply the relocation action
180 /// \param Value Target symbol address to apply the relocation action
181 /// \param Type object file specific relocation type
182 /// \param Addend A constant addend used to compute the value to be stored
183 /// into the relocatable field
184 virtual void resolveRelocation(uint8_t *LocalAddress,
185 uint64_t FinalAddress,
186 uint64_t Value,
187 uint32_t Type,
188 int64_t Addend) = 0;
189
190 /// \brief Parses the object file relocation and store it to Relocations
191 /// or SymbolRelocations. Its depend from object file type.
192 virtual void processRelocationRef(const ObjRelocationInfo &Rel,
193 const ObjectFile &Obj,
194 ObjSectionToIDMap &ObjSectionToID,
195 LocalSymbolMap &Symbols, StubMap &Stubs) = 0;
196
197 void resolveSymbols();
73198 public:
74199 RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
75200
76201 virtual ~RuntimeDyldImpl();
77202
78 virtual bool loadObject(MemoryBuffer *InputBuffer) = 0;
203 bool loadObject(const MemoryBuffer *InputBuffer);
79204
80205 void *getSymbolAddress(StringRef Name) {
81206 // FIXME: Just look up as a function for now. Overly simple of course.
86211 return getSectionAddress(Loc.first) + Loc.second;
87212 }
88213
89 virtual void resolveRelocations();
90
91 virtual void reassignSectionAddress(unsigned SectionID, uint64_t Addr) = 0;
214 void resolveRelocations();
215
216 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
92217
93218 void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress);
94219
102227 StringRef getErrorString() { return ErrorStr; }
103228
104229 virtual bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const = 0;
230
105231 };
106232
107233 } // end namespace llvm
2020
2121 namespace llvm {
2222
23 bool RuntimeDyldMachO::
24 resolveRelocation(uint8_t *LocalAddress,
25 uint64_t FinalAddress,
26 uint64_t Value,
27 bool isPCRel,
28 unsigned Type,
29 unsigned Size,
30 int64_t Addend) {
23 void RuntimeDyldMachO::resolveRelocation(uint8_t *LocalAddress,
24 uint64_t FinalAddress,
25 uint64_t Value,
26 uint32_t Type,
27 int64_t Addend) {
28 bool isPCRel = (Type >> 24) & 1;
29 unsigned MachoType = (Type >> 28) & 0xf;
30 unsigned Size = 1 << ((Type >> 25) & 3);
31
32 DEBUG(dbgs() << "resolveRelocation LocalAddress: " << format("%p", LocalAddress)
33 << " FinalAddress: " << format("%p", FinalAddress)
34 << " Value: " << format("%p", Value)
35 << " Addend: " << Addend
36 << " isPCRel: " << isPCRel
37 << " MachoType: " << MachoType
38 << " Size: " << Size
39 << "\n");
40
3141 // This just dispatches to the proper target specific routine.
32 switch (CPUType) {
42 switch (Arch) {
3343 default: llvm_unreachable("Unsupported CPU type!");
34 case mach::CTM_i386:
35 return resolveI386Relocation(LocalAddress,
44 case Triple::x86_64:
45 resolveX86_64Relocation(LocalAddress,
46 FinalAddress,
47 (uintptr_t)Value,
48 isPCRel,
49 MachoType,
50 Size,
51 Addend);
52 break;
53 case Triple::x86:
54 resolveI386Relocation(LocalAddress,
3655 FinalAddress,
3756 (uintptr_t)Value,
3857 isPCRel,
3958 Type,
4059 Size,
4160 Addend);
42 case mach::CTM_x86_64:
43 return resolveX86_64Relocation(LocalAddress,
44 FinalAddress,
45 (uintptr_t)Value,
46 isPCRel,
47 Type,
48 Size,
49 Addend);
50 case mach::CTM_ARM:
51 return resolveARMRelocation(LocalAddress,
52 FinalAddress,
53 (uintptr_t)Value,
54 isPCRel,
55 Type,
56 Size,
57 Addend);
61 break;
62 case Triple::arm: // Fall through.
63 case Triple::thumb:
64 resolveARMRelocation(LocalAddress,
65 FinalAddress,
66 (uintptr_t)Value,
67 isPCRel,
68 MachoType,
69 Size,
70 Addend);
71 break;
5872 }
5973 }
6074
189203 return false;
190204 }
191205
192 bool RuntimeDyldMachO::
193 loadSegment32(const MachOObject *Obj,
194 const MachOObject::LoadCommandInfo *SegmentLCI,
195 const InMemoryStruct &SymtabLC) {
196 // FIXME: This should really be combined w/ loadSegment64. Templatized
197 // function on the 32/64 datatypes maybe?
198 InMemoryStruct SegmentLC;
199 Obj->ReadSegmentLoadCommand(*SegmentLCI, SegmentLC);
200 if (!SegmentLC)
201 return Error("unable to load segment load command");
202
203
204 SmallVector SectionMap;
205 for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
206 InMemoryStruct Sect;
207 Obj->ReadSection(*SegmentLCI, SectNum, Sect);
208 if (!Sect)
209 return Error("unable to load section: '" + Twine(SectNum) + "'");
210
211 // Allocate memory via the MM for the section.
212 uint8_t *Buffer;
213 uint32_t SectionID = Sections.size();
214 if (Sect->Flags == 0x80000400)
215 Buffer = MemMgr->allocateCodeSection(Sect->Size, Sect->Align, SectionID);
216 else
217 Buffer = MemMgr->allocateDataSection(Sect->Size, Sect->Align, SectionID);
218
219 DEBUG(dbgs() << "Loading "
220 << ((Sect->Flags == 0x80000400) ? "text" : "data")
221 << " (ID #" << SectionID << ")"
222 << " '" << Sect->SegmentName << ","
223 << Sect->Name << "' of size " << Sect->Size
224 << " to address " << Buffer << ".\n");
225
226 // Copy the payload from the object file into the allocated buffer.
227 uint8_t *Base = (uint8_t*)Obj->getData(SegmentLC->FileOffset,
228 SegmentLC->FileSize).data();
229 memcpy(Buffer, Base + Sect->Address, Sect->Size);
230
231 // Remember what got allocated for this SectionID.
232 Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size));
233 SectionLocalMemToID[Buffer] = SectionID;
234
235 // By default, the load address of a section is its memory buffer.
236 SectionLoadAddress.push_back((uint64_t)Buffer);
237
238 // Keep a map of object file section numbers to corresponding SectionIDs
239 // while processing the file.
240 SectionMap.push_back(SectionID);
241 }
242
243 // Process the symbol table.
244 SmallVector SymbolNames;
245 processSymbols32(Obj, SectionMap, SymbolNames, SymtabLC);
246
247 // Process the relocations for each section we're loading.
248 Relocations.grow(Relocations.size() + SegmentLC->NumSections);
249 Referrers.grow(Referrers.size() + SegmentLC->NumSections);
250 for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
251 InMemoryStruct Sect;
252 Obj->ReadSection(*SegmentLCI, SectNum, Sect);
253 if (!Sect)
254 return Error("unable to load section: '" + Twine(SectNum) + "'");
255 for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) {
256 InMemoryStruct RE;
257 Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE);
258 if (RE->Word0 & macho::RF_Scattered)
259 return Error("NOT YET IMPLEMENTED: scattered relocations.");
260 // Word0 of the relocation is the offset into the section where the
261 // relocation should be applied. We need to translate that into an
262 // offset into a function since that's our atom.
263 uint32_t Offset = RE->Word0;
264 bool isExtern = (RE->Word1 >> 27) & 1;
265
266 // FIXME: Get the relocation addend from the target address.
267 // FIXME: VERY imporant for internal relocations.
268
269 // Figure out the source symbol of the relocation. If isExtern is true,
270 // this relocation references the symbol table, otherwise it references
271 // a section in the same object, numbered from 1 through NumSections
272 // (SectionBases is [0, NumSections-1]).
273 uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value
274 if (!isExtern) {
275 assert(SourceNum > 0 && "Invalid relocation section number!");
276 unsigned SectionID = SectionMap[SourceNum - 1];
277 unsigned TargetID = SectionMap[SectNum];
278 DEBUG(dbgs() << "Internal relocation at Section #"
279 << TargetID << " + " << Offset
280 << " from Section #"
281 << SectionID << " (Word1: "
282 << format("0x%x", RE->Word1) << ")\n");
283
284 // Store the relocation information. It will get resolved when
285 // the section addresses are assigned.
286 uint32_t RelocationIndex = Relocations[SectionID].size();
287 Relocations[SectionID].push_back(RelocationEntry(TargetID,
288 Offset,
289 RE->Word1,
290 0 /*Addend*/));
291 Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex));
292 } else {
293 StringRef SourceName = SymbolNames[SourceNum];
294
295 // Now store the relocation information. Associate it with the source
296 // symbol. Just add it to the unresolved list and let the general
297 // path post-load resolve it if we know where the symbol is.
298 UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum,
299 Offset,
300 RE->Word1,
301 0 /*Addend*/));
302 DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset
303 << " from '" << SourceName << "(Word1: "
304 << format("0x%x", RE->Word1) << ")\n");
305 }
306 }
307 }
308
309 // Resolve the addresses of any symbols that were defined in this segment.
310 for (int i = 0, e = SymbolNames.size(); i != e; ++i)
311 resolveSymbol(SymbolNames[i]);
312
313 return false;
314 }
315
316
317 bool RuntimeDyldMachO::
318 loadSegment64(const MachOObject *Obj,
319 const MachOObject::LoadCommandInfo *SegmentLCI,
320 const InMemoryStruct &SymtabLC) {
321 InMemoryStruct Segment64LC;
322 Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC);
323 if (!Segment64LC)
324 return Error("unable to load segment load command");
325
326
327 SmallVector SectionMap;
328 for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
329 InMemoryStruct Sect;
330 Obj->ReadSection64(*SegmentLCI, SectNum, Sect);
331 if (!Sect)
332 return Error("unable to load section: '" + Twine(SectNum) + "'");
333
334 // Allocate memory via the MM for the section.
335 uint8_t *Buffer;
336 uint32_t SectionID = Sections.size();
337 unsigned Align = 1 << Sect->Align; // .o file has log2 alignment.
338 if (Sect->Flags == 0x80000400)
339 Buffer = MemMgr->allocateCodeSection(Sect->Size, Align, SectionID);
340 else
341 Buffer = MemMgr->allocateDataSection(Sect->Size, Align, SectionID);
342
343 DEBUG(dbgs() << "Loading "
344 << ((Sect->Flags == 0x80000400) ? "text" : "data")
345 << " (ID #" << SectionID << ")"
346 << " '" << Sect->SegmentName << ","
347 << Sect->Name << "' of size " << Sect->Size
348 << " (align " << Align << ")"
349 << " to address " << Buffer << ".\n");
350
351 // Copy the payload from the object file into the allocated buffer.
352 uint8_t *Base = (uint8_t*)Obj->getData(Segment64LC->FileOffset,
353 Segment64LC->FileSize).data();
354 memcpy(Buffer, Base + Sect->Address, Sect->Size);
355
356 // Remember what got allocated for this SectionID.
357 Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size));
358 SectionLocalMemToID[Buffer] = SectionID;
359
360 // By default, the load address of a section is its memory buffer.
361 SectionLoadAddress.push_back((uint64_t)Buffer);
362
363 // Keep a map of object file section numbers to corresponding SectionIDs
364 // while processing the file.
365 SectionMap.push_back(SectionID);
366 }
367
368 // Process the symbol table.
369 SmallVector SymbolNames;
370 processSymbols64(Obj, SectionMap, SymbolNames, SymtabLC);
371
372 // Process the relocations for each section we're loading.
373 Relocations.grow(Relocations.size() + Segment64LC->NumSections);
374 Referrers.grow(Referrers.size() + Segment64LC->NumSections);
375 for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
376 InMemoryStruct Sect;
377 Obj->ReadSection64(*SegmentLCI, SectNum, Sect);
378 if (!Sect)
379 return Error("unable to load section: '" + Twine(SectNum) + "'");
380 for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) {
381 InMemoryStruct RE;
382 Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE);
383 if (RE->Word0 & macho::RF_Scattered)
384 return Error("NOT YET IMPLEMENTED: scattered relocations.");
385 // Word0 of the relocation is the offset into the section where the
386 // relocation should be applied. We need to translate that into an
387 // offset into a function since that's our atom.
388 uint32_t Offset = RE->Word0;
389 bool isExtern = (RE->Word1 >> 27) & 1;
390
391 // FIXME: Get the relocation addend from the target address.
392 // FIXME: VERY imporant for internal relocations.
393
394 // Figure out the source symbol of the relocation. If isExtern is true,
395 // this relocation references the symbol table, otherwise it references
396 // a section in the same object, numbered from 1 through NumSections
397 // (SectionBases is [0, NumSections-1]).
398 uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value
399 if (!isExtern) {
400 assert(SourceNum > 0 && "Invalid relocation section number!");
401 unsigned SectionID = SectionMap[SourceNum - 1];
402 unsigned TargetID = SectionMap[SectNum];
403 DEBUG(dbgs() << "Internal relocation at Section #"
404 << TargetID << " + " << Offset
405 << " from Section #"
406 << SectionID << " (Word1: "
407 << format("0x%x", RE->Word1) << ")\n");
408
409 // Store the relocation information. It will get resolved when
410 // the section addresses are assigned.
411 uint32_t RelocationIndex = Relocations[SectionID].size();
412 Relocations[SectionID].push_back(RelocationEntry(TargetID,
413 Offset,
414 RE->Word1,
415 0 /*Addend*/));
416 Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex));
417 } else {
418 StringRef SourceName = SymbolNames[SourceNum];
419
420 // Now store the relocation information. Associate it with the source
421 // symbol. Just add it to the unresolved list and let the general
422 // path post-load resolve it if we know where the symbol is.
423 UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum,
424 Offset,
425 RE->Word1,
426 0 /*Addend*/));
427 DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset
428 << " from '" << SourceName << "(Word1: "
429 << format("0x%x", RE->Word1) << ")\n");
430 }
431 }
432 }
433
434 // Resolve the addresses of any symbols that were defined in this segment.
435 for (int i = 0, e = SymbolNames.size(); i != e; ++i)
436 resolveSymbol(SymbolNames[i]);
437
438 return false;
439 }
440
441 bool RuntimeDyldMachO::
442 processSymbols32(const MachOObject *Obj,
443 SmallVectorImpl &SectionMap,
444 SmallVectorImpl &SymbolNames,
445 const InMemoryStruct &SymtabLC) {
446 // FIXME: Combine w/ processSymbols64. Factor 64/32 datatype and such.
447 for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
448 InMemoryStruct STE;
449 Obj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE);
450 if (!STE)
451 return Error("unable to read symbol: '" + Twine(i) + "'");
452 // Get the symbol name.
453 StringRef Name = Obj->getStringAtIndex(STE->StringIndex);
454 SymbolNames.push_back(Name);
455
456 // FIXME: Check the symbol type and flags.
457 if (STE->Type != 0xF) // external, defined in this segment.
458 continue;
459 // Flags in the upper nibble we don't care about.
460 if ((STE->Flags & 0xf) != 0x0)
461 continue;
462
463 // Remember the symbol.
464 uint32_t SectionID = SectionMap[STE->SectionIndex - 1];
465 SymbolTable[Name] = SymbolLoc(SectionID, STE->Value);
466
467 DEBUG(dbgs() << "Symbol: '" << Name << "' @ "
468 << (getSectionAddress(SectionID) + STE->Value)
469 << "\n");
470 }
471 return false;
472 }
473
474 bool RuntimeDyldMachO::
475 processSymbols64(const MachOObject *Obj,
476 SmallVectorImpl &SectionMap,
477 SmallVectorImpl &SymbolNames,
478 const InMemoryStruct &SymtabLC) {
479 for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
480 InMemoryStruct STE;
481 Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE);
482 if (!STE)
483 return Error("unable to read symbol: '" + Twine(i) + "'");
484 // Get the symbol name.
485 StringRef Name = Obj->getStringAtIndex(STE->StringIndex);
486 SymbolNames.push_back(Name);
487
488 // FIXME: Check the symbol type and flags.
489 if (STE->Type != 0xF) // external, defined in this segment.
490 continue;
491 // Flags in the upper nibble we don't care about.
492 if ((STE->Flags & 0xf) != 0x0)
493 continue;
494
495 // Remember the symbol.
496 uint32_t SectionID = SectionMap[STE->SectionIndex - 1];
497 SymbolTable[Name] = SymbolLoc(SectionID, STE->Value);
498
499 DEBUG(dbgs() << "Symbol: '" << Name << "' @ "
500 << (getSectionAddress(SectionID) + STE->Value)
501 << "\n");
502 }
503 return false;
504 }
505
506 // resolveSymbol - Resolve any relocations to the specified symbol if
507 // we know where it lives.
508 void RuntimeDyldMachO::resolveSymbol(StringRef Name) {
509 StringMap::const_iterator Loc = SymbolTable.find(Name);
510 if (Loc == SymbolTable.end())
511 return;
512
513 RelocationList &Relocs = UnresolvedRelocations[Name];
514 DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n");
515 for (int i = 0, e = Relocs.size(); i != e; ++i) {
516 // Change the relocation to be section relative rather than symbol
517 // relative and move it to the resolved relocation list.
518 RelocationEntry Entry = Relocs[i];
519 Entry.Addend += Loc->second.second;
520 uint32_t RelocationIndex = Relocations[Loc->second.first].size();
521 Relocations[Loc->second.first].push_back(Entry);
522 Referrers[Entry.SectionID].push_back(Referrer(Loc->second.first, RelocationIndex));
523 }
524 // FIXME: Keep a worklist of the relocations we've added so that we can
525 // resolve more selectively later.
526 Relocs.clear();
527 }
528
529 bool RuntimeDyldMachO::loadObject(MemoryBuffer *InputBuffer) {
530 // If the linker is in an error state, don't do anything.
531 if (hasError())
532 return true;
533 // Load the Mach-O wrapper object.
534 std::string ErrorStr;
535 OwningPtr Obj(
536 MachOObject::LoadFromBuffer(InputBuffer, &ErrorStr));
537 if (!Obj)
538 return Error("unable to load object: '" + ErrorStr + "'");
539
540 // Get the CPU type information from the header.
541 const macho::Header &Header = Obj->getHeader();
542
543 // FIXME: Error checking that the loaded object is compatible with
544 // the system we're running on.
545 CPUType = Header.CPUType;
546 CPUSubtype = Header.CPUSubtype;
547
548 // Validate that the load commands match what we expect.
549 const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0,
550 *DysymtabLCI = 0;
551 for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
552 const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i);
553 switch (LCI.Command.Type) {
554 case macho::LCT_Segment:
555 case macho::LCT_Segment64:
556 if (SegmentLCI)
557 return Error("unexpected input object (multiple segments)");
558 SegmentLCI = &LCI;
559 break;
560 case macho::LCT_Symtab:
561 if (SymtabLCI)
562 return Error("unexpected input object (multiple symbol tables)");
563 SymtabLCI = &LCI;
564 break;
565 case macho::LCT_Dysymtab:
566 if (DysymtabLCI)
567 return Error("unexpected input object (multiple symbol tables)");
568 DysymtabLCI = &LCI;
569 break;
570 default:
571 return Error("unexpected input object (unexpected load command");
572 }
573 }
574
575 if (!SymtabLCI)
576 return Error("no symbol table found in object");
577 if (!SegmentLCI)
578 return Error("no segments found in object");
579
580 // Read and register the symbol table data.
581 InMemoryStruct SymtabLC;
582 Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);
583 if (!SymtabLC)
584 return Error("unable to load symbol table load command");
585 Obj->RegisterStringTable(*SymtabLC);
586
587 // Read the dynamic link-edit information, if present (not present in static
588 // objects).
589 if (DysymtabLCI) {
590 InMemoryStruct DysymtabLC;
591 Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC);
592 if (!DysymtabLC)
593 return Error("unable to load dynamic link-exit load command");
594
595 // FIXME: We don't support anything interesting yet.
596 // if (DysymtabLC->LocalSymbolsIndex != 0)
597 // return Error("NOT YET IMPLEMENTED: local symbol entries");
598 // if (DysymtabLC->ExternalSymbolsIndex != 0)
599 // return Error("NOT YET IMPLEMENTED: non-external symbol entries");
600 // if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries)
601 // return Error("NOT YET IMPLEMENTED: undefined symbol entries");
602 }
603
604 // Load the segment load command.
605 if (SegmentLCI->Command.Type == macho::LCT_Segment) {
606 if (loadSegment32(Obj.get(), SegmentLCI, SymtabLC))
607 return true;
206 void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel,
207 const ObjectFile &Obj,
208 ObjSectionToIDMap &ObjSectionToID,
209 LocalSymbolMap &Symbols,
210 StubMap &Stubs) {
211
212 uint32_t RelType = (uint32_t) (Rel.Type & 0xffffffffL);
213 RelocationValueRef Value;
214 SectionEntry &Section = Sections[Rel.SectionID];
215 uint8_t *Target = Section.Address + Rel.Offset;
216
217 bool isExtern = (RelType >> 27) & 1;
218 if (isExtern) {
219 StringRef TargetName;
220 const SymbolRef &Symbol = Rel.Symbol;
221 Symbol.getName(TargetName);
222 // First look the symbol in object file symbols.
223 LocalSymbolMap::iterator lsi = Symbols.find(TargetName.data());
224 if (lsi != Symbols.end()) {
225 Value.SectionID = lsi->second.first;
226 Value.Addend = lsi->second.second;
227 } else {
228 // Second look the symbol in global symbol table.
229 StringMap::iterator gsi = SymbolTable.find(TargetName.data());
230 if (gsi != SymbolTable.end()) {
231 Value.SectionID = gsi->second.first;
232 Value.Addend = gsi->second.second;
233 } else
234 Value.SymbolName = TargetName.data();
235 }
608236 } else {
609 if (loadSegment64(Obj.get(), SegmentLCI, SymtabLC))
610 return true;
611 }
612
613 // Assign the addresses of the sections from the object so that any
614 // relocations to them get set properly.
615 // FIXME: This is done directly from the client at the moment. We should
616 // default the values to the local storage, at least when the target arch
617 // is the same as the host arch.
618
619 return false;
620 }
621
622 // Assign an address to a symbol name and resolve all the relocations
623 // associated with it.
624 void RuntimeDyldMachO::reassignSectionAddress(unsigned SectionID,
625 uint64_t Addr) {
626 // The address to use for relocation resolution is not
627 // the address of the local section buffer. We must be doing
628 // a remote execution environment of some sort. Re-apply any
629 // relocations referencing this section with the given address.
630 //
631 // Addr is a uint64_t because we can't assume the pointer width
632 // of the target is the same as that of the host. Just use a generic
633 // "big enough" type.
634
635 SectionLoadAddress[SectionID] = Addr;
636
637 RelocationList &Relocs = Relocations[SectionID];
638 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
639 RelocationEntry &RE = Relocs[i];
640 uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset;
641 uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset;
642 bool isPCRel = (RE.Data >> 24) & 1;
643 unsigned Type = (RE.Data >> 28) & 0xf;
644 unsigned Size = 1 << ((RE.Data >> 25) & 3);
645
646 DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID
647 << " + " << RE.Offset << " (" << format("%p", Target) << ")"
648 << " from Section #" << SectionID << " (" << format("%p", Addr) << ")"
649 << "(" << (isPCRel ? "pcrel" : "absolute")
650 << ", type: " << Type << ", Size: " << Size << ", Addend: "
651 << RE.Addend << ").\n");
652
653 resolveRelocation(Target,
654 FinalTarget,
655 Addr,
656 isPCRel,
657 Type,
658 Size,
659 RE.Addend);
660 }
661 ReferrerList &Refers = Referrers[SectionID];
662 for (unsigned i = 0, e = Refers.size(); i != e; ++i) {
663 Referrer &R = Refers[i];
664 RelocationEntry &RE = Relocations[R.SectionID][R.Index];
665 uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset;
666 uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset;
667 bool isPCRel = (RE.Data >> 24) & 1;
668 unsigned Type = (RE.Data >> 28) & 0xf;
669 unsigned Size = 1 << ((RE.Data >> 25) & 3);
670
671 DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID
672 << " + " << RE.Offset << " (" << format("%p", Target) << ")"
673 << " from Section #" << SectionID << " (" << format("%p", Addr) << ")"
674 << "(" << (isPCRel ? "pcrel" : "absolute")
675 << ", type: " << Type << ", Size: " << Size << ", Addend: "
676 << RE.Addend << ").\n");
677
678 resolveRelocation(Target,
679 FinalTarget,
680 Addr,
681 isPCRel,
682 Type,
683 Size,
684 RE.Addend);
685 }
686 }
687
688 bool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) {
237 error_code err;
238 uint8_t sectionIndex = static_cast(RelType & 0xFF);
239 section_iterator si = Obj.begin_sections(),
240 se = Obj.end_sections();
241 for (uint8_t i = 1; i < sectionIndex; i++) {
242 error_code err;
243 si.increment(err);
244 if (si == se)
245 break;
246 }
247 assert(si != se && "No section containing relocation!");
248 Value.SectionID = findOrEmitSection(*si, true, ObjSectionToID);
249 Value.Addend = *(const intptr_t *)Target;
250 if (Value.Addend) {
251 // The MachO addend is offset from the current section, we need set it
252 // as offset from destination section
253 Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress;
254 }
255 }
256
257 if (Arch == Triple::arm && RelType == macho::RIT_ARM_Branch24Bit) {
258 // This is an ARM branch relocation, need to use a stub function.
259
260 // Look up for existing stub.
261 StubMap::const_iterator i = Stubs.find(Value);
262 if (i != Stubs.end())
263 resolveRelocation(Target, (uint64_t)Target,
264 (uint64_t)Section.Address + i->second,
265 RelType, 0);
266 else {
267 // Create a new stub function.
268 Stubs[Value] = Section.StubOffset;
269 uint8_t *StubTargetAddr = createStubFunction(Section.Address +
270 Section.StubOffset);
271 AddRelocation(Value, Rel.SectionID, StubTargetAddr - Section.Address,
272 macho::RIT_Vanilla);
273 resolveRelocation(Target, (uint64_t)Target,
274 (uint64_t)Section.Address + Section.StubOffset,
275 RelType, 0);
276 Section.StubOffset += getMaxStubSize();
277 }
278 } else
279 AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType);
280 }
281
282
283 bool RuntimeDyldMachO::isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
689284 StringRef Magic = InputBuffer->getBuffer().slice(0, 4);
690285 if (Magic == "\xFE\xED\xFA\xCE") return true;
691286 if (Magic == "\xCE\xFA\xED\xFE") return true;
2424
2525 namespace llvm {
2626 class RuntimeDyldMachO : public RuntimeDyldImpl {
27
28 // For each symbol, keep a list of relocations based on it. Anytime
29 // its address is reassigned (the JIT re-compiled the function, e.g.),
30 // the relocations get re-resolved.
31 // The symbol (or section) the relocation is sourced from is the Key
32 // in the relocation list where it's stored.
33 struct RelocationEntry {
34 unsigned SectionID; // Section the relocation is contained in.
35 uint64_t Offset; // Offset into the section for the relocation.
36 uint32_t Data; // Second word of the raw macho relocation entry.
37 int64_t Addend; // Addend encoded in the instruction itself, if any,
38 // plus the offset into the source section for
39 // the symbol once the relocation is resolvable.
40
41 RelocationEntry(unsigned id, uint64_t offset, uint32_t data, int64_t addend)
42 : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
43 };
44 typedef SmallVector RelocationList;
45
46 // For each section, keep a list of referrers in that section that are clients
47 // of relocations in other sections. Whenever a relocation gets created,
48 // create a corresponding referrer. Whenever relocations are re-resolved,
49 // re-resolve the referrers' relocations as well.
50 struct Referrer {
51 unsigned SectionID; // Section whose RelocationList contains the relocation.
52 uint32_t Index; // Index of the RelocatonEntry in that RelocationList.
53
54 Referrer(unsigned id, uint32_t index)
55 : SectionID(id), Index(index) {}
56 };
57 typedef SmallVector ReferrerList;
58
59 // Relocations to sections already loaded. Indexed by SectionID which is the
60 // source of the address. The target where the address will be writen is
61 // SectionID/Offset in the relocation itself.
62 IndexedMap Relocations;
63 // Referrers corresponding to Relocations.
64 IndexedMap Referrers;
65 // Relocations to symbols that are not yet resolved. Must be external
66 // relocations by definition. Indexed by symbol name.
67 StringMap UnresolvedRelocations;
68
69 bool resolveRelocation(uint8_t *LocalAddress,
70 uint64_t FinalAddress,
71 uint64_t Value,
72 bool isPCRel,
73 unsigned Type,
74 unsigned Size,
75 int64_t Addend);
27 protected:
7628 bool resolveI386Relocation(uint8_t *LocalAddress,
7729 uint64_t FinalAddress,
7830 uint64_t Value,
9547 unsigned Size,
9648 int64_t Addend);
9749
98 bool loadSegment32(const MachOObject *Obj,
99 const MachOObject::LoadCommandInfo *SegmentLCI,
100 const InMemoryStruct &SymtabLC);
101 bool loadSegment64(const MachOObject *Obj,
102 const MachOObject::LoadCommandInfo *SegmentLCI,
103 const InMemoryStruct &SymtabLC);
104 bool processSymbols32(const MachOObject *Obj,
105 SmallVectorImpl &SectionMap,
106 SmallVectorImpl &SymbolNames,
107 const InMemoryStruct &SymtabLC);
108 bool processSymbols64(const MachOObject *Obj,
109 SmallVectorImpl &SectionMap,
110 SmallVectorImpl &SymbolNames,
111 const InMemoryStruct &SymtabLC);
112
113 void resolveSymbol(StringRef Name);
50 virtual void processRelocationRef(const ObjRelocationInfo &Rel,
51 const ObjectFile &Obj,
52 ObjSectionToIDMap &ObjSectionToID,
53 LocalSymbolMap &Symbols, StubMap &Stubs);
11454
11555 public:
56 virtual void resolveRelocation(uint8_t *LocalAddress,
57 uint64_t FinalAddress,
58 uint64_t Value,
59 uint32_t Type,
60 int64_t Addend);
61
11662 RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
11763
118 bool loadObject(MemoryBuffer *InputBuffer);
119
120 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
121
122 static bool isKnownFormat(const MemoryBuffer *InputBuffer);
123
124 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
125 return isKnownFormat(InputBuffer);
126 }
64 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
12765 };
12866
12967 } // end namespace llvm
4848 set(ENABLE_ASSERTIONS "0")
4949 endif()
5050
51 set(HOST_OS ${CMAKE_HOST_SYSTEM_NAME})
52
5153 configure_file(
5254 ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
5355 ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 @.LC0 = internal global [10 x i8] c"argc: %d\0A\00" ; <[10 x i8]*> [#uses=1]
3
4 declare i32 @puts(i8*)
5
6 define void @getoptions(i32* %argc) {
7 bb0:
8 ret void
9 }
10
11 declare i32 @printf(i8*, ...)
12
13 define i32 @main(i32 %argc, i8** %argv) {
14 bb0:
15 call i32 (i8*, ...)* @printf( i8* getelementptr ([10 x i8]* @.LC0, i64 0, i64 0), i32 %argc ) ; :0 [#uses=0]
16 %cast224 = bitcast i8** %argv to i8* ; [#uses=1]
17 %local = alloca i8* ; [#uses=3]
18 store i8* %cast224, i8** %local
19 %cond226 = icmp sle i32 %argc, 0 ; [#uses=1]
20 br i1 %cond226, label %bb3, label %bb2
21 bb2: ; preds = %bb2, %bb0
22 %cann-indvar = phi i32 [ 0, %bb0 ], [ %add1-indvar, %bb2 ] ; [#uses=2]
23 %add1-indvar = add i32 %cann-indvar, 1 ; [#uses=2]
24 %cann-indvar-idxcast = sext i32 %cann-indvar to i64 ; [#uses=1]
25 %CT = bitcast i8** %local to i8*** ; [#uses=1]
26 %reg115 = load i8*** %CT ; [#uses=1]
27 %cast235 = getelementptr i8** %reg115, i64 %cann-indvar-idxcast ; [#uses=1]
28 %reg117 = load i8** %cast235 ; [#uses=1]
29 %reg236 = call i32 @puts( i8* %reg117 ) ; [#uses=0]
30 %cond239 = icmp slt i32 %add1-indvar, %argc ; [#uses=1]
31 br i1 %cond239, label %bb2, label %bb3
32 bb3: ; preds = %bb2, %bb0
33 %cast243 = bitcast i8** %local to i32* ; [#uses=1]
34 call void @getoptions( i32* %cast243 )
35 ret i32 0
36 }
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @foo(i32 %X, i32 %Y, double %A) {
3 %cond212 = fcmp une double %A, 1.000000e+00 ; [#uses=1]
4 %cast110 = zext i1 %cond212 to i32 ; [#uses=1]
5 ret i32 %cast110
6 }
7
8 define i32 @main() {
9 %reg212 = call i32 @foo( i32 0, i32 1, double 1.000000e+00 ) ; [#uses=1]
10 ret i32 %reg212
11 }
12
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() {
3 call i32 @mylog( i32 4 ) ; :1 [#uses=0]
4 ret i32 0
5 }
6
7 define internal i32 @mylog(i32 %num) {
8 bb0:
9 br label %bb2
10 bb2: ; preds = %bb2, %bb0
11 %reg112 = phi i32 [ 10, %bb2 ], [ 1, %bb0 ] ; [#uses=1]
12 %cann-indvar = phi i32 [ %cann-indvar, %bb2 ], [ 0, %bb0 ] ; [#uses=1]
13 %reg114 = add i32 %reg112, 1 ; [#uses=2]
14 %cond222 = icmp slt i32 %reg114, %num ; [#uses=1]
15 br i1 %cond222, label %bb2, label %bb3
16 bb3: ; preds = %bb2
17 ret i32 %reg114
18 }
19
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() {
3 ;
4 br label %Loop
5 Loop: ; preds = %Loop, %0
6 %X = phi i32 [ 0, %0 ], [ 1, %Loop ] ; [#uses=1]
7 br i1 true, label %Out, label %Loop
8 Out: ; preds = %Loop
9 ret i32 %X
10 }
11
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 ; We were accidentally inverting the signedness of right shifts. Whoops.
3
4 define i32 @main() {
5 %X = ashr i32 -1, 16 ; [#uses=1]
6 %Y = ashr i32 %X, 16 ; [#uses=1]
7 %Z = add i32 %Y, 1 ; [#uses=1]
8 ret i32 %Z
9 }
10
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() {
3 %X = fadd double 0.000000e+00, 1.000000e+00 ; [#uses=1]
4 %Y = fsub double 0.000000e+00, 1.000000e+00 ; [#uses=2]
5 %Z = fcmp oeq double %X, %Y ; [#uses=0]
6 fadd double %Y, 0.000000e+00 ; :1 [#uses=0]
7 ret i32 0
8 }
9
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @bar(i8* %X) {
3 ; pointer should be 4 byte aligned!
4 %P = alloca double ; [#uses=1]
5 %R = ptrtoint double* %P to i32 ; [#uses=1]
6 %A = and i32 %R, 3 ; [#uses=1]
7 ret i32 %A
8 }
9
10 define i32 @main() {
11 %SP = alloca i8 ; [#uses=1]
12 %X = add i32 0, 0 ; [#uses=1]
13 alloca i8, i32 %X ; :1 [#uses=0]
14 call i32 @bar( i8* %SP ) ; :2 [#uses=1]
15 ret i32 %2
16 }
0 ; This testcase should return with an exit code of 1.
1 ;
2 ; RUN: not %lli -use-mcjit %s
3
4 @test = global i64 0 ; [#uses=1]
5
6 define internal i64 @test.upgrd.1() {
7 %tmp.0 = load i64* @test ; [#uses=1]
8 %tmp.1 = add i64 %tmp.0, 1 ; [#uses=1]
9 ret i64 %tmp.1
10 }
11
12 define i32 @main() {
13 %L = call i64 @test.upgrd.1( ) ; [#uses=1]
14 %I = trunc i64 %L to i32 ; [#uses=1]
15 ret i32 %I
16 }
17
18
0 ; RUN: %lli -use-mcjit %s test
1
2 declare i32 @puts(i8*)
3
4 define i32 @main(i32 %argc.1, i8** %argv.1) {
5 %tmp.5 = getelementptr i8** %argv.1, i64 1 ; [#uses=1]
6 %tmp.6 = load i8** %tmp.5 ; [#uses=1]
7 %tmp.0 = call i32 @puts( i8* %tmp.6 ) ; [#uses=0]
8 ret i32 0
9 }
10
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 target datalayout = "e-p:32:32"
3
4 define i32 @main() {
5 entry:
6 br label %endif
7 then: ; No predecessors!
8 br label %endif
9 endif: ; preds = %then, %entry
10 %x = phi i32 [ 4, %entry ], [ 27, %then ] ; [#uses=0]
11 %result = phi i32 [ 32, %then ], [ 0, %entry ] ; [#uses=0]
12 ret i32 0
13 }
14
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 ; Testcase distilled from 256.bzip2.
3
4 target datalayout = "e-p:32:32"
5
6 define i32 @main() {
7 entry:
8 br label %loopentry.0
9 loopentry.0: ; preds = %loopentry.0, %entry
10 %h.0 = phi i32 [ %tmp.2, %loopentry.0 ], [ -1, %entry ] ; [#uses=1]
11 %tmp.2 = add i32 %h.0, 1 ; [#uses=3]
12 %tmp.4 = icmp ne i32 %tmp.2, 0 ; [#uses=1]
13 br i1 %tmp.4, label %loopentry.0, label %loopentry.1
14 loopentry.1: ; preds = %loopentry.0
15 %h.1 = phi i32 [ %tmp.2, %loopentry.0 ] ; [#uses=1]
16 ret i32 %h.1
17 }
18
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 ; Testcase distilled from 256.bzip2.
3
4 target datalayout = "e-p:32:32"
5
6 define i32 @main() {
7 entry:
8 %X = add i32 1, -1 ; [#uses=3]
9 br label %Next
10 Next: ; preds = %entry
11 %A = phi i32 [ %X, %entry ] ; [#uses=0]
12 %B = phi i32 [ %X, %entry ] ; [#uses=0]
13 %C = phi i32 [ %X, %entry ] ; [#uses=1]
14 ret i32 %C
15 }
16
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 ; This testcase failed to work because two variable sized allocas confused the
3 ; local register allocator.
4
5 define i32 @main(i32 %X) {
6 %A = alloca i32, i32 %X ; [#uses=0]
7 %B = alloca float, i32 %X ; [#uses=0]
8 ret i32 0
9 }
10
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 ;
3 ; Regression Test: EnvironmentTest.ll
4 ;
5 ; Description:
6 ; This is a regression test that verifies that the JIT passes the
7 ; environment to the main() function.
8 ;
9
10
11 declare i32 @strlen(i8*)
12
13 define i32 @main(i32 %argc.1, i8** %argv.1, i8** %envp.1) {
14 %tmp.2 = load i8** %envp.1 ; [#uses=1]
15 %tmp.3 = call i32 @strlen( i8* %tmp.2 ) ; [#uses=1]
16 %T = icmp eq i32 %tmp.3, 0 ; [#uses=1]
17 %R = zext i1 %T to i32 ; [#uses=1]
18 ret i32 %R
19 }
20
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 ; This testcase exposes a bug in the local register allocator where it runs out
3 ; of registers (due to too many overlapping live ranges), but then attempts to
4 ; use the ESP register (which is not allocatable) to hold a value.
5
6 define i32 @main(i32 %A) {
7 ; ESP gets used again...
8 %Ap2 = alloca i32, i32 %A ; [#uses=11]
9 ; Produce lots of overlapping live ranges
10 %B = add i32 %A, 1 ; [#uses=1]
11 %C = add i32 %A, 2 ; [#uses=1]
12 %D = add i32 %A, 3 ; [#uses=1]
13 %E = add i32 %A, 4 ; [#uses=1]
14 %F = add i32 %A, 5 ; [#uses=1]
15 %G = add i32 %A, 6 ; [#uses=1]
16 %H = add i32 %A, 7 ; [#uses=1]
17 %I = add i32 %A, 8 ; [#uses=1]
18 %J = add i32 %A, 9 ; [#uses=1]
19 %K = add i32 %A, 10 ; [#uses=1]
20 ; Uses of all of the values
21 store i32 %A, i32* %Ap2
22 store i32 %B, i32* %Ap2
23 store i32 %C, i32* %Ap2
24 store i32 %D, i32* %Ap2
25 store i32 %E, i32* %Ap2
26 store i32 %F, i32* %Ap2
27 store i32 %G, i32* %Ap2
28 store i32 %H, i32* %Ap2
29 store i32 %I, i32* %Ap2
30 store i32 %J, i32* %Ap2
31 store i32 %K, i32* %Ap2
32 ret i32 0
33 }
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 @A = global i32 0 ; [#uses=1]
3
4 define i32 @main() {
5 %Ret = call i32 @test( i1 true, i32 0 ) ; [#uses=1]
6 ret i32 %Ret
7 }
8
9 define i32 @test(i1 %c, i32 %A) {
10 br i1 %c, label %Taken1, label %NotTaken
11 Cont: ; preds = %Taken1, %NotTaken
12 %V = phi i32 [ 0, %NotTaken ], [ sub (i32 ptrtoint (i32* @A to i32), i32 1234), %Taken1 ] ; [#uses=0]
13 ret i32 0
14 NotTaken: ; preds = %0
15 br label %Cont
16 Taken1: ; preds = %0
17 %B = icmp eq i32 %A, 0 ; [#uses=1]
18 br i1 %B, label %Cont, label %ExitError
19 ExitError: ; preds = %Taken1
20 ret i32 12
21 }
22
0 ; PR672
1 ; RUN: %lli -use-mcjit %s
2 ; XFAIL: mcjit-ia32
3
4 define i32 @main() {
5 %f = bitcast i32 (i32, i32*, i32)* @check_tail to i32* ; [#uses=1]
6 %res = tail call fastcc i32 @check_tail( i32 10, i32* %f, i32 10 ) ; [#uses=1]
7 ret i32 %res
8 }
9
10 define fastcc i32 @check_tail(i32 %x, i32* %f, i32 %g) {
11 %tmp1 = icmp sgt i32 %x, 0 ; [#uses=1]
12 br i1 %tmp1, label %if-then, label %if-else
13 if-then: ; preds = %0
14 %fun_ptr = bitcast i32* %f to i32 (i32, i32*, i32)* ; [#uses=1]
15 %arg1 = add i32 %x, -1 ; [#uses=1]
16 %res = tail call fastcc i32 %fun_ptr( i32 %arg1, i32* %f, i32 %g ) ; [#uses=1]
17 ret i32 %res
18 if-else: ; preds = %0
19 ret i32 %x
20 }
21
0 ; RUN: %lli -use-mcjit -force-interpreter %s
1 ; PR1836
2
3 define i32 @main() {
4 entry:
5 %retval = alloca i32 ; [#uses=2]
6 %tmp = alloca i32 ; [#uses=2]
7 %x = alloca i75, align 16 ; [#uses=1]
8 %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
9 store i75 999, i75* %x, align 16
10 store i32 0, i32* %tmp, align 4
11 %tmp1 = load i32* %tmp, align 4 ; [#uses=1]
12 store i32 %tmp1, i32* %retval, align 4
13 br label %return
14
15 return: ; preds = %entry
16 %retval2 = load i32* %retval ; [#uses=1]
17 ret i32 %retval2
18 }
0 ; RUN: %lli -use-mcjit -force-interpreter=true %s | grep 1
1
2 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
3 target triple = "i686-pc-linux-gnu"
4 @.str = internal constant [10 x i8] c"MSB = %d\0A\00" ; <[10 x i8]*> [#uses=1]
5
6 define i65 @foo(i65 %x) {
7 entry:
8 %x_addr = alloca i65 ; [#uses=2]
9 %retval = alloca i65 ; [#uses=2]
10 %tmp = alloca i65 ; [#uses=2]
11 %"alloca point" = bitcast i65 0 to i65 ; [#uses=0]
12 store i65 %x, i65* %x_addr
13 %tmp1 = load i65* %x_addr, align 4 ; [#uses=1]
14 %tmp2 = ashr i65 %tmp1, 65 ; [#uses=1]
15 store i65 %tmp2, i65* %tmp, align 4
16 %tmp3 = load i65* %tmp, align 4 ; [#uses=1]
17 store i65 %tmp3, i65* %retval, align 4
18 br label %return
19
20 return: ; preds = %entry
21 %retval4 = load i65* %retval ; [#uses=1]
22 ret i65 %retval4
23 }
24
25 define i32 @main() {
26 entry:
27 %retval = alloca i32 ; [#uses=1]
28 %iftmp.0 = alloca i32 ; [#uses=3]
29 %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
30 %tmp = call i65 @foo( i65 -9 ) ; [#uses=1]
31 %tmp1 = lshr i65 %tmp, 64 ; [#uses=1]
32 %tmp2 = xor i65 %tmp1, 1 ; [#uses=1]
33 %tmp3 = and i65 %tmp2, 1 ; [#uses=1]
34 %tmp34 = trunc i65 %tmp3 to i8 ; [#uses=1]
35 %toBool = icmp ne i8 %tmp34, 0 ; [#uses=1]
36 br i1 %toBool, label %cond_true, label %cond_false
37
38 cond_true: ; preds = %entry
39 store i32 0, i32* %iftmp.0, align 4
40 br label %cond_next
41
42 cond_false: ; preds = %entry
43 store i32 1, i32* %iftmp.0, align 4
44 br label %cond_next
45
46 cond_next: ; preds = %cond_false, %cond_true
47 %tmp5 = getelementptr [10 x i8]* @.str, i32 0, i32 0 ; [#uses=1]
48 %tmp6 = load i32* %iftmp.0, align 4 ; [#uses=1]
49 %tmp7 = call i32 (i8*, ...)* @printf( i8* noalias %tmp5, i32 %tmp6 ) nounwind ; [#uses=0]
50 br label %return
51
52 return: ; preds = %cond_next
53 store i32 0, i32* %retval, align 4
54 %retval8 = load i32* %retval ; [#uses=1]
55 ret i32 %retval8
56 }
57
58 declare i32 @printf(i8* noalias , ...) nounwind
0 ; RUN: %lli -use-mcjit -force-interpreter=true %s
1
2 define i32 @main() {
3 %a = add i32 0, undef
4 %b = fadd float 0.0, undef
5 %c = fadd double 0.0, undef
6 ret i32 0
7 }
0 ; RUN: %lli -use-mcjit -force-interpreter=true %s | grep 40091eb8
1 ;
2 define i32 @test(double %x) {
3 entry:
4 %x46.i = bitcast double %x to i64
5 %tmp343.i = lshr i64 %x46.i, 32
6 %tmp344.i = trunc i64 %tmp343.i to i32
7 ret i32 %tmp344.i
8 }
9
10 define i32 @main()
11 {
12 %res = call i32 @test(double 3.14)
13 %ptr = getelementptr [4 x i8]* @format, i32 0, i32 0
14 call i32 (i8*,...)* @printf(i8* %ptr, i32 %res)
15 ret i32 0
16 }
17
18 declare i32 @printf(i8*, ...)
19 @format = internal constant [4 x i8] c"%x\0A\00"
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 @.LC0 = internal global [12 x i8] c"Hello World\00" ; <[12 x i8]*> [#uses=1]
3
4 declare i32 @puts(i8*)
5
6 define i32 @main() {
7 %reg210 = call i32 @puts( i8* getelementptr ([12 x i8]* @.LC0, i64 0, i64 0) ) ; [#uses=0]
8 ret i32 0
9 }
10
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 @X = global i32 7 ; [#uses=0]
3 @msg = internal global [13 x i8] c"Hello World\0A\00" ; <[13 x i8]*> [#uses=1]
4
5 declare void @printf([13 x i8]*, ...)
6
7 define void @bar() {
8 call void ([13 x i8]*, ...)* @printf( [13 x i8]* @msg )
9 ret void
10 }
11
12 define i32 @main() {
13 call void @bar( )
14 ret i32 0
15 }
16
0 config.suffixes = ['.ll', '.c', '.cpp']
1
2 def getRoot(config):
3 if not config.parent:
4 return config
5 return getRoot(config.parent)
6
7 root = getRoot(config)
8
9 targets = set(root.targets_to_build.split())
10 if ('X86' in targets) | ('ARM' in targets):
11 config.unsupported = False
12 else:
13 config.unsupported = True
14
15 if root.host_os in ['Win32', 'Cygwin', 'MingW', 'Windows']:
16 config.unsupported = True
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() {
3 ret i32 0
4 }
5
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @bar() {
3 ret i32 0
4 }
5
6 define i32 @main() {
7 %r = call i32 @bar( ) ; [#uses=1]
8 ret i32 %r
9 }
10
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() {
3 %A = add i8 0, 12 ; [#uses=1]
4 %B = sub i8 %A, 1 ; [#uses=2]
5 %C = mul i8 %B, %B ; [#uses=2]
6 %D = sdiv i8 %C, %C ; [#uses=2]
7 %E = srem i8 %D, %D ; [#uses=0]
8 %F = udiv i8 5, 6 ; [#uses=0]
9 %G = urem i8 6, 5 ; [#uses=0]
10 %A.upgrd.1 = add i16 0, 12 ; [#uses=1]
11 %B.upgrd.2 = sub i16 %A.upgrd.1, 1 ; [#uses=2]
12 %C.upgrd.3 = mul i16 %B.upgrd.2, %B.upgrd.2 ; [#uses=2]
13 %D.upgrd.4 = sdiv i16 %C.upgrd.3, %C.upgrd.3 ; [#uses=2]
14 %E.upgrd.5 = srem i16 %D.upgrd.4, %D.upgrd.4 ; [#uses=0]
15 %F.upgrd.6 = udiv i16 5, 6 ; [#uses=0]
16 %G.upgrd.7 = urem i32 6, 5 ; [#uses=0]
17 %A.upgrd.8 = add i32 0, 12 ; [#uses=1]
18 %B.upgrd.9 = sub i32 %A.upgrd.8, 1 ; [#uses=2]
19 %C.upgrd.10 = mul i32 %B.upgrd.9, %B.upgrd.9 ; [#uses=2]
20 %D.upgrd.11 = sdiv i32 %C.upgrd.10, %C.upgrd.10 ; [#uses=2]
21 %E.upgrd.12 = srem i32 %D.upgrd.11, %D.upgrd.11 ; [#uses=0]
22 %F.upgrd.13 = udiv i32 5, 6 ; [#uses=0]
23 %G1 = urem i32 6, 5 ; [#uses=0]
24 %A.upgrd.14 = add i64 0, 12 ; [#uses=1]
25 %B.upgrd.15 = sub i64 %A.upgrd.14, 1 ; [#uses=2]
26 %C.upgrd.16 = mul i64 %B.upgrd.15, %B.upgrd.15 ; [#uses=2]
27 %D.upgrd.17 = sdiv i64 %C.upgrd.16, %C.upgrd.16 ; [#uses=2]
28 %E.upgrd.18 = srem i64 %D.upgrd.17, %D.upgrd.17 ; [#uses=0]
29 %F.upgrd.19 = udiv i64 5, 6 ; [#uses=0]
30 %G.upgrd.20 = urem i64 6, 5 ; [#uses=0]
31 ret i32 0
32 }
33
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 ; test unconditional branch
3 define i32 @main() {
4 br label %Test
5 Test: ; preds = %Test, %0
6 %X = icmp eq i32 0, 4 ; [#uses=1]
7 br i1 %X, label %Test, label %Label
8 Label: ; preds = %Test
9 ret i32 0
10 }
11
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @_Z14func_exit_codev() nounwind uwtable {
3 entry:
4 ret i32 0
5 }
6
7 define i32 @main() nounwind uwtable {
8 entry:
9 %retval = alloca i32, align 4
10 store i32 0, i32* %retval
11 %call = call i32 @_Z14func_exit_codev()
12 ret i32 %call
13 }
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 declare void @exit(i32)
3
4 define i32 @test(i8 %C, i16 %S) {
5 %X = trunc i16 %S to i8 ; [#uses=1]
6 %Y = zext i8 %X to i32 ; [#uses=1]
7 ret i32 %Y
8 }
9
10 define void @FP(void (i32)* %F) {
11 %X = call i32 @test( i8 123, i16 1024 ) ; [#uses=1]
12 call void %F( i32 %X )
13 ret void
14 }
15
16 define i32 @main() {
17 call void @FP( void (i32)* @exit )
18 ret i32 1
19 }
20
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @foo() {
3 ret i32 0
4 }
5
6 define i32 @main() {
7 icmp ne i1 true, false ; :1 [#uses=0]
8 zext i1 true to i8 ; :2 [#uses=0]
9 zext i1 true to i8 ; :3 [#uses=0]
10 zext i1 true to i16 ; :4 [#uses=0]
11 zext i1 true to i16 ; :5 [#uses=0]
12 zext i1 true to i32 ; :6 [#uses=0]
13 zext i1 true to i32 ; :7 [#uses=0]
14 zext i1 true to i64 ; :8 [#uses=0]
15 zext i1 true to i64 ; :9 [#uses=0]
16 uitofp i1 true to float ; :10 [#uses=0]
17 uitofp i1 true to double ; :11 [#uses=0]
18 icmp ne i8 0, 0 ; :12 [#uses=0]
19 icmp ne i8 1, 0 ; :13 [#uses=0]
20 bitcast i8 0 to i8 ; :14 [#uses=0]
21 bitcast i8 -1 to i8 ; :15 [#uses=0]
22 sext i8 4 to i16 ; :16 [#uses=0]
23 sext i8 4 to i16 ; :17 [#uses=0]
24 sext i8 4 to i64 ; :18 [#uses=0]
25 sext i8 4 to i64 ; :19 [#uses=0]
26 sitofp i8 4 to float ; :20 [#uses=0]
27 sitofp i8 4 to double ; :21 [#uses=0]
28 icmp ne i8 0, 0 ; :22 [#uses=0]
29 icmp ne i8 1, 0 ; :23 [#uses=0]
30 bitcast i8 0 to i8 ; :24 [#uses=0]
31 bitcast i8 1 to i8 ; :25 [#uses=0]
32 zext i8 4 to i16 ; :26 [#uses=0]
33 zext i8 4 to i16 ; :27 [#uses=0]
34 zext i8 4 to i64 ; :28 [#uses=0]
35 zext i8 4 to i64 ; :29 [#uses=0]
36 uitofp i8 0 to float ; :30 [#uses=0]
37 uitofp i8 0 to double ; :31 [#uses=0]
38 icmp ne i16 1, 0 ; :32 [#uses=0]
39 trunc i16 -1 to i8 ; :33 [#uses=0]
40 trunc i16 255 to i8 ; :34 [#uses=0]
41 bitcast i16 0 to i16 ; :35 [#uses=0]
42 bitcast i16 0 to i16 ; :36 [#uses=0]
43 sext i16 0 to i64 ; :37 [#uses=0]
44 sext i16 0 to i64 ; :38 [#uses=0]
45 sitofp i16 0 to float ; :39 [#uses=0]
46 sitofp i16 0 to double ; :40 [#uses=0]
47 icmp ne i16 1, 0 ; :41 [#uses=0]
48 trunc i16 1 to i8 ; :42 [#uses=0]
49 trunc i16 255 to i8 ; :43 [#uses=0]
50 bitcast i16 0 to i16 ; :44 [#uses=0]
51 bitcast i16 0 to i16 ; :45 [#uses=0]
52 zext i16 0 to i64 ; :46 [#uses=0]
53 zext i16 0 to i64 ; :47 [#uses=0]
54 uitofp i16 0 to float ; :48 [#uses=0]
55 uitofp i16 0 to double ; :49 [#uses=0]
56 icmp ne i32 6, 0 ; :50 [#uses=0]
57 trunc i32 -6 to i8 ; :51 [#uses=0]
58 trunc i32 6 to i8 ; :52 [#uses=0]
59 trunc i32 6 to i16 ; :53 [#uses=0]
60 bitcast i32 0 to i32 ; :54 [#uses=0]
61 sext i32 0 to i64 ; :55 [#uses=0]
62 sext i32 0 to i64 ; :56 [#uses=0]
63 sitofp i32 0 to float ; :57 [#uses=0]
64 sitofp i32 0 to double ; :58 [#uses=0]
65 icmp ne i32 6, 0 ; :59 [#uses=0]
66 trunc i32 7 to i8 ; :60 [#uses=0]
67 trunc i32 8 to i8 ; :61 [#uses=0]
68 trunc i32 9 to i16 ; :62 [#uses=0]
69 bitcast i32 10 to i32 ; :63 [#uses=0]
70 zext i32 0 to i64 ; :64 [#uses=0]
71 zext i32 0 to i64 ; :65 [#uses=0]
72 uitofp i32 0 to float ; :66 [#uses=0]
73 uitofp i32 0 to double ; :67 [#uses=0]
74 icmp ne i64 0, 0 ; :68 [#uses=0]
75 trunc i64 0 to i8 ; :69 [#uses=0]
76 trunc i64 0 to i8 ; :70 [#uses=0]
77 trunc i64 0 to i16 ; :71 [#uses=0]
78 trunc i64 0 to i16 ; :72 [#uses=0]
79 trunc i64 0 to i32 ; :73 [#uses=0]
80 trunc i64 0 to i32 ; :74 [#uses=0]
81 bitcast i64 0 to i64 ; :75 [#uses=0]
82 bitcast i64 0 to i64 ; :76 [#uses=0]
83 sitofp i64 0 to float ; :77 [#uses=0]
84 sitofp i64 0 to double ; :78 [#uses=0]
85 icmp ne i64 1, 0 ; :79 [#uses=0]
86 trunc i64 1 to i8 ; :80 [#uses=0]
87 trunc i64 1 to i8 ; :81 [#uses=0]
88 trunc i64 1 to i16 ; :82 [#uses=0]
89 trunc i64 1 to i16 ; :83 [#uses=0]
90 trunc i64 1 to i32 ; :84 [#uses=0]
91 trunc i64 1 to i32 ; :85 [#uses=0]
92 bitcast i64 1 to i64 ; :86 [#uses=0]
93 bitcast i64 1 to i64 ; :87 [#uses=0]
94 uitofp i64 1 to float ; :88 [#uses=0]
95 uitofp i64 0 to double ; :89 [#uses=0]
96 bitcast float 0.000000e+00 to float ; :90 [#uses=0]
97 fpext float 0.000000e+00 to double ; :91 [#uses=0]
98 fptosi double 0.000000e+00 to i8 ; :92 [#uses=0]
99 fptoui double 0.000000e+00 to i8 ; :93 [#uses=0]
100 fptosi double 0.000000e+00 to i16 ; :94 [#uses=0]
101 fptoui double 0.000000e+00 to i16 ; :95 [#uses=0]
102 fptosi double 0.000000e+00 to i32 ; :96 [#uses=0]
103 fptoui double 0.000000e+00 to i32 ; :97 [#uses=0]
104 fptosi double 0.000000e+00 to i64 ; :98 [#uses=0]
105 fptrunc double 0.000000e+00 to float ; :99 [#uses=0]
106 bitcast double 0.000000e+00 to double ; :100 [#uses=0]
107 ret i32 0
108 }
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 ; This tests to make sure that we can evaluate weird constant expressions
3
4 @A = global i32 5 ; [#uses=1]
5 @B = global i32 6 ; [#uses=1]
6
7 define i32 @main() {
8 %A = or i1 false, icmp slt (i32* @A, i32* @B) ; [#uses=0]
9 ret i32 0
10 }
11
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define double @test(double* %DP, double %Arg) {
3 %D = load double* %DP ; [#uses=1]
4 %V = fadd double %D, 1.000000e+00 ; [#uses=2]
5 %W = fsub double %V, %V ; [#uses=3]
6 %X = fmul double %W, %W ; [#uses=2]
7 %Y = fdiv double %X, %X ; [#uses=2]
8 %Q = fadd double %Y, %Arg ; [#uses=1]
9 %R = bitcast double %Q to double ; [#uses=1]
10 store double %Q, double* %DP
11 ret double %Y
12 }
13
14 define i32 @main() {
15 %X = alloca double ; [#uses=2]
16 store double 0.000000e+00, double* %X
17 call double @test( double* %X, double 2.000000e+00 ) ; :1 [#uses=0]
18 ret i32 0
19 }
20
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define double @test(double* %DP, double %Arg) {
3 %D = load double* %DP ; [#uses=1]
4 %V = fadd double %D, 1.000000e+00 ; [#uses=2]
5 %W = fsub double %V, %V ; [#uses=3]
6 %X = fmul double %W, %W ; [#uses=2]
7 %Y = fdiv double %X, %X ; [#uses=2]
8 %Z = frem double %Y, %Y ; [#uses=3]
9 %Z1 = fdiv double %Z, %W ; [#uses=0]
10 %Q = fadd double %Z, %Arg ; [#uses=1]
11 %R = bitcast double %Q to double ; [#uses=1]
12 store double %R, double* %DP
13 ret double %Z
14 }
15
16 define i32 @main() {
17 %X = alloca double ; [#uses=2]
18 store double 0.000000e+00, double* %X
19 call double @test( double* %X, double 2.000000e+00 ) ; :1 [#uses=0]
20 ret i32 0
21 }
22
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 @count = global i32 1, align 4
3
4 define i32 @main() nounwind uwtable {
5 entry:
6 %retval = alloca i32, align 4
7 %i = alloca i32, align 4
8 store i32 0, i32* %retval
9 store i32 0, i32* %i, align 4
10 br label %for.cond
11
12 for.cond: ; preds = %for.inc, %entry
13 %0 = load i32* %i, align 4
14 %cmp = icmp slt i32 %0, 49
15 br i1 %cmp, label %for.body, label %for.end
16
17 for.body: ; preds = %for.cond
18 %1 = load i32* @count, align 4
19 %inc = add nsw i32 %1, 1
20 store i32 %inc, i32* @count, align 4
21 br label %for.inc
22
23 for.inc: ; preds = %for.body
24 %2 = load i32* %i, align 4
25 %inc1 = add nsw i32 %2, 1
26 store i32 %inc1, i32* %i, align 4
27 br label %for.cond
28
29 for.end: ; preds = %for.cond
30 %3 = load i32* @count, align 4
31 %sub = sub nsw i32 %3, 50
32 ret i32 %sub
33 }
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define void @test(i8* %P, i16* %P.upgrd.1, i32* %P.upgrd.2, i64* %P.upgrd.3) {
3 %V = load i8* %P ; [#uses=1]
4 store i8 %V, i8* %P
5 %V.upgrd.4 = load i16* %P.upgrd.1 ; [#uses=1]
6 store i16 %V.upgrd.4, i16* %P.upgrd.1
7 %V.upgrd.5 = load i32* %P.upgrd.2 ; [#uses=1]
8 store i32 %V.upgrd.5, i32* %P.upgrd.2
9 %V.upgrd.6 = load i64* %P.upgrd.3 ; [#uses=1]
10 store i64 %V.upgrd.6, i64* %P.upgrd.3
11 ret void
12 }
13
14 define i32 @varalloca(i32 %Size) {
15 ;; Variable sized alloca
16 %X = alloca i32, i32 %Size ; [#uses=2]
17 store i32 %Size, i32* %X
18 %Y = load i32* %X ; [#uses=1]
19 ret i32 %Y
20 }
21
22 define i32 @main() {
23 %A = alloca i8 ; [#uses=1]
24 %B = alloca i16 ; [#uses=1]
25 %C = alloca i32 ; [#uses=1]
26 %D = alloca i64 ; [#uses=1]
27 call void @test( i8* %A, i16* %B, i32* %C, i64* %D )
28 call i32 @varalloca( i32 7 ) ; :1 [#uses=0]
29 ret i32 0
30 }
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() nounwind uwtable {
3 entry:
4 %retval = alloca i32, align 4
5 %count = alloca i32, align 4
6 %i = alloca i32, align 4
7 store i32 0, i32* %retval
8 store i32 0, i32* %count, align 4
9 store i32 0, i32* %i, align 4
10 br label %for.cond
11
12 for.cond: ; preds = %for.inc, %entry
13 %0 = load i32* %i, align 4
14 %cmp = icmp slt i32 %0, 50
15 br i1 %cmp, label %for.body, label %for.end
16
17 for.body: ; preds = %for.cond
18 %1 = load i32* %count, align 4
19 %inc = add nsw i32 %1, 1
20 store i32 %inc, i32* %count, align 4
21 br label %for.inc
22
23 for.inc: ; preds = %for.body
24 %2 = load i32* %i, align 4
25 %inc1 = add nsw i32 %2, 1
26 store i32 %inc1, i32* %i, align 4
27 br label %for.cond
28
29 for.end: ; preds = %for.cond
30 %3 = load i32* %count, align 4
31 %sub = sub nsw i32 %3, 50
32 ret i32 %sub
33 }
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() {
3 %A = and i8 4, 8 ; [#uses=2]
4 %B = or i8 %A, 7 ; [#uses=1]
5 %C = xor i8 %B, %A ; [#uses=0]
6 %A.upgrd.1 = and i16 4, 8 ; [#uses=2]
7 %B.upgrd.2 = or i16 %A.upgrd.1, 7 ; [#uses=1]
8 %C.upgrd.3 = xor i16 %B.upgrd.2, %A.upgrd.1 ; [#uses=0]
9 %A.upgrd.4 = and i32 4, 8 ; [#uses=2]
10 %B.upgrd.5 = or i32 %A.upgrd.4, 7 ; [#uses=1]
11 %C.upgrd.6 = xor i32 %B.upgrd.5, %A.upgrd.4 ; [#uses=0]
12 %A.upgrd.7 = and i64 4, 8 ; [#uses=2]
13 %B.upgrd.8 = or i64 %A.upgrd.7, 7 ; [#uses=1]
14 %C.upgrd.9 = xor i64 %B.upgrd.8, %A.upgrd.7 ; [#uses=0]
15 ret i32 0
16 }
17
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() {
3 ;
4 br label %Loop
5 Loop: ; preds = %Loop, %0
6 %I = phi i32 [ 0, %0 ], [ %i2, %Loop ] ; [#uses=1]
7 %i2 = add i32 %I, 1 ; [#uses=2]
8 %C = icmp eq i32 %i2, 10 ; [#uses=1]
9 br i1 %C, label %Out, label %Loop
10 Out: ; preds = %Loop
11 ret i32 0
12 }
13
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 ; test phi node
3 @Y = global i32 6 ; [#uses=1]
4
5 define void @blah(i32* %X) {
6 ;
7 br label %T
8 T: ; preds = %Dead, %0
9 phi i32* [ %X, %0 ], [ @Y, %Dead ] ; :1 [#uses=0]
10 ret void
11 Dead: ; No predecessors!
12 br label %T
13 }
14
15 define i32 @test(i1 %C) {
16 ;
17 br i1 %C, label %T, label %T
18 T: ; preds = %0, %0
19 %X = phi i32 [ 123, %0 ], [ 123, %0 ] ; [#uses=1]
20 ret i32 %X
21 }
22
23 define i32 @main() {
24 ;
25 br label %Test
26 Test: ; preds = %Dead, %0
27 %X = phi i32 [ 0, %0 ], [ %Y, %Dead ] ; [#uses=1]
28 ret i32 %X
29 Dead: ; No predecessors!
30 %Y = ashr i32 12, 4 ; [#uses=1]
31 br label %Test
32 }
33
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 ; test return instructions
3 define void @test1() {
4 ret void
5 }
6
7 define i8 @test2() {
8 ret i8 1
9 }
10
11 define i8 @test3() {
12 ret i8 1
13 }
14
15 define i16 @test4() {
16 ret i16 -1
17 }
18
19 define i16 @test5() {
20 ret i16 -1
21 }
22
23 define i32 @main() {
24 ret i32 0
25 }
26
27 define i32 @test6() {
28 ret i32 4
29 }
30
31 define i64 @test7() {
32 ret i64 0
33 }
34
35 define i64 @test8() {
36 ret i64 0
37 }
38
39 define float @test9() {
40 ret float 1.000000e+00
41 }
42
43 define double @test10() {
44 ret double 2.000000e+00
45 }
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() nounwind uwtable {
3 entry:
4 %retval = alloca i32, align 4
5 store i32 0, i32* %retval
6 ret i32 0
7 }
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2
3 define i32 @main() {
4 %double1 = fadd double 0.000000e+00, 0.000000e+00 ; [#uses=6]
5 %double2 = fadd double 0.000000e+00, 0.000000e+00 ; [#uses=6]
6 %float1 = fadd float 0.000000e+00, 0.000000e+00 ; [#uses=6]
7 %float2 = fadd float 0.000000e+00, 0.000000e+00 ; [#uses=6]
8 %test49 = fcmp oeq float %float1, %float2 ; [#uses=0]
9 %test50 = fcmp oge float %float1, %float2 ; [#uses=0]
10 %test51 = fcmp ogt float %float1, %float2 ; [#uses=0]
11 %test52 = fcmp ole float %float1, %float2 ; [#uses=0]
12 %test53 = fcmp olt float %float1, %float2 ; [#uses=0]
13 %test54 = fcmp une float %float1, %float2 ; [#uses=0]
14 %test55 = fcmp oeq double %double1, %double2 ; [#uses=0]
15 %test56 = fcmp oge double %double1, %double2 ; [#uses=0]
16 %test57 = fcmp ogt double %double1, %double2 ; [#uses=0]
17 %test58 = fcmp ole double %double1, %double2 ; [#uses=0]
18 %test59 = fcmp olt double %double1, %double2 ; [#uses=0]
19 %test60 = fcmp une double %double1, %double2 ; [#uses=0]
20 ret i32 0
21 }
22
23
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() {
3 %int1 = add i32 0, 0 ; [#uses=6]
4 %int2 = add i32 0, 0 ; [#uses=6]
5 %long1 = add i64 0, 0 ; [#uses=6]
6 %long2 = add i64 0, 0 ; [#uses=6]
7 %sbyte1 = add i8 0, 0 ; [#uses=6]
8 %sbyte2 = add i8 0, 0 ; [#uses=6]
9 %short1 = add i16 0, 0 ; [#uses=6]
10 %short2 = add i16 0, 0 ; [#uses=6]
11 %ubyte1 = add i8 0, 0 ; [#uses=6]
12 %ubyte2 = add i8 0, 0 ; [#uses=6]
13 %uint1 = add i32 0, 0 ; [#uses=6]
14 %uint2 = add i32 0, 0 ; [#uses=6]
15 %ulong1 = add i64 0, 0 ; [#uses=6]
16 %ulong2 = add i64 0, 0 ; [#uses=6]
17 %ushort1 = add i16 0, 0 ; [#uses=6]
18 %ushort2 = add i16 0, 0 ; [#uses=6]
19 %test1 = icmp eq i8 %ubyte1, %ubyte2 ; [#uses=0]
20 %test2 = icmp uge i8 %ubyte1, %ubyte2 ; [#uses=0]
21 %test3 = icmp ugt i8 %ubyte1, %ubyte2 ; [#uses=0]
22 %test4 = icmp ule i8 %ubyte1, %ubyte2 ; [#uses=0]
23 %test5 = icmp ult i8 %ubyte1, %ubyte2 ; [#uses=0]
24 %test6 = icmp ne i8 %ubyte1, %ubyte2 ; [#uses=0]
25 %test7 = icmp eq i16 %ushort1, %ushort2 ; [#uses=0]
26 %test8 = icmp uge i16 %ushort1, %ushort2 ; [#uses=0]
27 %test9 = icmp ugt i16 %ushort1, %ushort2 ; [#uses=0]
28 %test10 = icmp ule i16 %ushort1, %ushort2 ; [#uses=0]
29 %test11 = icmp ult i16 %ushort1, %ushort2 ; [#uses=0]
30 %test12 = icmp ne i16 %ushort1, %ushort2 ; [#uses=0]
31 %test13 = icmp eq i32 %uint1, %uint2 ; [#uses=0]
32 %test14 = icmp uge i32 %uint1, %uint2 ; [#uses=0]
33 %test15 = icmp ugt i32 %uint1, %uint2 ; [#uses=0]
34 %test16 = icmp ule i32 %uint1, %uint2 ; [#uses=0]
35 %test17 = icmp ult i32 %uint1, %uint2 ; [#uses=0]
36 %test18 = icmp ne i32 %uint1, %uint2 ; [#uses=0]
37 %test19 = icmp eq i64 %ulong1, %ulong2 ; [#uses=0]
38 %test20 = icmp uge i64 %ulong1, %ulong2 ; [#uses=0]
39 %test21 = icmp ugt i64 %ulong1, %ulong2 ; [#uses=0]
40 %test22 = icmp ule i64 %ulong1, %ulong2 ; [#uses=0]
41 %test23 = icmp ult i64 %ulong1, %ulong2 ; [#uses=0]
42 %test24 = icmp ne i64 %ulong1, %ulong2 ; [#uses=0]
43 %test25 = icmp eq i8 %sbyte1, %sbyte2 ; [#uses=0]
44 %test26 = icmp sge i8 %sbyte1, %sbyte2 ; [#uses=0]
45 %test27 = icmp sgt i8 %sbyte1, %sbyte2 ; [#uses=0]
46 %test28 = icmp sle i8 %sbyte1, %sbyte2 ; [#uses=0]
47 %test29 = icmp slt i8 %sbyte1, %sbyte2 ; [#uses=0]
48 %test30 = icmp ne i8 %sbyte1, %sbyte2 ; [#uses=0]
49 %test31 = icmp eq i16 %short1, %short2 ; [#uses=0]
50 %test32 = icmp sge i16 %short1, %short2 ; [#uses=0]
51 %test33 = icmp sgt i16 %short1, %short2 ; [#uses=0]
52 %test34 = icmp sle i16 %short1, %short2 ; [#uses=0]
53 %test35 = icmp slt i16 %short1, %short2 ; [#uses=0]
54 %test36 = icmp ne i16 %short1, %short2 ; [#uses=0]
55 %test37 = icmp eq i32 %int1, %int2 ; [#uses=0]
56 %test38 = icmp sge i32 %int1, %int2 ; [#uses=0]
57 %test39 = icmp sgt i32 %int1, %int2 ; [#uses=0]
58 %test40 = icmp sle i32 %int1, %int2 ; [#uses=0]
59 %test41 = icmp slt i32 %int1, %int2 ; [#uses=0]
60 %test42 = icmp ne i32 %int1, %int2 ; [#uses=0]
61 %test43 = icmp eq i64 %long1, %long2 ; [#uses=0]
62 %test44 = icmp sge i64 %long1, %long2 ; [#uses=0]
63 %test45 = icmp sgt i64 %long1, %long2 ; [#uses=0]
64 %test46 = icmp sle i64 %long1, %long2 ; [#uses=0]
65 %test47 = icmp slt i64 %long1, %long2 ; [#uses=0]
66 %test48 = icmp ne i64 %long1, %long2 ; [#uses=0]
67 ret i32 0
68 }
0 ; RUN: %lli -use-mcjit %s > /dev/null
1
2 define i32 @main() {
3 %shamt = add i8 0, 1 ; [#uses=8]
4 %shift.upgrd.1 = zext i8 %shamt to i32 ; [#uses=1]
5 %t1.s = shl i32 1, %shift.upgrd.1 ; [#uses=0]
6 %t2.s = shl i32 1, 4 ; [#uses=0]
7 %shift.upgrd.2 = zext i8 %shamt to i32 ; [#uses=1]
8 %t1 = shl i32 1, %shift.upgrd.2 ; [#uses=0]
9 %t2 = shl i32 1, 5 ; [#uses=0]
10 %t2.s.upgrd.3 = shl i64 1, 4 ; [#uses=0]
11 %t2.upgrd.4 = shl i64 1, 5 ; [#uses=0]
12 %shift.upgrd.5 = zext i8 %shamt to i32 ; [#uses=1]
13 %tr1.s = ashr i32 1, %shift.upgrd.5 ; [#uses=0]
14 %tr2.s = ashr i32 1, 4 ; [#uses=0]
15 %shift.upgrd.6 = zext i8 %shamt to i32 ; [#uses=1]
16 %tr1 = lshr i32 1, %shift.upgrd.6 ; [#uses=0]
17 %tr2 = lshr i32 1, 5 ; [#uses=0]
18 %tr1.l = ashr i64 1, 4 ; [#uses=0]
19 %shift.upgrd.7 = zext i8 %shamt to i64 ; [#uses=1]
20 %tr2.l = ashr i64 1, %shift.upgrd.7 ; [#uses=0]
21 %tr3.l = shl i64 1, 4 ; [#uses=0]
22 %shift.upgrd.8 = zext i8 %shamt to i64 ; [#uses=1]
23 %tr4.l = shl i64 1, %shift.upgrd.8 ; [#uses=0]
24 %tr1.u = lshr i64 1, 5 ; [#uses=0]
25 %shift.upgrd.9 = zext i8 %shamt to i64 ; [#uses=1]
26 %tr2.u = lshr i64 1, %shift.upgrd.9 ; [#uses=0]
27 %tr3.u = shl i64 1, 5 ; [#uses=0]
28 %shift.upgrd.10 = zext i8 %shamt to i64 ; [#uses=1]
29 %tr4.u = shl i64 1, %shift.upgrd.10 ; [#uses=0]
30 ret i32 0
31 }
170170 @$(ECHOPATH) s=@ENABLE_ASSERTIONS@=$(ENABLE_ASSERTIONS)=g >> lit.tmp
171171 @$(ECHOPATH) s=@TARGETS_TO_BUILD@=$(TARGETS_TO_BUILD)=g >> lit.tmp
172172 @$(ECHOPATH) s=@LLVM_BINDINGS@=$(BINDINGS_TO_BUILD)=g >> lit.tmp
173 @$(ECHOPATH) s=@HOST_OS@=$(HOST_OS)=g >> lit.tmp
173174 @sed -f lit.tmp $(PROJ_SRC_DIR)/lit.site.cfg.in > $@
174175 @-rm -f lit.tmp
175176
183184 @$(ECHOPATH) s=@ENABLE_SHARED@=$(ENABLE_SHARED)=g >> unit.tmp
184185 @$(ECHOPATH) s=@SHLIBDIR@=$(SharedLibDir)=g >> unit.tmp
185186 @$(ECHOPATH) s=@SHLIBPATH_VAR@=$(SHLIBPATH_VAR)=g >> unit.tmp
187 @$(ECHOPATH) s=@HOST_OS@=$(HOST_OS)=g >> unit.tmp
186188 @sed -f unit.tmp $(PROJ_SRC_DIR)/Unit/lit.site.cfg.in > $@
187189 @-rm -f unit.tmp
88 config.enable_assertions = @ENABLE_ASSERTIONS@
99 config.targets_to_build = "@TARGETS_TO_BUILD@"
1010 config.llvm_bindings = "@LLVM_BINDINGS@"
11 config.host_os = "@HOST_OS@"
1112
1213 # Support substitution of the tools_dir with user parameters. This is
1314 # used when we can't determine the tool dir at configuration time.
5757 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
5858 unsigned SectionID);
5959
60 uint8_t *startFunctionBody(const char *Name, uintptr_t &Size);
61 void endFunctionBody(const char *Name, uint8_t *FunctionStart,
62 uint8_t *FunctionEnd);
63
6460 virtual void *getPointerToNamedFunction(const std::string &Name,
6561 bool AbortOnFailure = true) {
6662 return 0;
7874 unsigned Alignment,
7975 unsigned SectionID) {
8076 return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base();
81 }
82
83 uint8_t *TrivialMemoryManager::startFunctionBody(const char *Name,
84 uintptr_t &Size) {
85 return (uint8_t*)sys::Memory::AllocateRWX(Size, 0, 0).base();
86 }
87
88 void TrivialMemoryManager::endFunctionBody(const char *Name,
89 uint8_t *FunctionStart,
90 uint8_t *FunctionEnd) {
91 uintptr_t Size = FunctionEnd - FunctionStart + 1;
92 FunctionMemory.push_back(sys::MemoryBlock(FunctionStart, Size));
9377 }
9478
9579 static const char *ProgramName;