llvm.org GIT mirror llvm / 799184d
Re-factored RuntimeDyld. Added ExecutionEngine/MCJIT tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153221 91177308-0d34-0410-b5e6-96231b3b80d8 Danil Malyshev 7 years ago
56 changed file(s) with 1840 addition(s) and 1088 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;
49
6050 };
6151
6252 class RuntimeDyld {
3232
3333 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
3434 unsigned SectionID) {
35 return JMM->allocateDataSection(Size, Alignment, SectionID);
35 return JMM->allocateSpace(Size, Alignment);
3636 }
3737
3838 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
3939 unsigned SectionID) {
40 return JMM->allocateCodeSection(Size, Alignment, SectionID);
40 return JMM->allocateSpace(Size, Alignment);
4141 }
4242
4343 virtual void *getPointerToNamedFunction(const std::string &Name,
4545 return JMM->getPointerToNamedFunction(Name, AbortOnFailure);
4646 }
4747
48 // Allocate ActualSize bytes, or more, for the named function. Return
49 // a pointer to the allocated memory and update Size to reflect how much
50 // memory was acutally allocated.
51 uint8_t *startFunctionBody(const char *Name, uintptr_t &Size) {
52 // FIXME: This should really reference the MCAsmInfo to get the global
53 // prefix.
54 if (Name[0] == '_') ++Name;
55 Function *F = M->getFunction(Name);
56 // Some ObjC names have a prefixed \01 in the IR. If we failed to find
57 // the symbol and it's of the ObjC conventions (starts with "-" or
58 // "+"), try prepending a \01 and see if we can find it that way.
59 if (!F && (Name[0] == '-' || Name[0] == '+'))
60 F = M->getFunction((Twine("\1") + Name).str());
61 assert(F && "No matching function in JIT IR Module!");
62 return JMM->startFunctionBody(F, Size);
63 }
64
65 // Mark the end of the function, including how much of the allocated
66 // memory was actually used.
67 void endFunctionBody(const char *Name, uint8_t *FunctionStart,
68 uint8_t *FunctionEnd) {
69 // FIXME: This should really reference the MCAsmInfo to get the global
70 // prefix.
71 if (Name[0] == '_') ++Name;
72 Function *F = M->getFunction(Name);
73 // Some ObjC names have a prefixed \01 in the IR. If we failed to find
74 // the symbol and it's of the ObjC conventions (starts with "-" or
75 // "+"), try prepending a \01 and see if we can find it that way.
76 if (!F && (Name[0] == '-' || Name[0] == '+'))
77 F = M->getFunction((Twine("\1") + Name).str());
78 assert(F && "No matching function in JIT IR Module!");
79 JMM->endFunctionBody(F, FunctionStart, FunctionEnd);
80 }
81
8248 };
8349
8450 } // 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
4929
5030 // Resolve the relocations for all symbols we currently know about.
5131 void RuntimeDyldImpl::resolveRelocations() {
32 // First, resolve relocations assotiated with external symbols.
33 resolveSymbols();
34
5235 // Just iterate over the sections we have and resolve all the relocations
5336 // in them. Gross overkill, but it gets the job done.
5437 for (int i = 0, e = Sections.size(); i != e; ++i) {
55 reassignSectionAddress(i, SectionLoadAddress[i]);
38 reassignSectionAddress(i, Sections[i].LoadAddress);
5639 }
5740 }
5841
5942 void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress,
6043 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 }
44 for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
45 if (Sections[i].Address == LocalAddress) {
46 reassignSectionAddress(i, TargetAddress);
47 return;
48 }
49 }
50 llvm_unreachable("Attempting to remap address of unknown section!");
51 }
52
53 bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
54 // FIXME: ObjectFile don't modify MemoryBuffer.
55 // It should use const MemoryBuffer as parameter.
56 ObjectFile *obj = ObjectFile::
57 createObjectFile(const_cast(InputBuffer));
58
59 Arch = (Triple::ArchType)obj->getArch();
60
61 LocalSymbolMap LocalSymbols; // Functions and data symbols from the
62 // object file.
63 ObjSectionToIDMap LocalSections; // Used sections from the object file
64
65 error_code err;
66
67
68 // Parse symbols
69 DEBUG(dbgs() << "Parse symbols:\n");
70 for (symbol_iterator it = obj->begin_symbols(), itEnd = obj->end_symbols();
71 it != itEnd; it.increment(err)) {
72 if (err) break;
73 object::SymbolRef::Type SymType;
74 StringRef Name;
75 if ((bool)(err = it->getType(SymType))) break;
76 if ((bool)(err = it->getName(Name))) break;
77
78 if (SymType == object::SymbolRef::ST_Function ||
79 SymType == object::SymbolRef::ST_Data) {
80 uint64_t FileOffset;
81 uint32_t flags;
82 StringRef sData;
83 section_iterator sIt = obj->end_sections();
84 if ((bool)(err = it->getFileOffset(FileOffset))) break;
85 if ((bool)(err = it->getFlags(flags))) break;
86 if ((bool)(err = it->getSection(sIt))) break;
87 if (sIt == obj->end_sections()) continue;
88 if ((bool)(err = sIt->getContents(sData))) break;
89 const uint8_t* SymPtr = (const uint8_t*)InputBuffer->getBufferStart() +
90 (uintptr_t)FileOffset;
91 uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)sData.begin());
92 unsigned SectionID =
93 findOrEmitSection(*sIt,
94 SymType == object::SymbolRef::ST_Function,
95 LocalSections);
96 bool isGlobal = flags & SymbolRef::SF_Global;
97 LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset);
98 DEBUG(dbgs() << "\tFileOffset: " << format("%p", (uintptr_t)FileOffset)
99 << " flags: " << flags
100 << " SID: " << SectionID
101 << " Offset: " << format("%p", SectOffset));
102 if (isGlobal)
103 SymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
104 }
105 DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n");
106 }
107 if (err) {
108 report_fatal_error(err.message());
109 }
110
111 // Parse and proccess relocations
112 DEBUG(dbgs() << "Parse relocations:\n");
113 for (section_iterator sIt = obj->begin_sections(),
114 sItEnd = obj->end_sections(); sIt != sItEnd; sIt.increment(err)) {
115 if (err) break;
116 bool isFirstRelocation = true;
117 unsigned SectionID = 0;
118 StubMap Stubs;
119
120 for (relocation_iterator it = sIt->begin_relocations(),
121 itEnd = sIt->end_relocations(); it != itEnd; it.increment(err)) {
122 if (err) break;
123
124 // If it's first relocation in this section, find its SectionID
125 if (isFirstRelocation) {
126 SectionID = findOrEmitSection(*sIt, true, LocalSections);
127 DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
128 isFirstRelocation = false;
129 }
130
131 ObjRelocationInfo RI;
132 RI.SectionID = SectionID;
133 if ((bool)(err = it->getAdditionalInfo(RI.AdditionalInfo))) break;
134 if ((bool)(err = it->getOffset(RI.Offset))) break;
135 if ((bool)(err = it->getSymbol(RI.Symbol))) break;
136 if ((bool)(err = it->getType(RI.Type))) break;
137
138 DEBUG(dbgs() << "\t\tAddend: " << RI.AdditionalInfo
139 << " Offset: " << format("%p", (uintptr_t)RI.Offset)
140 << " Type: " << (uint32_t)(RI.Type & 0xffffffffL)
141 << "\n");
142 processRelocationRef(RI, *obj, LocalSections, LocalSymbols, Stubs);
143 }
144 if (err) {
145 report_fatal_error(err.message());
146 }
147 }
148 return false;
149 }
150
151 unsigned RuntimeDyldImpl::emitSection(const SectionRef &Section,
152 bool IsCode) {
153
154 unsigned StubBufSize = 0,
155 StubSize = getMaxStubSize();
156 error_code err;
157 if (StubSize > 0) {
158 for (relocation_iterator it = Section.begin_relocations(),
159 itEnd = Section.end_relocations(); it != itEnd; it.increment(err))
160 StubBufSize += StubSize;
161 }
162 StringRef data;
163 uint64_t Alignment64;
164 if ((bool)(err = Section.getContents(data))) report_fatal_error(err.message());
165 if ((bool)(err = Section.getAlignment(Alignment64)))
166 report_fatal_error(err.message());
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::
190 findOrEmitSection(const SectionRef &Section, bool IsCode,
191 ObjSectionToIDMap &LocalSections) {
192
193 unsigned SectionID = 0;
194 ObjSectionToIDMap::iterator sIDIt = LocalSections.find(Section);
195 if (sIDIt != LocalSections.end())
196 SectionID = sIDIt->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 it = SymbolRelocations.begin(),
283 itEnd = SymbolRelocations.end();
284 for (; it != itEnd; it++) {
285 StringRef Name = it->first();
286 RelocationList &Relocs = it->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::
168 processRelocationRef(const ObjRelocationInfo &Rel, const ObjectFile &Obj,
169 ObjSectionToIDMap &ObjSectionToID,
170 LocalSymbolMap &Symbols, StubMap &Stubs) {
171
172 uint32_t RelType = (uint32_t)(Rel.Type & 0xffffffffL);
173 intptr_t Addend = (intptr_t)Rel.AdditionalInfo;
174 RelocationValueRef Value;
175 StringRef TargetName;
176 const SymbolRef &Symbol = Rel.Symbol;
177 Symbol.getName(TargetName);
178 DEBUG(dbgs() << "\t\tRelType: " << RelType
179 << " Addend: " << Addend
180 << " TargetName: " << TargetName
181 << "\n");
182 // First look the symbol in object file symbols.
183 LocalSymbolMap::iterator it = Symbols.find(TargetName.data());
184 if (it != Symbols.end()) {
185 Value.SectionID = it->second.first;
186 Value.Addend = it->second.second;
187 } else {
188 // Second look the symbol in global symbol table.
189 StringMap::iterator itS = SymbolTable.find(TargetName.data());
190 if (itS != SymbolTable.end()) {
191 Value.SectionID = itS->second.first;
192 Value.Addend = itS->second.second;
193 } else {
194 SymbolRef::Type SymType;
195 Symbol.getType(SymType);
196 switch (SymType) {
197 case SymbolRef::ST_Debug: {
198 // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously
199 // and can be changed by another developers. Maybe best way is add
200 // a new symbol type ST_Section to SymbolRef and use it.
201 section_iterator sIt = Obj.end_sections();
202 Symbol.getSection(sIt);
203 if (sIt == Obj.end_sections())
204 llvm_unreachable("Symbol section not found, bad object file format!");
205 DEBUG(dbgs() << "\t\tThis is section symbol\n");
206 Value.SectionID = findOrEmitSection((*sIt), true, ObjSectionToID);
207 Value.Addend = Addend;
208 break;
209 }
210 case SymbolRef::ST_Unknown: {
211 Value.SymbolName = TargetName.data();
212 Value.Addend = Addend;
213 break;
214 }
215 default:
216 llvm_unreachable("Unresolved symbol type!");
217 break;
218 }
219 }
220 }
221 DEBUG(dbgs() << "\t\tRel.SectionID: " << Rel.SectionID
222 << " Rel.Offset: " << Rel.Offset
223 << "\n");
224 if (Arch == Triple::arm &&
225 (RelType == ELF::R_ARM_PC24 ||
226 RelType == ELF::R_ARM_CALL ||
227 RelType == ELF::R_ARM_JUMP24)) {
228 // This is an ARM branch relocation, need to use a stub function.
229 DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.");
230 SectionEntry &Section = Sections[Rel.SectionID];
231 uint8_t *Target = Section.Address + Rel.Offset;
232
233 // Look up for existing stub.
234 StubMap::const_iterator stubIt = Stubs.find(Value);
235 if (stubIt != Stubs.end()) {
236 resolveRelocation(Target, Section.LoadAddress, (uint64_t)Section.Address +
237 stubIt->second, RelType, 0);
238 DEBUG(dbgs() << " Stub function found\n");
239 } else {
240 // Create a new stub function.
241 DEBUG(dbgs() << " Create a new stub function\n");
242 Stubs[Value] = Section.StubOffset;
243 uint8_t *StubTargetAddr = createStubFunction(Section.Address +
244 Section.StubOffset);
245 AddRelocation(Value, Rel.SectionID,
246 StubTargetAddr - Section.Address, ELF::R_ARM_ABS32);
247 resolveRelocation(Target, Section.LoadAddress, (uint64_t)Section.Address +
248 Section.StubOffset, RelType, 0);
249 Section.StubOffset += getMaxStubSize();
250 }
251 } else
252 AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType);
301253 }
302254
303255 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_x86_64:
35 return resolveX86_64Relocation(LocalAddress,
36 FinalAddress,
37 (uintptr_t)Value,
38 isPCRel,
39 Type,
40 Size,
41 Addend);
42 case mach::CTM_ARM:
43 return resolveARMRelocation(LocalAddress,
44 FinalAddress,
45 (uintptr_t)Value,
46 isPCRel,
47 Type,
48 Size,
49 Addend);
44 case Triple::x86_64: // Fall through.
45 case Triple::x86:
46 resolveX86_64Relocation(LocalAddress,
47 FinalAddress,
48 (uintptr_t)Value,
49 isPCRel,
50 MachoType,
51 Size,
52 Addend);
53 break;
54 case Triple::arm: // Fall through.
55 case Triple::thumb:
56 resolveARMRelocation(LocalAddress,
57 FinalAddress,
58 (uintptr_t)Value,
59 isPCRel,
60 MachoType,
61 Size,
62 Addend);
63 break;
5064 }
5165 }
5266
152166 return false;
153167 }
154168
155 bool RuntimeDyldMachO::
156 loadSegment32(const MachOObject *Obj,
157 const MachOObject::LoadCommandInfo *SegmentLCI,
158 const InMemoryStruct &SymtabLC) {
159 // FIXME: This should really be combined w/ loadSegment64. Templatized
160 // function on the 32/64 datatypes maybe?
161 InMemoryStruct SegmentLC;
162 Obj->ReadSegmentLoadCommand(*SegmentLCI, SegmentLC);
163 if (!SegmentLC)
164 return Error("unable to load segment load command");
165
166
167 SmallVector SectionMap;
168 for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
169 InMemoryStruct Sect;
170 Obj->ReadSection(*SegmentLCI, SectNum, Sect);
171 if (!Sect)
172 return Error("unable to load section: '" + Twine(SectNum) + "'");
173
174 // Allocate memory via the MM for the section.
175 uint8_t *Buffer;
176 uint32_t SectionID = Sections.size();
177 if (Sect->Flags == 0x80000400)
178 Buffer = MemMgr->allocateCodeSection(Sect->Size, Sect->Align, SectionID);
179 else
180 Buffer = MemMgr->allocateDataSection(Sect->Size, Sect->Align, SectionID);
181
182 DEBUG(dbgs() << "Loading "
183 << ((Sect->Flags == 0x80000400) ? "text" : "data")
184 << " (ID #" << SectionID << ")"
185 << " '" << Sect->SegmentName << ","
186 << Sect->Name << "' of size " << Sect->Size
187 << " to address " << Buffer << ".\n");
188
189 // Copy the payload from the object file into the allocated buffer.
190 uint8_t *Base = (uint8_t*)Obj->getData(SegmentLC->FileOffset,
191 SegmentLC->FileSize).data();
192 memcpy(Buffer, Base + Sect->Address, Sect->Size);
193
194 // Remember what got allocated for this SectionID.
195 Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size));
196 SectionLocalMemToID[Buffer] = SectionID;
197
198 // By default, the load address of a section is its memory buffer.
199 SectionLoadAddress.push_back((uint64_t)Buffer);
200
201 // Keep a map of object file section numbers to corresponding SectionIDs
202 // while processing the file.
203 SectionMap.push_back(SectionID);
204 }
205
206 // Process the symbol table.
207 SmallVector SymbolNames;
208 processSymbols32(Obj, SectionMap, SymbolNames, SymtabLC);
209
210 // Process the relocations for each section we're loading.
211 Relocations.grow(Relocations.size() + SegmentLC->NumSections);
212 Referrers.grow(Referrers.size() + SegmentLC->NumSections);
213 for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
214 InMemoryStruct Sect;
215 Obj->ReadSection(*SegmentLCI, SectNum, Sect);
216 if (!Sect)
217 return Error("unable to load section: '" + Twine(SectNum) + "'");
218 for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) {
219 InMemoryStruct RE;
220 Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE);
221 if (RE->Word0 & macho::RF_Scattered)
222 return Error("NOT YET IMPLEMENTED: scattered relocations.");
223 // Word0 of the relocation is the offset into the section where the
224 // relocation should be applied. We need to translate that into an
225 // offset into a function since that's our atom.
226 uint32_t Offset = RE->Word0;
227 bool isExtern = (RE->Word1 >> 27) & 1;
228
229 // FIXME: Get the relocation addend from the target address.
230 // FIXME: VERY imporant for internal relocations.
231
232 // Figure out the source symbol of the relocation. If isExtern is true,
233 // this relocation references the symbol table, otherwise it references
234 // a section in the same object, numbered from 1 through NumSections
235 // (SectionBases is [0, NumSections-1]).
236 uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value
237 if (!isExtern) {
238 assert(SourceNum > 0 && "Invalid relocation section number!");
239 unsigned SectionID = SectionMap[SourceNum - 1];
240 unsigned TargetID = SectionMap[SectNum];
241 DEBUG(dbgs() << "Internal relocation at Section #"
242 << TargetID << " + " << Offset
243 << " from Section #"
244 << SectionID << " (Word1: "
245 << format("0x%x", RE->Word1) << ")\n");
246
247 // Store the relocation information. It will get resolved when
248 // the section addresses are assigned.
249 uint32_t RelocationIndex = Relocations[SectionID].size();
250 Relocations[SectionID].push_back(RelocationEntry(TargetID,
251 Offset,
252 RE->Word1,
253 0 /*Addend*/));
254 Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex));
255 } else {
256 StringRef SourceName = SymbolNames[SourceNum];
257
258 // Now store the relocation information. Associate it with the source
259 // symbol. Just add it to the unresolved list and let the general
260 // path post-load resolve it if we know where the symbol is.
261 UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum,
262 Offset,
263 RE->Word1,
264 0 /*Addend*/));
265 DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset
266 << " from '" << SourceName << "(Word1: "
267 << format("0x%x", RE->Word1) << ")\n");
268 }
269 }
270 }
271
272 // Resolve the addresses of any symbols that were defined in this segment.
273 for (int i = 0, e = SymbolNames.size(); i != e; ++i)
274 resolveSymbol(SymbolNames[i]);
275
276 return false;
277 }
278
279
280 bool RuntimeDyldMachO::
281 loadSegment64(const MachOObject *Obj,
282 const MachOObject::LoadCommandInfo *SegmentLCI,
283 const InMemoryStruct &SymtabLC) {
284 InMemoryStruct Segment64LC;
285 Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC);
286 if (!Segment64LC)
287 return Error("unable to load segment load command");
288
289
290 SmallVector SectionMap;
291 for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
292 InMemoryStruct Sect;
293 Obj->ReadSection64(*SegmentLCI, SectNum, Sect);
294 if (!Sect)
295 return Error("unable to load section: '" + Twine(SectNum) + "'");
296
297 // Allocate memory via the MM for the section.
298 uint8_t *Buffer;
299 uint32_t SectionID = Sections.size();
300 unsigned Align = 1 << Sect->Align; // .o file has log2 alignment.
301 if (Sect->Flags == 0x80000400)
302 Buffer = MemMgr->allocateCodeSection(Sect->Size, Align, SectionID);
303 else
304 Buffer = MemMgr->allocateDataSection(Sect->Size, Align, SectionID);
305
306 DEBUG(dbgs() << "Loading "
307 << ((Sect->Flags == 0x80000400) ? "text" : "data")
308 << " (ID #" << SectionID << ")"
309 << " '" << Sect->SegmentName << ","
310 << Sect->Name << "' of size " << Sect->Size
311 << " (align " << Align << ")"
312 << " to address " << Buffer << ".\n");
313
314 // Copy the payload from the object file into the allocated buffer.
315 uint8_t *Base = (uint8_t*)Obj->getData(Segment64LC->FileOffset,
316 Segment64LC->FileSize).data();
317 memcpy(Buffer, Base + Sect->Address, Sect->Size);
318
319 // Remember what got allocated for this SectionID.
320 Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size));
321 SectionLocalMemToID[Buffer] = SectionID;
322
323 // By default, the load address of a section is its memory buffer.
324 SectionLoadAddress.push_back((uint64_t)Buffer);
325
326 // Keep a map of object file section numbers to corresponding SectionIDs
327 // while processing the file.
328 SectionMap.push_back(SectionID);
329 }
330
331 // Process the symbol table.
332 SmallVector SymbolNames;
333 processSymbols64(Obj, SectionMap, SymbolNames, SymtabLC);
334
335 // Process the relocations for each section we're loading.
336 Relocations.grow(Relocations.size() + Segment64LC->NumSections);
337 Referrers.grow(Referrers.size() + Segment64LC->NumSections);
338 for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
339 InMemoryStruct Sect;
340 Obj->ReadSection64(*SegmentLCI, SectNum, Sect);
341 if (!Sect)
342 return Error("unable to load section: '" + Twine(SectNum) + "'");
343 for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) {
344 InMemoryStruct RE;
345 Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE);
346 if (RE->Word0 & macho::RF_Scattered)
347 return Error("NOT YET IMPLEMENTED: scattered relocations.");
348 // Word0 of the relocation is the offset into the section where the
349 // relocation should be applied. We need to translate that into an
350 // offset into a function since that's our atom.
351 uint32_t Offset = RE->Word0;
352 bool isExtern = (RE->Word1 >> 27) & 1;
353
354 // FIXME: Get the relocation addend from the target address.
355 // FIXME: VERY imporant for internal relocations.
356
357 // Figure out the source symbol of the relocation. If isExtern is true,
358 // this relocation references the symbol table, otherwise it references
359 // a section in the same object, numbered from 1 through NumSections
360 // (SectionBases is [0, NumSections-1]).
361 uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value
362 if (!isExtern) {
363 assert(SourceNum > 0 && "Invalid relocation section number!");
364 unsigned SectionID = SectionMap[SourceNum - 1];
365 unsigned TargetID = SectionMap[SectNum];
366 DEBUG(dbgs() << "Internal relocation at Section #"
367 << TargetID << " + " << Offset
368 << " from Section #"
369 << SectionID << " (Word1: "
370 << format("0x%x", RE->Word1) << ")\n");
371
372 // Store the relocation information. It will get resolved when
373 // the section addresses are assigned.
374 uint32_t RelocationIndex = Relocations[SectionID].size();
375 Relocations[SectionID].push_back(RelocationEntry(TargetID,
376 Offset,
377 RE->Word1,
378 0 /*Addend*/));
379 Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex));
380 } else {
381 StringRef SourceName = SymbolNames[SourceNum];
382
383 // Now store the relocation information. Associate it with the source
384 // symbol. Just add it to the unresolved list and let the general
385 // path post-load resolve it if we know where the symbol is.
386 UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum,
387 Offset,
388 RE->Word1,
389 0 /*Addend*/));
390 DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset
391 << " from '" << SourceName << "(Word1: "
392 << format("0x%x", RE->Word1) << ")\n");
393 }
394 }
395 }
396
397 // Resolve the addresses of any symbols that were defined in this segment.
398 for (int i = 0, e = SymbolNames.size(); i != e; ++i)
399 resolveSymbol(SymbolNames[i]);
400
401 return false;
402 }
403
404 bool RuntimeDyldMachO::
405 processSymbols32(const MachOObject *Obj,
406 SmallVectorImpl &SectionMap,
407 SmallVectorImpl &SymbolNames,
408 const InMemoryStruct &SymtabLC) {
409 // FIXME: Combine w/ processSymbols64. Factor 64/32 datatype and such.
410 for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
411 InMemoryStruct STE;
412 Obj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE);
413 if (!STE)
414 return Error("unable to read symbol: '" + Twine(i) + "'");
415 // Get the symbol name.
416 StringRef Name = Obj->getStringAtIndex(STE->StringIndex);
417 SymbolNames.push_back(Name);
418
419 // FIXME: Check the symbol type and flags.
420 if (STE->Type != 0xF) // external, defined in this segment.
421 continue;
422 // Flags in the upper nibble we don't care about.
423 if ((STE->Flags & 0xf) != 0x0)
424 continue;
425
426 // Remember the symbol.
427 uint32_t SectionID = SectionMap[STE->SectionIndex - 1];
428 SymbolTable[Name] = SymbolLoc(SectionID, STE->Value);
429
430 DEBUG(dbgs() << "Symbol: '" << Name << "' @ "
431 << (getSectionAddress(SectionID) + STE->Value)
432 << "\n");
433 }
434 return false;
435 }
436
437 bool RuntimeDyldMachO::
438 processSymbols64(const MachOObject *Obj,
439 SmallVectorImpl &SectionMap,
440 SmallVectorImpl &SymbolNames,
441 const InMemoryStruct &SymtabLC) {
442 for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
443 InMemoryStruct STE;
444 Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE);
445 if (!STE)
446 return Error("unable to read symbol: '" + Twine(i) + "'");
447 // Get the symbol name.
448 StringRef Name = Obj->getStringAtIndex(STE->StringIndex);
449 SymbolNames.push_back(Name);
450
451 // FIXME: Check the symbol type and flags.
452 if (STE->Type != 0xF) // external, defined in this segment.
453 continue;
454 // Flags in the upper nibble we don't care about.
455 if ((STE->Flags & 0xf) != 0x0)
456 continue;
457
458 // Remember the symbol.
459 uint32_t SectionID = SectionMap[STE->SectionIndex - 1];
460 SymbolTable[Name] = SymbolLoc(SectionID, STE->Value);
461
462 DEBUG(dbgs() << "Symbol: '" << Name << "' @ "
463 << (getSectionAddress(SectionID) + STE->Value)
464 << "\n");
465 }
466 return false;
467 }
468
469 // resolveSymbol - Resolve any relocations to the specified symbol if
470 // we know where it lives.
471 void RuntimeDyldMachO::resolveSymbol(StringRef Name) {
472 StringMap::const_iterator Loc = SymbolTable.find(Name);
473 if (Loc == SymbolTable.end())
474 return;
475
476 RelocationList &Relocs = UnresolvedRelocations[Name];
477 DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n");
478 for (int i = 0, e = Relocs.size(); i != e; ++i) {
479 // Change the relocation to be section relative rather than symbol
480 // relative and move it to the resolved relocation list.
481 RelocationEntry Entry = Relocs[i];
482 Entry.Addend += Loc->second.second;
483 uint32_t RelocationIndex = Relocations[Loc->second.first].size();
484 Relocations[Loc->second.first].push_back(Entry);
485 Referrers[Entry.SectionID].push_back(Referrer(Loc->second.first, RelocationIndex));
486 }
487 // FIXME: Keep a worklist of the relocations we've added so that we can
488 // resolve more selectively later.
489 Relocs.clear();
490 }
491
492 bool RuntimeDyldMachO::loadObject(MemoryBuffer *InputBuffer) {
493 // If the linker is in an error state, don't do anything.
494 if (hasError())
495 return true;
496 // Load the Mach-O wrapper object.
497 std::string ErrorStr;
498 OwningPtr Obj(
499 MachOObject::LoadFromBuffer(InputBuffer, &ErrorStr));
500 if (!Obj)
501 return Error("unable to load object: '" + ErrorStr + "'");
502
503 // Get the CPU type information from the header.
504 const macho::Header &Header = Obj->getHeader();
505
506 // FIXME: Error checking that the loaded object is compatible with
507 // the system we're running on.
508 CPUType = Header.CPUType;
509 CPUSubtype = Header.CPUSubtype;
510
511 // Validate that the load commands match what we expect.
512 const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0,
513 *DysymtabLCI = 0;
514 for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
515 const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i);
516 switch (LCI.Command.Type) {
517 case macho::LCT_Segment:
518 case macho::LCT_Segment64:
519 if (SegmentLCI)
520 return Error("unexpected input object (multiple segments)");
521 SegmentLCI = &LCI;
522 break;
523 case macho::LCT_Symtab:
524 if (SymtabLCI)
525 return Error("unexpected input object (multiple symbol tables)");
526 SymtabLCI = &LCI;
527 break;
528 case macho::LCT_Dysymtab:
529 if (DysymtabLCI)
530 return Error("unexpected input object (multiple symbol tables)");
531 DysymtabLCI = &LCI;
532 break;
533 default:
534 return Error("unexpected input object (unexpected load command");
535 }
536 }
537
538 if (!SymtabLCI)
539 return Error("no symbol table found in object");
540 if (!SegmentLCI)
541 return Error("no segments found in object");
542
543 // Read and register the symbol table data.
544 InMemoryStruct SymtabLC;
545 Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);
546 if (!SymtabLC)
547 return Error("unable to load symbol table load command");
548 Obj->RegisterStringTable(*SymtabLC);
549
550 // Read the dynamic link-edit information, if present (not present in static
551 // objects).
552 if (DysymtabLCI) {
553 InMemoryStruct DysymtabLC;
554 Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC);
555 if (!DysymtabLC)
556 return Error("unable to load dynamic link-exit load command");
557
558 // FIXME: We don't support anything interesting yet.
559 // if (DysymtabLC->LocalSymbolsIndex != 0)
560 // return Error("NOT YET IMPLEMENTED: local symbol entries");
561 // if (DysymtabLC->ExternalSymbolsIndex != 0)
562 // return Error("NOT YET IMPLEMENTED: non-external symbol entries");
563 // if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries)
564 // return Error("NOT YET IMPLEMENTED: undefined symbol entries");
565 }
566
567 // Load the segment load command.
568 if (SegmentLCI->Command.Type == macho::LCT_Segment) {
569 if (loadSegment32(Obj.get(), SegmentLCI, SymtabLC))
570 return true;
169 void RuntimeDyldMachO::
170 processRelocationRef(const ObjRelocationInfo &Rel, const ObjectFile &Obj,
171 ObjSectionToIDMap &ObjSectionToID,
172 LocalSymbolMap &Symbols, StubMap &Stubs) {
173
174 uint32_t RelType = (uint32_t) (Rel.Type & 0xffffffffL);
175 RelocationValueRef Value;
176 SectionEntry &Section = Sections[Rel.SectionID];
177 uint8_t *Target = Section.Address + Rel.Offset;
178
179 bool isExtern = (RelType >> 27) & 1;
180 if (isExtern) {
181 StringRef TargetName;
182 const SymbolRef &Symbol = Rel.Symbol;
183 Symbol.getName(TargetName);
184 // First look the symbol in object file symbols.
185 LocalSymbolMap::iterator it = Symbols.find(TargetName.data());
186 if (it != Symbols.end()) {
187 Value.SectionID = it->second.first;
188 Value.Addend = it->second.second;
189 } else {
190 // Second look the symbol in global symbol table.
191 StringMap::iterator itS = SymbolTable.find(TargetName.data());
192 if (itS != SymbolTable.end()) {
193 Value.SectionID = itS->second.first;
194 Value.Addend = itS->second.second;
195 } else
196 Value.SymbolName = TargetName.data();
197 }
571198 } else {
572 if (loadSegment64(Obj.get(), SegmentLCI, SymtabLC))
573 return true;
574 }
575
576 // Assign the addresses of the sections from the object so that any
577 // relocations to them get set properly.
578 // FIXME: This is done directly from the client at the moment. We should
579 // default the values to the local storage, at least when the target arch
580 // is the same as the host arch.
581
582 return false;
583 }
584
585 // Assign an address to a symbol name and resolve all the relocations
586 // associated with it.
587 void RuntimeDyldMachO::reassignSectionAddress(unsigned SectionID,
588 uint64_t Addr) {
589 // The address to use for relocation resolution is not
590 // the address of the local section buffer. We must be doing
591 // a remote execution environment of some sort. Re-apply any
592 // relocations referencing this section with the given address.
593 //
594 // Addr is a uint64_t because we can't assume the pointer width
595 // of the target is the same as that of the host. Just use a generic
596 // "big enough" type.
597
598 SectionLoadAddress[SectionID] = Addr;
599
600 RelocationList &Relocs = Relocations[SectionID];
601 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
602 RelocationEntry &RE = Relocs[i];
603 uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset;
604 uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset;
605 bool isPCRel = (RE.Data >> 24) & 1;
606 unsigned Type = (RE.Data >> 28) & 0xf;
607 unsigned Size = 1 << ((RE.Data >> 25) & 3);
608
609 DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID
610 << " + " << RE.Offset << " (" << format("%p", Target) << ")"
611 << " from Section #" << SectionID << " (" << format("%p", Addr) << ")"
612 << "(" << (isPCRel ? "pcrel" : "absolute")
613 << ", type: " << Type << ", Size: " << Size << ", Addend: "
614 << RE.Addend << ").\n");
615
616 resolveRelocation(Target,
617 FinalTarget,
618 Addr,
619 isPCRel,
620 Type,
621 Size,
622 RE.Addend);
623 }
624 ReferrerList &Refers = Referrers[SectionID];
625 for (unsigned i = 0, e = Refers.size(); i != e; ++i) {
626 Referrer &R = Refers[i];
627 RelocationEntry &RE = Relocations[R.SectionID][R.Index];
628 uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset;
629 uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset;
630 bool isPCRel = (RE.Data >> 24) & 1;
631 unsigned Type = (RE.Data >> 28) & 0xf;
632 unsigned Size = 1 << ((RE.Data >> 25) & 3);
633
634 DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID
635 << " + " << RE.Offset << " (" << format("%p", Target) << ")"
636 << " from Section #" << SectionID << " (" << format("%p", Addr) << ")"
637 << "(" << (isPCRel ? "pcrel" : "absolute")
638 << ", type: " << Type << ", Size: " << Size << ", Addend: "
639 << RE.Addend << ").\n");
640
641 resolveRelocation(Target,
642 FinalTarget,
643 Addr,
644 isPCRel,
645 Type,
646 Size,
647 RE.Addend);
648 }
649 }
650
651 bool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) {
199 error_code err;
200 uint8_t sIdx = static_cast(RelType & 0xFF);
201 section_iterator sIt = Obj.begin_sections(),
202 sItEnd = Obj.end_sections();
203 for (uint8_t i = 1; i < sIdx; i++) {
204 error_code err;
205 sIt.increment(err);
206 if (sIt == sItEnd)
207 break;
208 }
209 assert(sIt != sItEnd && "No section containing relocation!");
210 Value.SectionID = findOrEmitSection(*sIt, true, ObjSectionToID);
211 Value.Addend = *(const intptr_t *)Target;
212 if (Value.Addend) {
213 // The MachO addend is offset from the current section, we need set it
214 // as offset from destination section
215 Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress;
216 }
217 }
218
219 if (Arch == Triple::arm && RelType == macho::RIT_ARM_Branch24Bit) {
220 // This is an ARM branch relocation, need to use a stub function.
221
222 // Look up for existing stub.
223 StubMap::const_iterator stubIt = Stubs.find(Value);
224 if (stubIt != Stubs.end())
225 resolveRelocation(Target, (uint64_t)Target,
226 (uint64_t)Section.Address + stubIt->second,
227 RelType, 0);
228 else {
229 // Create a new stub function.
230 Stubs[Value] = Section.StubOffset;
231 uint8_t *StubTargetAddr = createStubFunction(Section.Address +
232 Section.StubOffset);
233 AddRelocation(Value, Rel.SectionID, StubTargetAddr - Section.Address,
234 macho::RIT_Vanilla);
235 resolveRelocation(Target, (uint64_t)Target,
236 (uint64_t)Section.Address + Section.StubOffset,
237 RelType, 0);
238 Section.StubOffset += getMaxStubSize();
239 }
240 } else
241 AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType);
242 }
243
244
245 bool RuntimeDyldMachO::isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
652246 StringRef Magic = InputBuffer->getBuffer().slice(0, 4);
653247 if (Magic == "\xFE\xED\xFA\xCE") return true;
654248 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 resolveX86_64Relocation(uint8_t *LocalAddress,
7729 uint64_t FinalAddress,
7830 uint64_t Value,
8840 unsigned Size,
8941 int64_t Addend);
9042
91 bool loadSegment32(const MachOObject *Obj,
92 const MachOObject::LoadCommandInfo *SegmentLCI,
93 const InMemoryStruct &SymtabLC);
94 bool loadSegment64(const MachOObject *Obj,
95 const MachOObject::LoadCommandInfo *SegmentLCI,
96 const InMemoryStruct &SymtabLC);
97 bool processSymbols32(const MachOObject *Obj,
98 SmallVectorImpl &SectionMap,
99 SmallVectorImpl &SymbolNames,
100 const InMemoryStruct &SymtabLC);
101 bool processSymbols64(const MachOObject *Obj,
102 SmallVectorImpl &SectionMap,
103 SmallVectorImpl &SymbolNames,
104 const InMemoryStruct &SymtabLC);
105
106 void resolveSymbol(StringRef Name);
43 virtual void processRelocationRef(const ObjRelocationInfo &Rel,
44 const ObjectFile &Obj,
45 ObjSectionToIDMap &ObjSectionToID,
46 LocalSymbolMap &Symbols, StubMap &Stubs);
10747
10848 public:
49 virtual void resolveRelocation(uint8_t *LocalAddress,
50 uint64_t FinalAddress,
51 uint64_t Value,
52 uint32_t Type,
53 int64_t Addend);
54
10955 RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
11056
111 bool loadObject(MemoryBuffer *InputBuffer);
112
113 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
114
115 static bool isKnownFormat(const MemoryBuffer *InputBuffer);
116
117 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
118 return isKnownFormat(InputBuffer);
119 }
57 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
12058 };
12159
12260 } // end namespace llvm
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']:
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;