llvm.org GIT mirror llvm / 0e4fa5f
Re-factored RuntimeDyLd: 1. The main works will made in the RuntimeDyLdImpl with uses the ObjectFile class. RuntimeDyLdMachO and RuntimeDyLdELF now only parses relocations and resolve it. This is allows to make improvements of the RuntimeDyLd more easily. In addition the support for COFF can be easily added. 2. Added ARM relocations to RuntimeDyLdELF. 3. Added support for stub functions for the ARM, allowing to do a long branch. 4. Added support for external functions that are not loaded from the object files, but can be loaded from external libraries. Now MCJIT can correctly execute the code containing the printf, putc, and etc. 5. The sections emitted instead functions, thanks Jim Grosbach. MemoryManager.startFunctionBody() and MemoryManager.endFunctionBody() have been removed. 6. MCJITMemoryManager.allocateDataSection() and MCJITMemoryManager. allocateCodeSection() used JMM->allocateSpace() instead of JMM->allocateCodeSection() and JMM->allocateDataSection(), because I got an error: "Cannot allocate an allocated block!" with object file contains more than one code or data sections. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153754 91177308-0d34-0410-b5e6-96231b3b80d8 Danil Malyshev 7 years ago
9 changed file(s) with 770 addition(s) and 1090 deletion(s). Raw diff Collapse all Expand all
4444 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
4545 unsigned SectionID) = 0;
4646
47 // Allocate ActualSize bytes, or more, for the named function. Return
48 // a pointer to the allocated memory and update Size to reflect how much
49 // memory was acutally allocated.
50 virtual uint8_t *startFunctionBody(const char *Name, uintptr_t &Size) = 0;
51
52 // Mark the end of the function, including how much of the allocated
53 // memory was actually used.
54 virtual void endFunctionBody(const char *Name, uint8_t *FunctionStart,
55 uint8_t *FunctionEnd) = 0;
56
57
5847 virtual void *getPointerToNamedFunction(const std::string &Name,
5948 bool AbortOnFailure = true) = 0;
6049 };
3333
3434 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
3535 unsigned SectionID) {
36 return JMM->allocateDataSection(Size, Alignment, SectionID);
36 return JMM->allocateSpace(Size, Alignment);
3737 }
3838
3939 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
4040 unsigned SectionID) {
41 return JMM->allocateCodeSection(Size, Alignment, SectionID);
41 return JMM->allocateSpace(Size, Alignment);
4242 }
4343
4444 virtual void *getPointerToNamedFunction(const std::string &Name,
4646 return JMM->getPointerToNamedFunction(Name, AbortOnFailure);
4747 }
4848
49 // Allocate ActualSize bytes, or more, for the named function. Return
50 // a pointer to the allocated memory and update Size to reflect how much
51 // memory was acutally allocated.
52 uint8_t *startFunctionBody(const char *Name, uintptr_t &Size) {
53 // FIXME: This should really reference the MCAsmInfo to get the global
54 // prefix.
55 if (Name[0] == '_') ++Name;
56 Function *F = M->getFunction(Name);
57 // Some ObjC names have a prefixed \01 in the IR. If we failed to find
58 // the symbol and it's of the ObjC conventions (starts with "-" or
59 // "+"), try prepending a \01 and see if we can find it that way.
60 if (!F && (Name[0] == '-' || Name[0] == '+'))
61 F = M->getFunction((Twine("\1") + Name).str());
62 assert(F && "No matching function in JIT IR Module!");
63 return JMM->startFunctionBody(F, Size);
64 }
65
66 // Mark the end of the function, including how much of the allocated
67 // memory was actually used.
68 void endFunctionBody(const char *Name, uint8_t *FunctionStart,
69 uint8_t *FunctionEnd) {
70 // FIXME: This should really reference the MCAsmInfo to get the global
71 // prefix.
72 if (Name[0] == '_') ++Name;
73 Function *F = M->getFunction(Name);
74 // Some ObjC names have a prefixed \01 in the IR. If we failed to find
75 // the symbol and it's of the ObjC conventions (starts with "-" or
76 // "+"), try prepending a \01 and see if we can find it that way.
77 if (!F && (Name[0] == '-' || Name[0] == '+'))
78 F = M->getFunction((Twine("\1") + Name).str());
79 assert(F && "No matching function in JIT IR Module!");
80 JMM->endFunctionBody(F, FunctionStart, FunctionEnd);
81 }
82
8349 };
8450
8551 } // End llvm namespace
2525
2626 namespace llvm {
2727
28 void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress,
29 uint8_t *EndAddress) {
30 // FIXME: DEPRECATED in favor of by-section allocation.
31 // Allocate memory for the function via the memory manager.
32 uintptr_t Size = EndAddress - StartAddress + 1;
33 uintptr_t AllocSize = Size;
34 uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize);
35 assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) &&
36 "Memory manager failed to allocate enough memory!");
37 // Copy the function payload into the memory block.
38 memcpy(Mem, StartAddress, Size);
39 MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size);
40 // Remember where we put it.
41 unsigned SectionID = Sections.size();
42 Sections.push_back(sys::MemoryBlock(Mem, Size));
43
44 // Default the assigned address for this symbol to wherever this
45 // allocated it.
46 SymbolTable[Name] = SymbolLoc(SectionID, 0);
47 DEBUG(dbgs() << " allocated to [" << Mem << ", " << Mem + Size << "]\n");
48 }
28 namespace {
29 // Helper for extensive error checking in debug builds.
30 error_code Check(error_code Err) {
31 if (Err) {
32 report_fatal_error(Err.message());
33 }
34 return Err;
35 }
36 } // end anonymous namespace
37
4938
5039 // Resolve the relocations for all symbols we currently know about.
5140 void RuntimeDyldImpl::resolveRelocations() {
41 // First, resolve relocations assotiated with external symbols.
42 resolveSymbols();
43
5244 // Just iterate over the sections we have and resolve all the relocations
5345 // in them. Gross overkill, but it gets the job done.
5446 for (int i = 0, e = Sections.size(); i != e; ++i) {
55 reassignSectionAddress(i, SectionLoadAddress[i]);
47 reassignSectionAddress(i, Sections[i].LoadAddress);
5648 }
5749 }
5850
5951 void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress,
6052 uint64_t TargetAddress) {
61 assert(SectionLocalMemToID.count(LocalAddress) &&
62 "Attempting to remap address of unknown section!");
63 unsigned SectionID = SectionLocalMemToID[LocalAddress];
64 reassignSectionAddress(SectionID, TargetAddress);
65 }
53 for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
54 if (Sections[i].Address == LocalAddress) {
55 reassignSectionAddress(i, TargetAddress);
56 return;
57 }
58 }
59 llvm_unreachable("Attempting to remap address of unknown section!");
60 }
61
62 bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
63 // FIXME: ObjectFile don't modify MemoryBuffer.
64 // It should use const MemoryBuffer as parameter.
65 ObjectFile *obj
66 = ObjectFile::createObjectFile(const_cast(InputBuffer));
67
68 Arch = (Triple::ArchType)obj->getArch();
69
70 LocalSymbolMap LocalSymbols; // Functions and data symbols from the
71 // object file.
72 ObjSectionToIDMap LocalSections; // Used sections from the object file
73
74 error_code err;
75 // Parse symbols
76 DEBUG(dbgs() << "Parse symbols:\n");
77 for (symbol_iterator i = obj->begin_symbols(), e = obj->end_symbols();
78 i != e; i.increment(err)) {
79 Check(err);
80 object::SymbolRef::Type SymType;
81 StringRef Name;
82 Check(i->getType(SymType));
83 Check(i->getName(Name));
84
85 if (SymType == object::SymbolRef::ST_Function ||
86 SymType == object::SymbolRef::ST_Data) {
87 uint64_t FileOffset;
88 uint32_t flags;
89 StringRef sData;
90 section_iterator si = obj->end_sections();
91 Check(i->getFileOffset(FileOffset));
92 Check(i->getFlags(flags));
93 Check(i->getSection(si));
94 if (si == obj->end_sections()) continue;
95 Check(si->getContents(sData));
96 const uint8_t* SymPtr = (const uint8_t*)InputBuffer->getBufferStart() +
97 (uintptr_t)FileOffset;
98 uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)sData.begin());
99 unsigned SectionID
100 = findOrEmitSection(*si,
101 SymType == object::SymbolRef::ST_Function,
102 LocalSections);
103 bool isGlobal = flags & SymbolRef::SF_Global;
104 LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset);
105 DEBUG(dbgs() << "\tFileOffset: " << format("%p", (uintptr_t)FileOffset)
106 << " flags: " << flags
107 << " SID: " << SectionID
108 << " Offset: " << format("%p", SectOffset));
109 if (isGlobal)
110 SymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
111 }
112 DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n");
113 }
114
115 // Parse and proccess relocations
116 DEBUG(dbgs() << "Parse relocations:\n");
117 for (section_iterator si = obj->begin_sections(),
118 se = obj->end_sections(); si != se; si.increment(err)) {
119 Check(err);
120 bool isFirstRelocation = true;
121 unsigned SectionID = 0;
122 StubMap Stubs;
123
124 for (relocation_iterator i = si->begin_relocations(),
125 e = si->end_relocations(); i != e; i.increment(err)) {
126 Check(err);
127
128 // If it's first relocation in this section, find its SectionID
129 if (isFirstRelocation) {
130 SectionID = findOrEmitSection(*si, true, LocalSections);
131 DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
132 isFirstRelocation = false;
133 }
134
135 ObjRelocationInfo RI;
136 RI.SectionID = SectionID;
137 Check(i->getAdditionalInfo(RI.AdditionalInfo));
138 Check(i->getOffset(RI.Offset));
139 Check(i->getSymbol(RI.Symbol));
140 Check(i->getType(RI.Type));
141
142 DEBUG(dbgs() << "\t\tAddend: " << RI.AdditionalInfo
143 << " Offset: " << format("%p", (uintptr_t)RI.Offset)
144 << " Type: " << (uint32_t)(RI.Type & 0xffffffffL)
145 << "\n");
146 processRelocationRef(RI, *obj, LocalSections, LocalSymbols, Stubs);
147 }
148 }
149 return false;
150 }
151
152 unsigned RuntimeDyldImpl::emitSection(const SectionRef &Section,
153 bool IsCode) {
154
155 unsigned StubBufSize = 0,
156 StubSize = getMaxStubSize();
157 error_code err;
158 if (StubSize > 0) {
159 for (relocation_iterator i = Section.begin_relocations(),
160 e = Section.end_relocations(); i != e; i.increment(err))
161 StubBufSize += StubSize;
162 }
163 StringRef data;
164 uint64_t Alignment64;
165 Check(Section.getContents(data));
166 Check(Section.getAlignment(Alignment64));
167
168 unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
169 unsigned DataSize = data.size();
170 unsigned Allocate = DataSize + StubBufSize;
171 unsigned SectionID = Sections.size();
172 const char *pData = data.data();
173 uint8_t *Addr = IsCode
174 ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID)
175 : MemMgr->allocateDataSection(Allocate, Alignment, SectionID);
176
177 memcpy(Addr, pData, DataSize);
178 DEBUG(dbgs() << "emitSection SectionID: " << SectionID
179 << " obj addr: " << format("%p", pData)
180 << " new addr: " << format("%p", Addr)
181 << " DataSize: " << DataSize
182 << " StubBufSize: " << StubBufSize
183 << " Allocate: " << Allocate
184 << "\n");
185 Sections.push_back(SectionEntry(Addr, Allocate, DataSize,(uintptr_t)pData));
186 return SectionID;
187 }
188
189 unsigned RuntimeDyldImpl::findOrEmitSection(const SectionRef &Section,
190 bool IsCode,
191 ObjSectionToIDMap &LocalSections) {
192
193 unsigned SectionID = 0;
194 ObjSectionToIDMap::iterator i = LocalSections.find(Section);
195 if (i != LocalSections.end())
196 SectionID = i->second;
197 else {
198 SectionID = emitSection(Section, IsCode);
199 LocalSections[Section] = SectionID;
200 }
201 return SectionID;
202 }
203
204 void RuntimeDyldImpl::AddRelocation(const RelocationValueRef &Value,
205 unsigned SectionID, uintptr_t Offset,
206 uint32_t RelType) {
207 DEBUG(dbgs() << "AddRelocation SymNamePtr: " << format("%p", Value.SymbolName)
208 << " SID: " << Value.SectionID
209 << " Addend: " << format("%p", Value.Addend)
210 << " Offset: " << format("%p", Offset)
211 << " RelType: " << format("%x", RelType)
212 << "\n");
213
214 if (Value.SymbolName == 0) {
215 Relocations[Value.SectionID].push_back(RelocationEntry(
216 SectionID,
217 Offset,
218 RelType,
219 Value.Addend));
220 } else
221 SymbolRelocations[Value.SymbolName].push_back(RelocationEntry(
222 SectionID,
223 Offset,
224 RelType,
225 Value.Addend));
226 }
227
228 uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
229 // TODO: There is only ARM far stub now. We should add the Thumb stub,
230 // and stubs for branches Thumb - ARM and ARM - Thumb.
231 if (Arch == Triple::arm) {
232 uint32_t *StubAddr = (uint32_t*)Addr;
233 *StubAddr = 0xe51ff004; // ldr pc,
234 return (uint8_t*)++StubAddr;
235 }
236 else
237 return Addr;
238 }
239
240 // Assign an address to a symbol name and resolve all the relocations
241 // associated with it.
242 void RuntimeDyldImpl::reassignSectionAddress(unsigned SectionID,
243 uint64_t Addr) {
244 // The address to use for relocation resolution is not
245 // the address of the local section buffer. We must be doing
246 // a remote execution environment of some sort. Re-apply any
247 // relocations referencing this section with the given address.
248 //
249 // Addr is a uint64_t because we can't assume the pointer width
250 // of the target is the same as that of the host. Just use a generic
251 // "big enough" type.
252 Sections[SectionID].LoadAddress = Addr;
253 DEBUG(dbgs() << "Resolving relocations Section #" << SectionID
254 << "\t" << format("%p", (uint8_t *)Addr)
255 << "\n");
256 resolveRelocationList(Relocations[SectionID], Addr);
257 }
258
259 void RuntimeDyldImpl::resolveRelocationEntry(const RelocationEntry &RE,
260 uint64_t Value) {
261 uint8_t *Target = Sections[RE.SectionID].Address + RE.Offset;
262 DEBUG(dbgs() << "\tSectionID: " << RE.SectionID
263 << " + " << RE.Offset << " (" << format("%p", Target) << ")"
264 << " Data: " << RE.Data
265 << " Addend: " << RE.Addend
266 << "\n");
267
268 resolveRelocation(Target, Sections[RE.SectionID].LoadAddress + RE.Offset,
269 Value, RE.Data, RE.Addend);
270 }
271
272 void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
273 uint64_t Value) {
274 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
275 resolveRelocationEntry(Relocs[i], Value);
276 }
277 }
278
279 // resolveSymbols - Resolve any relocations to the specified symbols if
280 // we know where it lives.
281 void RuntimeDyldImpl::resolveSymbols() {
282 StringMap::iterator i = SymbolRelocations.begin(),
283 e = SymbolRelocations.end();
284 for (; i != e; i++) {
285 StringRef Name = i->first();
286 RelocationList &Relocs = i->second;
287 StringMap::const_iterator Loc = SymbolTable.find(Name);
288 if (Loc == SymbolTable.end()) {
289 // This is an external symbol, try to get it address from
290 // MemoryManager.
291 uint8_t *Addr = (uint8_t*) MemMgr->getPointerToNamedFunction(Name.data(),
292 true);
293 DEBUG(dbgs() << "Resolving relocations Name: " << Name
294 << "\t" << format("%p", Addr)
295 << "\n");
296 resolveRelocationList(Relocs, (uintptr_t)Addr);
297 } else {
298 // Change the relocation to be section relative rather than symbol
299 // relative and move it to the resolved relocation list.
300 DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n");
301 for (int i = 0, e = Relocs.size(); i != e; ++i) {
302 RelocationEntry Entry = Relocs[i];
303 Entry.Addend += Loc->second.second;
304 Relocations[Loc->second.first].push_back(Entry);
305 }
306 Relocs.clear();
307 }
308 }
309 }
310
66311
67312 //===----------------------------------------------------------------------===//
68313 // RuntimeDyld class implementation
2424
2525 namespace llvm {
2626
27 namespace {
28
29 // FIXME: this function should probably not live here...
30 //
31 // Returns the name and address of an unrelocated symbol in an ELF section
32 void getSymbolInfo(symbol_iterator Sym, uint64_t &Addr, StringRef &Name) {
33 //FIXME: error checking here required to catch corrupt ELF objects...
34 error_code Err = Sym->getName(Name);
35
36 uint64_t AddrInSection;
37 Err = Sym->getAddress(AddrInSection);
38
39 SectionRef empty_section;
40 section_iterator Section(empty_section);
41 Err = Sym->getSection(Section);
42
43 StringRef SectionContents;
44 Section->getContents(SectionContents);
45
46 Addr = reinterpret_cast(SectionContents.data()) + AddrInSection;
47 }
48
49 }
50
51 bool RuntimeDyldELF::loadObject(MemoryBuffer *InputBuffer) {
52 if (!isCompatibleFormat(InputBuffer))
53 return true;
54
55 OwningPtr Obj(ObjectFile::createELFObjectFile(InputBuffer));
56
57 Arch = Obj->getArch();
58
59 // Map address in the Object file image to function names
60 IntervalMap::Allocator A;
61 IntervalMap FuncMap(A);
62
63 // This is a bit of a hack. The ObjectFile we've just loaded reports
64 // section addresses as 0 and doesn't provide access to the section
65 // offset (from which we could calculate the address. Instead,
66 // we're storing the address when it comes up in the ST_Debug case
67 // below.
68 //
69 StringMap DebugSymbolMap;
70
71 symbol_iterator SymEnd = Obj->end_symbols();
72 error_code Err;
73 for (symbol_iterator Sym = Obj->begin_symbols();
74 Sym != SymEnd; Sym.increment(Err)) {
75 SymbolRef::Type Type;
76 Sym->getType(Type);
77 if (Type == SymbolRef::ST_Function) {
78 StringRef Name;
79 uint64_t Addr;
80 getSymbolInfo(Sym, Addr, Name);
81
82 uint64_t Size;
83 Err = Sym->getSize(Size);
84
85 uint8_t *Start;
86 uint8_t *End;
87 Start = reinterpret_cast(Addr);
88 End = reinterpret_cast(Addr + Size - 1);
89
90 extractFunction(Name, Start, End);
91 FuncMap.insert(Addr, Addr + Size - 1, Name);
92 } else if (Type == SymbolRef::ST_Debug) {
93 // This case helps us find section addresses
94 StringRef Name;
95 uint64_t Addr;
96 getSymbolInfo(Sym, Addr, Name);
97 DebugSymbolMap[Name] = Addr;
98 }
99 }
100
101 // Iterate through the relocations for this object
102 section_iterator SecEnd = Obj->end_sections();
103 for (section_iterator Sec = Obj->begin_sections();
104 Sec != SecEnd; Sec.increment(Err)) {
105 StringRef SecName;
106 uint64_t SecAddr;
107 Sec->getName(SecName);
108 // Ignore sections that aren't in our map
109 if (DebugSymbolMap.find(SecName) == DebugSymbolMap.end()) {
110 continue;
111 }
112 SecAddr = DebugSymbolMap[SecName];
113 relocation_iterator RelEnd = Sec->end_relocations();
114 for (relocation_iterator Rel = Sec->begin_relocations();
115 Rel != RelEnd; Rel.increment(Err)) {
116 uint64_t RelOffset;
117 uint64_t RelType;
118 int64_t RelAddend;
119 SymbolRef RelSym;
120 StringRef SymName;
121 uint64_t SymAddr;
122 uint64_t SymOffset;
123
124 Rel->getAddress(RelOffset);
125 Rel->getType(RelType);
126 Rel->getAdditionalInfo(RelAddend);
127 Rel->getSymbol(RelSym);
128 RelSym.getName(SymName);
129 RelSym.getAddress(SymAddr);
130 RelSym.getFileOffset(SymOffset);
131
132 // If this relocation is inside a function, we want to store the
133 // function name and a function-relative offset
134 IntervalMap::iterator ContainingFunc
135 = FuncMap.find(SecAddr + RelOffset);
136 if (ContainingFunc.valid()) {
137 // Re-base the relocation to make it relative to the target function
138 RelOffset = (SecAddr + RelOffset) - ContainingFunc.start();
139 Relocations[SymName].push_back(RelocationEntry(ContainingFunc.value(),
140 RelOffset,
141 RelType,
142 RelAddend,
143 true));
144 } else {
145 Relocations[SymName].push_back(RelocationEntry(SecName,
146 RelOffset,
147 RelType,
148 RelAddend,
149 false));
150 }
151 }
152 }
153 return false;
154 }
155
156 void RuntimeDyldELF::resolveRelocations() {
157 // FIXME: deprecated. should be changed to use the by-section
158 // allocation and relocation scheme.
159
160 // Just iterate over the symbols in our symbol table and assign their
161 // addresses.
162 StringMap::iterator i = SymbolTable.begin();
163 StringMap::iterator e = SymbolTable.end();
164 for (;i != e; ++i) {
165 assert (i->getValue().second == 0 && "non-zero offset in by-function sym!");
166 reassignSymbolAddress(i->getKey(),
167 (uint8_t*)Sections[i->getValue().first].base());
168 }
169 }
170
171 void RuntimeDyldELF::resolveX86_64Relocation(StringRef Name,
172 uint8_t *Addr,
173 const RelocationEntry &RE) {
174 uint8_t *TargetAddr;
175 if (RE.IsFunctionRelative) {
176 StringMap::const_iterator Loc = SymbolTable.find(RE.Target);
177 assert(Loc != SymbolTable.end() && "Function for relocation not found");
178 TargetAddr =
179 reinterpret_cast(Sections[Loc->second.first].base()) +
180 Loc->second.second + RE.Offset;
181 } else {
182 // FIXME: Get the address of the target section and add that to RE.Offset
183 llvm_unreachable("Non-function relocation not implemented yet!");
184 }
185
186 switch (RE.Type) {
187 default: llvm_unreachable("Relocation type not implemented yet!");
27
28 void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress,
29 uint64_t FinalAddress,
30 uint64_t Value,
31 uint32_t Type,
32 int64_t Addend) {
33 switch (Type) {
34 default:
35 llvm_unreachable("Relocation type not implemented yet!");
36 break;
18837 case ELF::R_X86_64_64: {
189 uint8_t **Target = reinterpret_cast(TargetAddr);
190 *Target = Addr + RE.Addend;
38 uint64_t *Target = (uint64_t*)(LocalAddress);
39 *Target = Value + Addend;
19140 break;
19241 }
19342 case ELF::R_X86_64_32:
19443 case ELF::R_X86_64_32S: {
195 uint64_t Value = reinterpret_cast(Addr) + RE.Addend;
44 Value += Addend;
19645 // FIXME: Handle the possibility of this assertion failing
197 assert((RE.Type == ELF::R_X86_64_32 && !(Value & 0xFFFFFFFF00000000ULL)) ||
198 (RE.Type == ELF::R_X86_64_32S &&
46 assert((Type == ELF::R_X86_64_32 && !(Value & 0xFFFFFFFF00000000ULL)) ||
47 (Type == ELF::R_X86_64_32S &&
19948 (Value & 0xFFFFFFFF00000000ULL) == 0xFFFFFFFF00000000ULL));
20049 uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
201 uint32_t *Target = reinterpret_cast(TargetAddr);
50 uint32_t *Target = reinterpret_cast(LocalAddress);
20251 *Target = TruncatedAddr;
20352 break;
20453 }
20554 case ELF::R_X86_64_PC32: {
206 uint32_t *Placeholder = reinterpret_cast(TargetAddr);
207 uint64_t RealOffset = *Placeholder +
208 reinterpret_cast(Addr) +
209 RE.Addend - reinterpret_cast(TargetAddr);
210 assert((RealOffset & 0xFFFFFFFF) == RealOffset);
211 uint32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
55 uint32_t *Placeholder = reinterpret_cast(LocalAddress);
56 int64_t RealOffset = *Placeholder + Value + Addend - FinalAddress;
57 assert(RealOffset <= 214783647 && RealOffset >= -214783648);
58 int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
21259 *Placeholder = TruncOffset;
21360 break;
21461 }
21562 }
21663 }
21764
218 void RuntimeDyldELF::resolveX86Relocation(StringRef Name,
219 uint8_t *Addr,
220 const RelocationEntry &RE) {
221 uint8_t *TargetAddr;
222 if (RE.IsFunctionRelative) {
223 StringMap::const_iterator Loc = SymbolTable.find(RE.Target);
224 assert(Loc != SymbolTable.end() && "Function for relocation not found");
225 TargetAddr =
226 reinterpret_cast(Sections[Loc->second.first].base()) +
227 Loc->second.second + RE.Offset;
228 } else {
229 // FIXME: Get the address of the target section and add that to RE.Offset
230 llvm_unreachable("Non-function relocation not implemented yet!");
231 }
232
233 switch (RE.Type) {
65 void RuntimeDyldELF::resolveX86Relocation(uint8_t *LocalAddress,
66 uint32_t FinalAddress,
67 uint32_t Value,
68 uint32_t Type,
69 int32_t Addend) {
70 switch (Type) {
23471 case ELF::R_386_32: {
235 uint8_t **Target = reinterpret_cast(TargetAddr);
236 *Target = Addr + RE.Addend;
72 uint32_t *Target = (uint32_t*)(LocalAddress);
73 *Target = Value + Addend;
23774 break;
23875 }
23976 case ELF::R_386_PC32: {
240 uint32_t *Placeholder = reinterpret_cast(TargetAddr);
241 uint32_t RealOffset = *Placeholder + reinterpret_cast(Addr) +
242 RE.Addend - reinterpret_cast(TargetAddr);
77 uint32_t *Placeholder = reinterpret_cast(LocalAddress);
78 uint32_t RealOffset = *Placeholder + Value + Addend - FinalAddress;
24379 *Placeholder = RealOffset;
24480 break;
24581 }
24783 // There are other relocation types, but it appears these are the
24884 // only ones currently used by the LLVM ELF object writer
24985 llvm_unreachable("Relocation type not implemented yet!");
250 }
251 }
252
253 void RuntimeDyldELF::resolveArmRelocation(StringRef Name,
254 uint8_t *Addr,
255 const RelocationEntry &RE) {
256 }
257
258 void RuntimeDyldELF::resolveRelocation(StringRef Name,
259 uint8_t *Addr,
260 const RelocationEntry &RE) {
86 break;
87 }
88 }
89
90 void RuntimeDyldELF::resolveARMRelocation(uint8_t *LocalAddress,
91 uint32_t FinalAddress,
92 uint32_t Value,
93 uint32_t Type,
94 int32_t Addend) {
95 // TODO: Add Thumb relocations.
96 uint32_t* TargetPtr = (uint32_t*)LocalAddress;
97 Value += Addend;
98
99 DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: " << LocalAddress
100 << " FinalAddress: " << format("%p",FinalAddress)
101 << " Value: " << format("%x",Value)
102 << " Type: " << format("%x",Type)
103 << " Addend: " << format("%x",Addend)
104 << "\n");
105
106 switch(Type) {
107 default:
108 llvm_unreachable("Not implemented relocation type!");
109
110 // Just write 32bit value to relocation address
111 case ELF::R_ARM_ABS32 :
112 *TargetPtr = Value;
113 break;
114
115 // Write first 16 bit of 32 bit value to the mov instruction.
116 // Last 4 bit should be shifted.
117 case ELF::R_ARM_MOVW_ABS_NC :
118 Value = Value & 0xFFFF;
119 *TargetPtr |= Value & 0xFFF;
120 *TargetPtr |= ((Value >> 12) & 0xF) << 16;
121 break;
122
123 // Write last 16 bit of 32 bit value to the mov instruction.
124 // Last 4 bit should be shifted.
125 case ELF::R_ARM_MOVT_ABS :
126 Value = (Value >> 16) & 0xFFFF;
127 *TargetPtr |= Value & 0xFFF;
128 *TargetPtr |= ((Value >> 12) & 0xF) << 16;
129 break;
130
131 // Write 24 bit relative value to the branch instruction.
132 case ELF::R_ARM_PC24 : // Fall through.
133 case ELF::R_ARM_CALL : // Fall through.
134 case ELF::R_ARM_JUMP24 :
135 int32_t RelValue = static_cast(Value - FinalAddress - 8);
136 RelValue = (RelValue & 0x03FFFFFC) >> 2;
137 *TargetPtr &= 0xFF000000;
138 *TargetPtr |= RelValue;
139 break;
140 }
141 }
142
143 void RuntimeDyldELF::resolveRelocation(uint8_t *LocalAddress,
144 uint64_t FinalAddress,
145 uint64_t Value,
146 uint32_t Type,
147 int64_t Addend) {
261148 switch (Arch) {
262149 case Triple::x86_64:
263 resolveX86_64Relocation(Name, Addr, RE);
150 resolveX86_64Relocation(LocalAddress, FinalAddress, Value, Type, Addend);
264151 break;
265152 case Triple::x86:
266 resolveX86Relocation(Name, Addr, RE);
267 break;
268 case Triple::arm:
269 resolveArmRelocation(Name, Addr, RE);
153 resolveX86Relocation(LocalAddress, (uint32_t)(FinalAddress & 0xffffffffL),
154 (uint32_t)(Value & 0xffffffffL), Type,
155 (uint32_t)(Addend & 0xffffffffL));
156 break;
157 case Triple::arm: // Fall through.
158 case Triple::thumb:
159 resolveARMRelocation(LocalAddress, (uint32_t)(FinalAddress & 0xffffffffL),
160 (uint32_t)(Value & 0xffffffffL), Type,
161 (uint32_t)(Addend & 0xffffffffL));
270162 break;
271163 default: llvm_unreachable("Unsupported CPU type!");
272164 }
273165 }
274166
275 void RuntimeDyldELF::reassignSymbolAddress(StringRef Name, uint8_t *Addr) {
276 // FIXME: deprecated. switch to reassignSectionAddress() instead.
277 //
278 // Actually moving the symbol address requires by-section mapping.
279 assert(Sections[SymbolTable.lookup(Name).first].base() == (void*)Addr &&
280 "Unable to relocate section in by-function JIT allocation model!");
281
282 RelocationList &Relocs = Relocations[Name];
283 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
284 RelocationEntry &RE = Relocs[i];
285 resolveRelocation(Name, Addr, RE);
286 }
287 }
288
289 // Assign an address to a symbol name and resolve all the relocations
290 // associated with it.
291 void RuntimeDyldELF::reassignSectionAddress(unsigned SectionID, uint64_t Addr) {
292 // The address to use for relocation resolution is not
293 // the address of the local section buffer. We must be doing
294 // a remote execution environment of some sort. Re-apply any
295 // relocations referencing this section with the given address.
296 //
297 // Addr is a uint64_t because we can't assume the pointer width
298 // of the target is the same as that of the host. Just use a generic
299 // "big enough" type.
300 assert(0);
167 void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
168 const ObjectFile &Obj,
169 ObjSectionToIDMap &ObjSectionToID,
170 LocalSymbolMap &Symbols,
171 StubMap &Stubs) {
172
173 uint32_t RelType = (uint32_t)(Rel.Type & 0xffffffffL);
174 intptr_t Addend = (intptr_t)Rel.AdditionalInfo;
175 RelocationValueRef Value;
176 StringRef TargetName;
177 const SymbolRef &Symbol = Rel.Symbol;
178 Symbol.getName(TargetName);
179 DEBUG(dbgs() << "\t\tRelType: " << RelType
180 << " Addend: " << Addend
181 << " TargetName: " << TargetName
182 << "\n");
183 // First look the symbol in object file symbols.
184 LocalSymbolMap::iterator lsi = Symbols.find(TargetName.data());
185 if (lsi != Symbols.end()) {
186 Value.SectionID = lsi->second.first;
187 Value.Addend = lsi->second.second;
188 } else {
189 // Second look the symbol in global symbol table.
190 StringMap::iterator gsi = SymbolTable.find(TargetName.data());
191 if (gsi != SymbolTable.end()) {
192 Value.SectionID = gsi->second.first;
193 Value.Addend = gsi->second.second;
194 } else {
195 SymbolRef::Type SymType;
196 Symbol.getType(SymType);
197 switch (SymType) {
198 case SymbolRef::ST_Debug: {
199 // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously
200 // and can be changed by another developers. Maybe best way is add
201 // a new symbol type ST_Section to SymbolRef and use it.
202 section_iterator si = Obj.end_sections();
203 Symbol.getSection(si);
204 if (si == Obj.end_sections())
205 llvm_unreachable("Symbol section not found, bad object file format!");
206 DEBUG(dbgs() << "\t\tThis is section symbol\n");
207 Value.SectionID = findOrEmitSection((*si), true, ObjSectionToID);
208 Value.Addend = Addend;
209 break;
210 }
211 case SymbolRef::ST_Unknown: {
212 Value.SymbolName = TargetName.data();
213 Value.Addend = Addend;
214 break;
215 }
216 default:
217 llvm_unreachable("Unresolved symbol type!");
218 break;
219 }
220 }
221 }
222 DEBUG(dbgs() << "\t\tRel.SectionID: " << Rel.SectionID
223 << " Rel.Offset: " << Rel.Offset
224 << "\n");
225 if (Arch == Triple::arm &&
226 (RelType == ELF::R_ARM_PC24 ||
227 RelType == ELF::R_ARM_CALL ||
228 RelType == ELF::R_ARM_JUMP24)) {
229 // This is an ARM branch relocation, need to use a stub function.
230 DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.");
231 SectionEntry &Section = Sections[Rel.SectionID];
232 uint8_t *Target = Section.Address + Rel.Offset;
233
234 // Look up for existing stub.
235 StubMap::const_iterator i = Stubs.find(Value);
236 if (i != Stubs.end()) {
237 resolveRelocation(Target, Section.LoadAddress, (uint64_t)Section.Address +
238 i->second, RelType, 0);
239 DEBUG(dbgs() << " Stub function found\n");
240 } else {
241 // Create a new stub function.
242 DEBUG(dbgs() << " Create a new stub function\n");
243 Stubs[Value] = Section.StubOffset;
244 uint8_t *StubTargetAddr = createStubFunction(Section.Address +
245 Section.StubOffset);
246 AddRelocation(Value, Rel.SectionID,
247 StubTargetAddr - Section.Address, ELF::R_ARM_ABS32);
248 resolveRelocation(Target, Section.LoadAddress, (uint64_t)Section.Address +
249 Section.StubOffset, RelType, 0);
250 Section.StubOffset += getMaxStubSize();
251 }
252 } else
253 AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType);
301254 }
302255
303256 bool RuntimeDyldELF::isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
2020
2121 namespace llvm {
2222 class RuntimeDyldELF : public RuntimeDyldImpl {
23 // For each symbol, keep a list of relocations based on it. Anytime
24 // its address is reassigned (the JIT re-compiled the function, e.g.),
25 // the relocations get re-resolved.
26 struct RelocationEntry {
27 // Function or section this relocation is contained in.
28 std::string Target;
29 // Offset into the target function or section for the relocation.
30 uint32_t Offset;
31 // Relocation type
32 uint32_t Type;
33 // Addend encoded in the instruction itself, if any.
34 int32_t Addend;
35 // Has the relocation been recalcuated as an offset within a function?
36 bool IsFunctionRelative;
37 // Has this relocation been resolved previously?
38 bool isResolved;
23 protected:
24 void resolveX86_64Relocation(uint8_t *LocalAddress,
25 uint64_t FinalAddress,
26 uint64_t Value,
27 uint32_t Type,
28 int64_t Addend);
3929
40 RelocationEntry(StringRef t,
41 uint32_t offset,
42 uint32_t type,
43 int32_t addend,
44 bool isFunctionRelative)
45 : Target(t)
46 , Offset(offset)
47 , Type(type)
48 , Addend(addend)
49 , IsFunctionRelative(isFunctionRelative)
50 , isResolved(false) { }
51 };
52 typedef SmallVector RelocationList;
53 StringMap Relocations;
54 unsigned Arch;
30 void resolveX86Relocation(uint8_t *LocalAddress,
31 uint32_t FinalAddress,
32 uint32_t Value,
33 uint32_t Type,
34 int32_t Addend);
5535
56 void resolveRelocations();
36 void resolveARMRelocation(uint8_t *LocalAddress,
37 uint32_t FinalAddress,
38 uint32_t Value,
39 uint32_t Type,
40 int32_t Addend);
5741
58 void resolveX86_64Relocation(StringRef Name,
59 uint8_t *Addr,
60 const RelocationEntry &RE);
42 virtual void resolveRelocation(uint8_t *LocalAddress,
43 uint64_t FinalAddress,
44 uint64_t Value,
45 uint32_t Type,
46 int64_t Addend);
6147
62 void resolveX86Relocation(StringRef Name,
63 uint8_t *Addr,
64 const RelocationEntry &RE);
65
66 void resolveArmRelocation(StringRef Name,
67 uint8_t *Addr,
68 const RelocationEntry &RE);
69
70 void resolveRelocation(StringRef Name,
71 uint8_t *Addr,
72 const RelocationEntry &RE);
48 virtual void processRelocationRef(const ObjRelocationInfo &Rel,
49 const ObjectFile &Obj,
50 ObjSectionToIDMap &ObjSectionToID,
51 LocalSymbolMap &Symbols, StubMap &Stubs);
7352
7453 public:
7554 RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
76
77 bool loadObject(MemoryBuffer *InputBuffer);
78
79 void reassignSymbolAddress(StringRef Name, uint8_t *Addr);
80 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
8155
8256 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
8357 };
8458
8559 } // end namespace llvm
8660
87 #endif
88
89 //===-- RuntimeDyldELF.h - Run-time dynamic linker for MC-JIT ---*- C++ -*-===//
90 //
91 // The LLVM Compiler Infrastructure
92 //
93 // This file is distributed under the University of Illinois Open Source
94 // License. See LICENSE.TXT for details.
95 //
96 //===----------------------------------------------------------------------===//
97 //
98 // ELF support for MC-JIT runtime dynamic linker.
99 //
100 //===----------------------------------------------------------------------===//
101
102 #ifndef LLVM_RUNTIME_DYLD_ELF_H
103 #define LLVM_RUNTIME_DYLD_ELF_H
104
105 #include "RuntimeDyldImpl.h"
106
107 using namespace llvm;
108
109
110 namespace llvm {
111 class RuntimeDyldELF : public RuntimeDyldImpl {
112 // For each symbol, keep a list of relocations based on it. Anytime
113 // its address is reassigned (the JIT re-compiled the function, e.g.),
114 // the relocations get re-resolved.
115 struct RelocationEntry {
116 // Function or section this relocation is contained in.
117 std::string Target;
118 // Offset into the target function or section for the relocation.
119 uint32_t Offset;
120 // Relocation type
121 uint32_t Type;
122 // Addend encoded in the instruction itself, if any.
123 int32_t Addend;
124 // Has the relocation been recalcuated as an offset within a function?
125 bool IsFunctionRelative;
126 // Has this relocation been resolved previously?
127 bool isResolved;
128
129 RelocationEntry(StringRef t,
130 uint32_t offset,
131 uint32_t type,
132 int32_t addend,
133 bool isFunctionRelative)
134 : Target(t)
135 , Offset(offset)
136 , Type(type)
137 , Addend(addend)
138 , IsFunctionRelative(isFunctionRelative)
139 , isResolved(false) { }
140 };
141 typedef SmallVector RelocationList;
142 StringMap Relocations;
143 unsigned Arch;
144
145 void resolveRelocations();
146
147 void resolveX86_64Relocation(StringRef Name,
148 uint8_t *Addr,
149 const RelocationEntry &RE);
150
151 void resolveX86Relocation(StringRef Name,
152 uint8_t *Addr,
153 const RelocationEntry &RE);
154
155 void resolveArmRelocation(StringRef Name,
156 uint8_t *Addr,
157 const RelocationEntry &RE);
158
159 void resolveRelocation(StringRef Name,
160 uint8_t *Addr,
161 const RelocationEntry &RE);
162
163 public:
164 RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
165
166 bool loadObject(MemoryBuffer *InputBuffer);
167
168 void reassignSymbolAddress(StringRef Name, uint8_t *Addr);
169 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
170
171 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
172 };
173
174 } // end namespace llvm
175
176 #endif
177
61 #endif
1414 #define LLVM_RUNTIME_DYLD_IMPL_H
1515
1616 #include "llvm/ExecutionEngine/RuntimeDyld.h"
17 #include "llvm/Object/ObjectFile.h"
1718 #include "llvm/ADT/DenseMap.h"
1819 #include "llvm/ADT/StringMap.h"
1920 #include "llvm/ADT/Twine.h"
2021 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ExecutionEngine/ExecutionEngine.h"
2222 #include "llvm/Support/Memory.h"
2323 #include "llvm/Support/MemoryBuffer.h"
2424 #include "llvm/Support/system_error.h"
2525 #include "llvm/Support/raw_ostream.h"
2626 #include "llvm/Support/Debug.h"
2727 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/ADT/Triple.h"
29 #include
30 #include "llvm/Support/Format.h"
2831
2932 using namespace llvm;
33 using namespace llvm::object;
3034
3135 namespace llvm {
36
37 class SectionEntry {
38 public:
39 uint8_t* Address;
40 size_t Size;
41 uint64_t LoadAddress; // For each section, the address it will be
42 // considered to live at for relocations. The same
43 // as the pointer to the above memory block for
44 // hosted JITs.
45 uintptr_t StubOffset; // It's used for architecturies with stub
46 // functions for far relocations like ARM.
47 uintptr_t ObjAddress; // Section address in object file. It's use for
48 // calculate MachO relocation addend
49 SectionEntry(uint8_t* address, size_t size, uintptr_t stubOffset,
50 uintptr_t objAddress)
51 : Address(address), Size(size), LoadAddress((uintptr_t)address),
52 StubOffset(stubOffset), ObjAddress(objAddress) {}
53 };
54
55 class RelocationEntry {
56 public:
57 unsigned SectionID; // Section the relocation is contained in.
58 uintptr_t Offset; // Offset into the section for the relocation.
59 uint32_t Data; // Relocatino data. Including type of relocation
60 // and another flags and parameners from
61 intptr_t Addend; // Addend encoded in the instruction itself, if any,
62 // plus the offset into the source section for
63 // the symbol once the relocation is resolvable.
64 RelocationEntry(unsigned id, uint64_t offset, uint32_t data, int64_t addend)
65 : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
66 };
67
68 // Raw relocation data from object file
69 class ObjRelocationInfo {
70 public:
71 unsigned SectionID;
72 uint64_t Offset;
73 SymbolRef Symbol;
74 uint64_t Type;
75 int64_t AdditionalInfo;
76 };
77
78 class RelocationValueRef {
79 public:
80 unsigned SectionID;
81 intptr_t Addend;
82 const char *SymbolName;
83 RelocationValueRef(): SectionID(0), Addend(0), SymbolName(0) {}
84
85 inline bool operator==(const RelocationValueRef &Other) const {
86 return std::memcmp(this, &Other, sizeof(RelocationValueRef)) == 0;
87 }
88 inline bool operator <(const RelocationValueRef &Other) const {
89 return std::memcmp(this, &Other, sizeof(RelocationValueRef)) < 0;
90 }
91 };
92
3293 class RuntimeDyldImpl {
3394 protected:
34 unsigned CPUType;
35 unsigned CPUSubtype;
36
3795 // The MemoryManager to load objects into.
3896 RTDyldMemoryManager *MemMgr;
3997
40 // For each section, we have a MemoryBlock of it's data.
41 // Indexed by SectionID.
42 SmallVector Sections;
43 // For each section, the address it will be considered to live at for
44 // relocations. The same as the pointer to the above memory block for hosted
45 // JITs. Indexed by SectionID.
46 SmallVector SectionLoadAddress;
47
48 // Keep a map of starting local address to the SectionID which references it.
49 // Lookup function for when we assign virtual addresses.
50 DenseMap SectionLocalMemToID;
98 // A list of emmitted sections.
99 typedef SmallVector SectionList;
100 SectionList Sections;
101
102 // Keep a map of sections from object file to the SectionID which
103 // references it.
104 typedef std::map ObjSectionToIDMap;
51105
52106 // Master symbol table. As modules are loaded and external symbols are
53107 // resolved, their addresses are stored here as a SectionID/Offset pair.
54 typedef std::pair64_t> SymbolLoc;
108 typedef std::pairptr_t> SymbolLoc;
55109 StringMap SymbolTable;
110 typedef DenseMap LocalSymbolMap;
111
112 // For each symbol, keep a list of relocations based on it. Anytime
113 // its address is reassigned (the JIT re-compiled the function, e.g.),
114 // the relocations get re-resolved.
115 // The symbol (or section) the relocation is sourced from is the Key
116 // in the relocation list where it's stored.
117 typedef SmallVector RelocationList;
118 // Relocations to sections already loaded. Indexed by SectionID which is the
119 // source of the address. The target where the address will be writen is
120 // SectionID/Offset in the relocation itself.
121 DenseMap Relocations;
122 // Relocations to external symbols that are not yet resolved.
123 // Indexed by symbol name.
124 StringMap SymbolRelocations;
125
126 typedef std::map StubMap;
127
128 Triple::ArchType Arch;
129
130 inline unsigned getMaxStubSize() {
131 if (Arch == Triple::arm || Arch == Triple::thumb)
132 return 8; // 32-bit instruction and 32-bit address
133 else
134 return 0;
135 }
56136
57137 bool HasError;
58138 std::string ErrorStr;
65145 }
66146
67147 uint8_t *getSectionAddress(unsigned SectionID) {
68 return (uint8_t*)Sections[SectionID].base();
69 }
70 void extractFunction(StringRef Name, uint8_t *StartAddress,
71 uint8_t *EndAddress);
72
148 return (uint8_t*)Sections[SectionID].Address;
149 }
150
151 /// \brief Emits section data from the object file to the MemoryManager.
152 /// \param IsCode if it's true then allocateCodeSection() will be
153 /// used for emmits, else allocateDataSection() will be used.
154 /// \return SectionID.
155 unsigned emitSection(const SectionRef &Section, bool IsCode);
156
157 /// \brief Find Section in LocalSections. If the secton is not found - emit
158 /// it and store in LocalSections.
159 /// \param IsCode if it's true then allocateCodeSection() will be
160 /// used for emmits, else allocateDataSection() will be used.
161 /// \return SectionID.
162 unsigned findOrEmitSection(const SectionRef &Section, bool IsCode,
163 ObjSectionToIDMap &LocalSections);
164
165 /// \brief If Value.SymbolName is NULL then store relocation to the
166 /// Relocations, else store it in the SymbolRelocations.
167 void AddRelocation(const RelocationValueRef &Value, unsigned SectionID,
168 uintptr_t Offset, uint32_t RelType);
169
170 /// \brief Emits long jump instruction to Addr.
171 /// \return Pointer to the memory area for emitting target address.
172 uint8_t* createStubFunction(uint8_t *Addr);
173
174 /// \brief Resolves relocations from Relocs list with address from Value.
175 void resolveRelocationList(const RelocationList &Relocs, uint64_t Value);
176 void resolveRelocationEntry(const RelocationEntry &RE, uint64_t Value);
177
178 /// \brief A object file specific relocation resolver
179 /// \param Address Address to apply the relocation action
180 /// \param Value Target symbol address to apply the relocation action
181 /// \param Type object file specific relocation type
182 /// \param Addend A constant addend used to compute the value to be stored
183 /// into the relocatable field
184 virtual void resolveRelocation(uint8_t *LocalAddress,
185 uint64_t FinalAddress,
186 uint64_t Value,
187 uint32_t Type,
188 int64_t Addend) = 0;
189
190 /// \brief Parses the object file relocation and store it to Relocations
191 /// or SymbolRelocations. Its depend from object file type.
192 virtual void processRelocationRef(const ObjRelocationInfo &Rel,
193 const ObjectFile &Obj,
194 ObjSectionToIDMap &ObjSectionToID,
195 LocalSymbolMap &Symbols, StubMap &Stubs) = 0;
196
197 void resolveSymbols();
73198 public:
74199 RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
75200
76201 virtual ~RuntimeDyldImpl();
77202
78 virtual bool loadObject(MemoryBuffer *InputBuffer) = 0;
203 bool loadObject(const MemoryBuffer *InputBuffer);
79204
80205 void *getSymbolAddress(StringRef Name) {
81206 // FIXME: Just look up as a function for now. Overly simple of course.
86211 return getSectionAddress(Loc.first) + Loc.second;
87212 }
88213
89 virtual void resolveRelocations();
90
91 virtual void reassignSectionAddress(unsigned SectionID, uint64_t Addr) = 0;
214 void resolveRelocations();
215
216 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
92217
93218 void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress);
94219
102227 StringRef getErrorString() { return ErrorStr; }
103228
104229 virtual bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const = 0;
230
105231 };
106232
107233 } // end namespace llvm
2020
2121 namespace llvm {
2222
23 bool RuntimeDyldMachO::
24 resolveRelocation(uint8_t *LocalAddress,
25 uint64_t FinalAddress,
26 uint64_t Value,
27 bool isPCRel,
28 unsigned Type,
29 unsigned Size,
30 int64_t Addend) {
23 void RuntimeDyldMachO::resolveRelocation(uint8_t *LocalAddress,
24 uint64_t FinalAddress,
25 uint64_t Value,
26 uint32_t Type,
27 int64_t Addend) {
28 bool isPCRel = (Type >> 24) & 1;
29 unsigned MachoType = (Type >> 28) & 0xf;
30 unsigned Size = 1 << ((Type >> 25) & 3);
31
32 DEBUG(dbgs() << "resolveRelocation LocalAddress: " << format("%p", LocalAddress)
33 << " FinalAddress: " << format("%p", FinalAddress)
34 << " Value: " << format("%p", Value)
35 << " Addend: " << Addend
36 << " isPCRel: " << isPCRel
37 << " MachoType: " << MachoType
38 << " Size: " << Size
39 << "\n");
40
3141 // This just dispatches to the proper target specific routine.
32 switch (CPUType) {
42 switch (Arch) {
3343 default: llvm_unreachable("Unsupported CPU type!");
34 case mach::CTM_i386:
35 return resolveI386Relocation(LocalAddress,
44 case Triple::x86_64:
45 resolveX86_64Relocation(LocalAddress,
46 FinalAddress,
47 (uintptr_t)Value,
48 isPCRel,
49 MachoType,
50 Size,
51 Addend);
52 break;
53 case Triple::x86:
54 resolveI386Relocation(LocalAddress,
3655 FinalAddress,
3756 (uintptr_t)Value,
3857 isPCRel,
3958 Type,
4059 Size,
4160 Addend);
42 case mach::CTM_x86_64:
43 return resolveX86_64Relocation(LocalAddress,
44 FinalAddress,
45 (uintptr_t)Value,
46 isPCRel,
47 Type,
48 Size,
49 Addend);
50 case mach::CTM_ARM:
51 return resolveARMRelocation(LocalAddress,
52 FinalAddress,
53 (uintptr_t)Value,
54 isPCRel,
55 Type,
56 Size,
57 Addend);
61 break;
62 case Triple::arm: // Fall through.
63 case Triple::thumb:
64 resolveARMRelocation(LocalAddress,
65 FinalAddress,
66 (uintptr_t)Value,
67 isPCRel,
68 MachoType,
69 Size,
70 Addend);
71 break;
5872 }
5973 }
6074
189203 return false;
190204 }
191205
192 bool RuntimeDyldMachO::
193 loadSegment32(const MachOObject *Obj,
194 const MachOObject::LoadCommandInfo *SegmentLCI,
195 const InMemoryStruct &SymtabLC) {
196 // FIXME: This should really be combined w/ loadSegment64. Templatized
197 // function on the 32/64 datatypes maybe?
198 InMemoryStruct SegmentLC;
199 Obj->ReadSegmentLoadCommand(*SegmentLCI, SegmentLC);
200 if (!SegmentLC)
201 return Error("unable to load segment load command");
202
203
204 SmallVector SectionMap;
205 for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
206 InMemoryStruct Sect;
207 Obj->ReadSection(*SegmentLCI, SectNum, Sect);
208 if (!Sect)
209 return Error("unable to load section: '" + Twine(SectNum) + "'");
210
211 // Allocate memory via the MM for the section.
212 uint8_t *Buffer;
213 uint32_t SectionID = Sections.size();
214 if (Sect->Flags == 0x80000400)
215 Buffer = MemMgr->allocateCodeSection(Sect->Size, Sect->Align, SectionID);
216 else
217 Buffer = MemMgr->allocateDataSection(Sect->Size, Sect->Align, SectionID);
218
219 DEBUG(dbgs() << "Loading "
220 << ((Sect->Flags == 0x80000400) ? "text" : "data")
221 << " (ID #" << SectionID << ")"
222 << " '" << Sect->SegmentName << ","
223 << Sect->Name << "' of size " << Sect->Size
224 << " to address " << Buffer << ".\n");
225
226 // Copy the payload from the object file into the allocated buffer.
227 uint8_t *Base = (uint8_t*)Obj->getData(SegmentLC->FileOffset,
228 SegmentLC->FileSize).data();
229 memcpy(Buffer, Base + Sect->Address, Sect->Size);
230
231 // Remember what got allocated for this SectionID.
232 Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size));
233 SectionLocalMemToID[Buffer] = SectionID;
234
235 // By default, the load address of a section is its memory buffer.
236 SectionLoadAddress.push_back((uint64_t)Buffer);
237
238 // Keep a map of object file section numbers to corresponding SectionIDs
239 // while processing the file.
240 SectionMap.push_back(SectionID);
241 }
242
243 // Process the symbol table.
244 SmallVector SymbolNames;
245 processSymbols32(Obj, SectionMap, SymbolNames, SymtabLC);
246
247 // Process the relocations for each section we're loading.
248 Relocations.grow(Relocations.size() + SegmentLC->NumSections);
249 Referrers.grow(Referrers.size() + SegmentLC->NumSections);
250 for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
251 InMemoryStruct Sect;
252 Obj->ReadSection(*SegmentLCI, SectNum, Sect);
253 if (!Sect)
254 return Error("unable to load section: '" + Twine(SectNum) + "'");
255 for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) {
256 InMemoryStruct RE;
257 Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE);
258 if (RE->Word0 & macho::RF_Scattered)
259 return Error("NOT YET IMPLEMENTED: scattered relocations.");
260 // Word0 of the relocation is the offset into the section where the
261 // relocation should be applied. We need to translate that into an
262 // offset into a function since that's our atom.
263 uint32_t Offset = RE->Word0;
264 bool isExtern = (RE->Word1 >> 27) & 1;
265
266 // FIXME: Get the relocation addend from the target address.
267 // FIXME: VERY imporant for internal relocations.
268
269 // Figure out the source symbol of the relocation. If isExtern is true,
270 // this relocation references the symbol table, otherwise it references
271 // a section in the same object, numbered from 1 through NumSections
272 // (SectionBases is [0, NumSections-1]).
273 uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value
274 if (!isExtern) {
275 assert(SourceNum > 0 && "Invalid relocation section number!");
276 unsigned SectionID = SectionMap[SourceNum - 1];
277 unsigned TargetID = SectionMap[SectNum];
278 DEBUG(dbgs() << "Internal relocation at Section #"
279 << TargetID << " + " << Offset
280 << " from Section #"
281 << SectionID << " (Word1: "
282 << format("0x%x", RE->Word1) << ")\n");
283
284 // Store the relocation information. It will get resolved when
285 // the section addresses are assigned.
286 uint32_t RelocationIndex = Relocations[SectionID].size();
287 Relocations[SectionID].push_back(RelocationEntry(TargetID,
288 Offset,
289 RE->Word1,
290 0 /*Addend*/));
291 Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex));
292 } else {
293 StringRef SourceName = SymbolNames[SourceNum];
294
295 // Now store the relocation information. Associate it with the source
296 // symbol. Just add it to the unresolved list and let the general
297 // path post-load resolve it if we know where the symbol is.
298 UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum,
299 Offset,
300 RE->Word1,
301 0 /*Addend*/));
302 DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset
303 << " from '" << SourceName << "(Word1: "
304 << format("0x%x", RE->Word1) << ")\n");
305 }
306 }
307 }
308
309 // Resolve the addresses of any symbols that were defined in this segment.
310 for (int i = 0, e = SymbolNames.size(); i != e; ++i)
311 resolveSymbol(SymbolNames[i]);
312
313 return false;
314 }
315
316
317 bool RuntimeDyldMachO::
318 loadSegment64(const MachOObject *Obj,
319 const MachOObject::LoadCommandInfo *SegmentLCI,
320 const InMemoryStruct &SymtabLC) {
321 InMemoryStruct Segment64LC;
322 Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC);
323 if (!Segment64LC)
324 return Error("unable to load segment load command");
325
326
327 SmallVector SectionMap;
328 for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
329 InMemoryStruct Sect;
330 Obj->ReadSection64(*SegmentLCI, SectNum, Sect);
331 if (!Sect)
332 return Error("unable to load section: '" + Twine(SectNum) + "'");
333
334 // Allocate memory via the MM for the section.
335 uint8_t *Buffer;
336 uint32_t SectionID = Sections.size();
337 unsigned Align = 1 << Sect->Align; // .o file has log2 alignment.
338 if (Sect->Flags == 0x80000400)
339 Buffer = MemMgr->allocateCodeSection(Sect->Size, Align, SectionID);
340 else
341 Buffer = MemMgr->allocateDataSection(Sect->Size, Align, SectionID);
342
343 DEBUG(dbgs() << "Loading "
344 << ((Sect->Flags == 0x80000400) ? "text" : "data")
345 << " (ID #" << SectionID << ")"
346 << " '" << Sect->SegmentName << ","
347 << Sect->Name << "' of size " << Sect->Size
348 << " (align " << Align << ")"
349 << " to address " << Buffer << ".\n");
350
351 // Copy the payload from the object file into the allocated buffer.
352 uint8_t *Base = (uint8_t*)Obj->getData(Segment64LC->FileOffset,
353 Segment64LC->FileSize).data();
354 memcpy(Buffer, Base + Sect->Address, Sect->Size);
355
356 // Remember what got allocated for this SectionID.
357 Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size));
358 SectionLocalMemToID[Buffer] = SectionID;
359
360 // By default, the load address of a section is its memory buffer.
361 SectionLoadAddress.push_back((uint64_t)Buffer);
362
363 // Keep a map of object file section numbers to corresponding SectionIDs
364 // while processing the file.
365 SectionMap.push_back(SectionID);
366 }
367
368 // Process the symbol table.
369 SmallVector SymbolNames;
370 processSymbols64(Obj, SectionMap, SymbolNames, SymtabLC);
371
372 // Process the relocations for each section we're loading.
373 Relocations.grow(Relocations.size() + Segment64LC->NumSections);
374 Referrers.grow(Referrers.size() + Segment64LC->NumSections);
375 for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
376 InMemoryStruct Sect;
377 Obj->ReadSection64(*SegmentLCI, SectNum, Sect);
378 if (!Sect)
379 return Error("unable to load section: '" + Twine(SectNum) + "'");
380 for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) {
381 InMemoryStruct RE;
382 Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE);
383 if (RE->Word0 & macho::RF_Scattered)
384 return Error("NOT YET IMPLEMENTED: scattered relocations.");
385 // Word0 of the relocation is the offset into the section where the
386 // relocation should be applied. We need to translate that into an
387 // offset into a function since that's our atom.
388 uint32_t Offset = RE->Word0;
389 bool isExtern = (RE->Word1 >> 27) & 1;
390
391 // FIXME: Get the relocation addend from the target address.
392 // FIXME: VERY imporant for internal relocations.
393
394 // Figure out the source symbol of the relocation. If isExtern is true,
395 // this relocation references the symbol table, otherwise it references
396 // a section in the same object, numbered from 1 through NumSections
397 // (SectionBases is [0, NumSections-1]).
398 uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value
399 if (!isExtern) {
400 assert(SourceNum > 0 && "Invalid relocation section number!");
401 unsigned SectionID = SectionMap[SourceNum - 1];
402 unsigned TargetID = SectionMap[SectNum];
403 DEBUG(dbgs() << "Internal relocation at Section #"
404 << TargetID << " + " << Offset
405 << " from Section #"
406 << SectionID << " (Word1: "
407 << format("0x%x", RE->Word1) << ")\n");
408
409 // Store the relocation information. It will get resolved when
410 // the section addresses are assigned.
411 uint32_t RelocationIndex = Relocations[SectionID].size();
412 Relocations[SectionID].push_back(RelocationEntry(TargetID,
413 Offset,
414 RE->Word1,
415 0 /*Addend*/));
416 Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex));
417 } else {
418 StringRef SourceName = SymbolNames[SourceNum];
419
420 // Now store the relocation information. Associate it with the source
421 // symbol. Just add it to the unresolved list and let the general
422 // path post-load resolve it if we know where the symbol is.
423 UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum,
424 Offset,
425 RE->Word1,
426 0 /*Addend*/));
427 DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset
428 << " from '" << SourceName << "(Word1: "
429 << format("0x%x", RE->Word1) << ")\n");
430 }
431 }
432 }
433
434 // Resolve the addresses of any symbols that were defined in this segment.
435 for (int i = 0, e = SymbolNames.size(); i != e; ++i)
436 resolveSymbol(SymbolNames[i]);
437
438 return false;
439 }
440
441 bool RuntimeDyldMachO::
442 processSymbols32(const MachOObject *Obj,
443 SmallVectorImpl &SectionMap,
444 SmallVectorImpl &SymbolNames,
445 const InMemoryStruct &SymtabLC) {
446 // FIXME: Combine w/ processSymbols64. Factor 64/32 datatype and such.
447 for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
448 InMemoryStruct STE;
449 Obj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE);
450 if (!STE)
451 return Error("unable to read symbol: '" + Twine(i) + "'");
452 // Get the symbol name.
453 StringRef Name = Obj->getStringAtIndex(STE->StringIndex);
454 SymbolNames.push_back(Name);
455
456 // FIXME: Check the symbol type and flags.
457 if (STE->Type != 0xF) // external, defined in this segment.
458 continue;
459 // Flags in the upper nibble we don't care about.
460 if ((STE->Flags & 0xf) != 0x0)
461 continue;
462
463 // Remember the symbol.
464 uint32_t SectionID = SectionMap[STE->SectionIndex - 1];
465 SymbolTable[Name] = SymbolLoc(SectionID, STE->Value);
466
467 DEBUG(dbgs() << "Symbol: '" << Name << "' @ "
468 << (getSectionAddress(SectionID) + STE->Value)
469 << "\n");
470 }
471 return false;
472 }
473
474 bool RuntimeDyldMachO::
475 processSymbols64(const MachOObject *Obj,
476 SmallVectorImpl &SectionMap,
477 SmallVectorImpl &SymbolNames,
478 const InMemoryStruct &SymtabLC) {
479 for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
480 InMemoryStruct STE;
481 Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE);
482 if (!STE)
483 return Error("unable to read symbol: '" + Twine(i) + "'");
484 // Get the symbol name.
485 StringRef Name = Obj->getStringAtIndex(STE->StringIndex);
486 SymbolNames.push_back(Name);
487
488 // FIXME: Check the symbol type and flags.
489 if (STE->Type != 0xF) // external, defined in this segment.
490 continue;
491 // Flags in the upper nibble we don't care about.
492 if ((STE->Flags & 0xf) != 0x0)
493 continue;
494
495 // Remember the symbol.
496 uint32_t SectionID = SectionMap[STE->SectionIndex - 1];
497 SymbolTable[Name] = SymbolLoc(SectionID, STE->Value);
498
499 DEBUG(dbgs() << "Symbol: '" << Name << "' @ "
500 << (getSectionAddress(SectionID) + STE->Value)
501 << "\n");
502 }
503 return false;
504 }
505
506 // resolveSymbol - Resolve any relocations to the specified symbol if
507 // we know where it lives.
508 void RuntimeDyldMachO::resolveSymbol(StringRef Name) {
509 StringMap::const_iterator Loc = SymbolTable.find(Name);
510 if (Loc == SymbolTable.end())
511 return;
512
513 RelocationList &Relocs = UnresolvedRelocations[Name];
514 DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n");
515 for (int i = 0, e = Relocs.size(); i != e; ++i) {
516 // Change the relocation to be section relative rather than symbol
517 // relative and move it to the resolved relocation list.
518 RelocationEntry Entry = Relocs[i];
519 Entry.Addend += Loc->second.second;
520 uint32_t RelocationIndex = Relocations[Loc->second.first].size();
521 Relocations[Loc->second.first].push_back(Entry);
522 Referrers[Entry.SectionID].push_back(Referrer(Loc->second.first, RelocationIndex));
523 }
524 // FIXME: Keep a worklist of the relocations we've added so that we can
525 // resolve more selectively later.
526 Relocs.clear();
527 }
528
529 bool RuntimeDyldMachO::loadObject(MemoryBuffer *InputBuffer) {
530 // If the linker is in an error state, don't do anything.
531 if (hasError())
532 return true;
533 // Load the Mach-O wrapper object.
534 std::string ErrorStr;
535 OwningPtr Obj(
536 MachOObject::LoadFromBuffer(InputBuffer, &ErrorStr));
537 if (!Obj)
538 return Error("unable to load object: '" + ErrorStr + "'");
539
540 // Get the CPU type information from the header.
541 const macho::Header &Header = Obj->getHeader();
542
543 // FIXME: Error checking that the loaded object is compatible with
544 // the system we're running on.
545 CPUType = Header.CPUType;
546 CPUSubtype = Header.CPUSubtype;
547
548 // Validate that the load commands match what we expect.
549 const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0,
550 *DysymtabLCI = 0;
551 for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
552 const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i);
553 switch (LCI.Command.Type) {
554 case macho::LCT_Segment:
555 case macho::LCT_Segment64:
556 if (SegmentLCI)
557 return Error("unexpected input object (multiple segments)");
558 SegmentLCI = &LCI;
559 break;
560 case macho::LCT_Symtab:
561 if (SymtabLCI)
562 return Error("unexpected input object (multiple symbol tables)");
563 SymtabLCI = &LCI;
564 break;
565 case macho::LCT_Dysymtab:
566 if (DysymtabLCI)
567 return Error("unexpected input object (multiple symbol tables)");
568 DysymtabLCI = &LCI;
569 break;
570 default:
571 return Error("unexpected input object (unexpected load command");
572 }
573 }
574
575 if (!SymtabLCI)
576 return Error("no symbol table found in object");
577 if (!SegmentLCI)
578 return Error("no segments found in object");
579
580 // Read and register the symbol table data.
581 InMemoryStruct SymtabLC;
582 Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);
583 if (!SymtabLC)
584 return Error("unable to load symbol table load command");
585 Obj->RegisterStringTable(*SymtabLC);
586
587 // Read the dynamic link-edit information, if present (not present in static
588 // objects).
589 if (DysymtabLCI) {
590 InMemoryStruct DysymtabLC;
591 Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC);
592 if (!DysymtabLC)
593 return Error("unable to load dynamic link-exit load command");
594
595 // FIXME: We don't support anything interesting yet.
596 // if (DysymtabLC->LocalSymbolsIndex != 0)
597 // return Error("NOT YET IMPLEMENTED: local symbol entries");
598 // if (DysymtabLC->ExternalSymbolsIndex != 0)
599 // return Error("NOT YET IMPLEMENTED: non-external symbol entries");
600 // if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries)
601 // return Error("NOT YET IMPLEMENTED: undefined symbol entries");
602 }
603
604 // Load the segment load command.
605 if (SegmentLCI->Command.Type == macho::LCT_Segment) {
606 if (loadSegment32(Obj.get(), SegmentLCI, SymtabLC))
607 return true;
206 void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel,
207 const ObjectFile &Obj,
208 ObjSectionToIDMap &ObjSectionToID,
209 LocalSymbolMap &Symbols,
210 StubMap &Stubs) {
211
212 uint32_t RelType = (uint32_t) (Rel.Type & 0xffffffffL);
213 RelocationValueRef Value;
214 SectionEntry &Section = Sections[Rel.SectionID];
215 uint8_t *Target = Section.Address + Rel.Offset;
216
217 bool isExtern = (RelType >> 27) & 1;
218 if (isExtern) {
219 StringRef TargetName;
220 const SymbolRef &Symbol = Rel.Symbol;
221 Symbol.getName(TargetName);
222 // First look the symbol in object file symbols.
223 LocalSymbolMap::iterator lsi = Symbols.find(TargetName.data());
224 if (lsi != Symbols.end()) {
225 Value.SectionID = lsi->second.first;
226 Value.Addend = lsi->second.second;
227 } else {
228 // Second look the symbol in global symbol table.
229 StringMap::iterator gsi = SymbolTable.find(TargetName.data());
230 if (gsi != SymbolTable.end()) {
231 Value.SectionID = gsi->second.first;
232 Value.Addend = gsi->second.second;
233 } else
234 Value.SymbolName = TargetName.data();
235 }
608236 } else {
609 if (loadSegment64(Obj.get(), SegmentLCI, SymtabLC))
610 return true;
611 }
612
613 // Assign the addresses of the sections from the object so that any
614 // relocations to them get set properly.
615 // FIXME: This is done directly from the client at the moment. We should
616 // default the values to the local storage, at least when the target arch
617 // is the same as the host arch.
618
619 return false;
620 }
621
622 // Assign an address to a symbol name and resolve all the relocations
623 // associated with it.
624 void RuntimeDyldMachO::reassignSectionAddress(unsigned SectionID,
625 uint64_t Addr) {
626 // The address to use for relocation resolution is not
627 // the address of the local section buffer. We must be doing
628 // a remote execution environment of some sort. Re-apply any
629 // relocations referencing this section with the given address.
630 //
631 // Addr is a uint64_t because we can't assume the pointer width
632 // of the target is the same as that of the host. Just use a generic
633 // "big enough" type.
634
635 SectionLoadAddress[SectionID] = Addr;
636
637 RelocationList &Relocs = Relocations[SectionID];
638 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
639 RelocationEntry &RE = Relocs[i];
640 uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset;
641 uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset;
642 bool isPCRel = (RE.Data >> 24) & 1;
643 unsigned Type = (RE.Data >> 28) & 0xf;
644 unsigned Size = 1 << ((RE.Data >> 25) & 3);
645
646 DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID
647 << " + " << RE.Offset << " (" << format("%p", Target) << ")"
648 << " from Section #" << SectionID << " (" << format("%p", Addr) << ")"
649 << "(" << (isPCRel ? "pcrel" : "absolute")
650 << ", type: " << Type << ", Size: " << Size << ", Addend: "
651 << RE.Addend << ").\n");
652
653 resolveRelocation(Target,
654 FinalTarget,
655 Addr,
656 isPCRel,
657 Type,
658 Size,
659 RE.Addend);
660 }
661 ReferrerList &Refers = Referrers[SectionID];
662 for (unsigned i = 0, e = Refers.size(); i != e; ++i) {
663 Referrer &R = Refers[i];
664 RelocationEntry &RE = Relocations[R.SectionID][R.Index];
665 uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset;
666 uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset;
667 bool isPCRel = (RE.Data >> 24) & 1;
668 unsigned Type = (RE.Data >> 28) & 0xf;
669 unsigned Size = 1 << ((RE.Data >> 25) & 3);
670
671 DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID
672 << " + " << RE.Offset << " (" << format("%p", Target) << ")"
673 << " from Section #" << SectionID << " (" << format("%p", Addr) << ")"
674 << "(" << (isPCRel ? "pcrel" : "absolute")
675 << ", type: " << Type << ", Size: " << Size << ", Addend: "
676 << RE.Addend << ").\n");
677
678 resolveRelocation(Target,
679 FinalTarget,
680 Addr,
681 isPCRel,
682 Type,
683 Size,
684 RE.Addend);
685 }
686 }
687
688 bool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) {
237 error_code err;
238 uint8_t sectionIndex = static_cast(RelType & 0xFF);
239 section_iterator si = Obj.begin_sections(),
240 se = Obj.end_sections();
241 for (uint8_t i = 1; i < sectionIndex; i++) {
242 error_code err;
243 si.increment(err);
244 if (si == se)
245 break;
246 }
247 assert(si != se && "No section containing relocation!");
248 Value.SectionID = findOrEmitSection(*si, true, ObjSectionToID);
249 Value.Addend = *(const intptr_t *)Target;
250 if (Value.Addend) {
251 // The MachO addend is offset from the current section, we need set it
252 // as offset from destination section
253 Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress;
254 }
255 }
256
257 if (Arch == Triple::arm && RelType == macho::RIT_ARM_Branch24Bit) {
258 // This is an ARM branch relocation, need to use a stub function.
259
260 // Look up for existing stub.
261 StubMap::const_iterator i = Stubs.find(Value);
262 if (i != Stubs.end())
263 resolveRelocation(Target, (uint64_t)Target,
264 (uint64_t)Section.Address + i->second,
265 RelType, 0);
266 else {
267 // Create a new stub function.
268 Stubs[Value] = Section.StubOffset;
269 uint8_t *StubTargetAddr = createStubFunction(Section.Address +
270 Section.StubOffset);
271 AddRelocation(Value, Rel.SectionID, StubTargetAddr - Section.Address,
272 macho::RIT_Vanilla);
273 resolveRelocation(Target, (uint64_t)Target,
274 (uint64_t)Section.Address + Section.StubOffset,
275 RelType, 0);
276 Section.StubOffset += getMaxStubSize();
277 }
278 } else
279 AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType);
280 }
281
282
283 bool RuntimeDyldMachO::isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
689284 StringRef Magic = InputBuffer->getBuffer().slice(0, 4);
690285 if (Magic == "\xFE\xED\xFA\xCE") return true;
691286 if (Magic == "\xCE\xFA\xED\xFE") return true;
2424
2525 namespace llvm {
2626 class RuntimeDyldMachO : public RuntimeDyldImpl {
27
28 // For each symbol, keep a list of relocations based on it. Anytime
29 // its address is reassigned (the JIT re-compiled the function, e.g.),
30 // the relocations get re-resolved.
31 // The symbol (or section) the relocation is sourced from is the Key
32 // in the relocation list where it's stored.
33 struct RelocationEntry {
34 unsigned SectionID; // Section the relocation is contained in.
35 uint64_t Offset; // Offset into the section for the relocation.
36 uint32_t Data; // Second word of the raw macho relocation entry.
37 int64_t Addend; // Addend encoded in the instruction itself, if any,
38 // plus the offset into the source section for
39 // the symbol once the relocation is resolvable.
40
41 RelocationEntry(unsigned id, uint64_t offset, uint32_t data, int64_t addend)
42 : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
43 };
44 typedef SmallVector RelocationList;
45
46 // For each section, keep a list of referrers in that section that are clients
47 // of relocations in other sections. Whenever a relocation gets created,
48 // create a corresponding referrer. Whenever relocations are re-resolved,
49 // re-resolve the referrers' relocations as well.
50 struct Referrer {
51 unsigned SectionID; // Section whose RelocationList contains the relocation.
52 uint32_t Index; // Index of the RelocatonEntry in that RelocationList.
53
54 Referrer(unsigned id, uint32_t index)
55 : SectionID(id), Index(index) {}
56 };
57 typedef SmallVector ReferrerList;
58
59 // Relocations to sections already loaded. Indexed by SectionID which is the
60 // source of the address. The target where the address will be writen is
61 // SectionID/Offset in the relocation itself.
62 IndexedMap Relocations;
63 // Referrers corresponding to Relocations.
64 IndexedMap Referrers;
65 // Relocations to symbols that are not yet resolved. Must be external
66 // relocations by definition. Indexed by symbol name.
67 StringMap UnresolvedRelocations;
68
69 bool resolveRelocation(uint8_t *LocalAddress,
70 uint64_t FinalAddress,
71 uint64_t Value,
72 bool isPCRel,
73 unsigned Type,
74 unsigned Size,
75 int64_t Addend);
27 protected:
7628 bool resolveI386Relocation(uint8_t *LocalAddress,
7729 uint64_t FinalAddress,
7830 uint64_t Value,
9547 unsigned Size,
9648 int64_t Addend);
9749
98 bool loadSegment32(const MachOObject *Obj,
99 const MachOObject::LoadCommandInfo *SegmentLCI,
100 const InMemoryStruct &SymtabLC);
101 bool loadSegment64(const MachOObject *Obj,
102 const MachOObject::LoadCommandInfo *SegmentLCI,
103 const InMemoryStruct &SymtabLC);
104 bool processSymbols32(const MachOObject *Obj,
105 SmallVectorImpl &SectionMap,
106 SmallVectorImpl &SymbolNames,
107 const InMemoryStruct &SymtabLC);
108 bool processSymbols64(const MachOObject *Obj,
109 SmallVectorImpl &SectionMap,
110 SmallVectorImpl &SymbolNames,
111 const InMemoryStruct &SymtabLC);
112
113 void resolveSymbol(StringRef Name);
50 virtual void processRelocationRef(const ObjRelocationInfo &Rel,
51 const ObjectFile &Obj,
52 ObjSectionToIDMap &ObjSectionToID,
53 LocalSymbolMap &Symbols, StubMap &Stubs);
11454
11555 public:
56 virtual void resolveRelocation(uint8_t *LocalAddress,
57 uint64_t FinalAddress,
58 uint64_t Value,
59 uint32_t Type,
60 int64_t Addend);
61
11662 RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
11763
118 bool loadObject(MemoryBuffer *InputBuffer);
119
120 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
121
122 static bool isKnownFormat(const MemoryBuffer *InputBuffer);
123
124 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
125 return isKnownFormat(InputBuffer);
126 }
64 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
12765 };
12866
12967 } // end namespace llvm
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;