static void getSectionsAndSymbols(const macho::Header &Header, MachOObjectFile *MachOObj, InMemoryStruct<macho::SymtabLoadCommand> *SymtabLC, std::vector<SectionRef> &Sections, std::vector<SymbolRef> &Symbols, SmallVectorImpl<uint64_t> &FoundFns) { error_code ec; for (symbol_iterator SI = MachOObj->begin_symbols(), SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec)) Symbols.push_back(*SI); for (section_iterator SI = MachOObj->begin_sections(), SE = MachOObj->end_sections(); SI != SE; SI.increment(ec)) { SectionRef SR = *SI; StringRef SectName; SR.getName(SectName); Sections.push_back(*SI); } for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { const MachOObject::LoadCommandInfo &LCI = MachOObj->getObject()->getLoadCommandInfo(i); if (LCI.Command.Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. InMemoryStruct<macho::LinkeditDataLoadCommand> LLC; MachOObj->getObject()->ReadLinkeditDataLoadCommand(LCI, LLC); MachOObj->getObject()->ReadULEB128s(LLC->DataOffset, FoundFns); } } }
/// Given a relocation from __compact_unwind, consisting of the RelocationRef /// and data being relocated, determine the best base Name and Addend to use for /// display purposes. /// /// 1. An Extern relocation will directly reference a symbol (and the data is /// then already an addend), so use that. /// 2. Otherwise the data is an offset in the object file's layout; try to find // a symbol before it in the same section, and use the offset from there. /// 3. Finally, if all that fails, fall back to an offset from the start of the /// referenced section. static void findUnwindRelocNameAddend(const MachOObjectFile *Obj, std::map<uint64_t, SymbolRef> &Symbols, const RelocationRef &Reloc, uint64_t Addr, StringRef &Name, uint64_t &Addend) { if (Reloc.getSymbol() != Obj->symbol_end()) { Reloc.getSymbol()->getName(Name); Addend = Addr; return; } auto RE = Obj->getRelocation(Reloc.getRawDataRefImpl()); SectionRef RelocSection = Obj->getRelocationSection(RE); uint64_t SectionAddr; RelocSection.getAddress(SectionAddr); auto Sym = Symbols.upper_bound(Addr); if (Sym == Symbols.begin()) { // The first symbol in the object is after this reference, the best we can // do is section-relative notation. RelocSection.getName(Name); Addend = Addr - SectionAddr; return; } // Go back one so that SymbolAddress <= Addr. --Sym; section_iterator SymSection = Obj->section_end(); Sym->second.getSection(SymSection); if (RelocSection == *SymSection) { // There's a valid symbol in the same section before this reference. Sym->second.getName(Name); Addend = Addr - Sym->first; return; } // There is a symbol before this reference, but it's in a different // section. Probably not helpful to mention it, so use the section name. RelocSection.getName(Name); Addend = Addr - SectionAddr; }
explicit section(const SectionRef& sec) { StringRef name; if(error_code err = sec.getName(name)) llvm_binary_fail(err); this->name_ = name.str(); if (error_code err = sec.getAddress(this->addr_)) llvm_binary_fail(err); if (error_code err = sec.getSize(this->size_)) llvm_binary_fail(err); }
static void getSectionsAndSymbols(const MachO::mach_header Header, MachOObjectFile *MachOObj, std::vector<SectionRef> &Sections, std::vector<SymbolRef> &Symbols, SmallVectorImpl<uint64_t> &FoundFns, uint64_t &BaseSegmentAddress) { for (symbol_iterator SI = MachOObj->symbol_begin(), SE = MachOObj->symbol_end(); SI != SE; ++SI) Symbols.push_back(*SI); for (section_iterator SI = MachOObj->section_begin(), SE = MachOObj->section_end(); SI != SE; ++SI) { SectionRef SR = *SI; StringRef SectName; SR.getName(SectName); Sections.push_back(*SI); } MachOObjectFile::LoadCommandInfo Command = MachOObj->getFirstLoadCommandInfo(); bool BaseSegmentAddressSet = false; for (unsigned i = 0; ; ++i) { if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) { // We found a function starts segment, parse the addresses for later // consumption. MachO::linkedit_data_command LLC = MachOObj->getLinkeditDataLoadCommand(Command); MachOObj->ReadULEB128s(LLC.dataoff, FoundFns); } else if (Command.C.cmd == MachO::LC_SEGMENT) { MachO::segment_command SLC = MachOObj->getSegmentLoadCommand(Command); StringRef SegName = SLC.segname; if(!BaseSegmentAddressSet && SegName != "__PAGEZERO") { BaseSegmentAddressSet = true; BaseSegmentAddress = SLC.vmaddr; } } if (i == Header.ncmds - 1) break; else Command = MachOObj->getNextLoadCommandInfo(Command); } }
/// Return true if the provided section is an offload section and return the /// triple by reference. static bool IsOffloadSection(SectionRef CurSection, StringRef &OffloadTriple) { StringRef SectionName; CurSection.getName(SectionName); if (SectionName.empty()) return false; // If it does not start with the reserved suffix, just skip this section. if (!SectionName.startswith(OFFLOAD_BUNDLER_MAGIC_STR)) return false; // Return the triple that is right after the reserved prefix. OffloadTriple = SectionName.substr(sizeof(OFFLOAD_BUNDLER_MAGIC_STR) - 1); return true; }
static void getSectionsAndSymbols(const macho::Header Header, MachOObjectFile *MachOObj, std::vector<SectionRef> &Sections, std::vector<SymbolRef> &Symbols, SmallVectorImpl<uint64_t> &FoundFns) { error_code ec; for (symbol_iterator SI = MachOObj->begin_symbols(), SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec)) Symbols.push_back(*SI); for (section_iterator SI = MachOObj->begin_sections(), SE = MachOObj->end_sections(); SI != SE; SI.increment(ec)) { SectionRef SR = *SI; StringRef SectName; SR.getName(SectName); Sections.push_back(*SI); } MachOObjectFile::LoadCommandInfo Command = MachOObj->getFirstLoadCommandInfo(); for (unsigned i = 0; ; ++i) { if (Command.C.Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. macho::LinkeditDataLoadCommand LLC = MachOObj->getLinkeditDataLoadCommand(Command); MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns); } if (i == Header.NumLoadCommands - 1) break; else Command = MachOObj->getNextLoadCommandInfo(Command); } }
unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, const SectionRef &Section, bool IsCode) { unsigned StubBufSize = 0, StubSize = getMaxStubSize(); error_code err; if (StubSize > 0) { for (relocation_iterator i = Section.begin_relocations(), e = Section.end_relocations(); i != e; i.increment(err), Check(err)) StubBufSize += StubSize; } StringRef data; uint64_t Alignment64; Check(Section.getContents(data)); Check(Section.getAlignment(Alignment64)); unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; bool IsRequired; bool IsVirtual; bool IsZeroInit; uint64_t DataSize; StringRef Name; Check(Section.isRequiredForExecution(IsRequired)); Check(Section.isVirtual(IsVirtual)); Check(Section.isZeroInit(IsZeroInit)); Check(Section.getSize(DataSize)); Check(Section.getName(Name)); unsigned Allocate; unsigned SectionID = Sections.size(); uint8_t *Addr; const char *pData = 0; // Some sections, such as debug info, don't need to be loaded for execution. // Leave those where they are. if (IsRequired) { Allocate = DataSize + StubBufSize; Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID) : MemMgr->allocateDataSection(Allocate, Alignment, SectionID); if (!Addr) report_fatal_error("Unable to allocate section memory!"); // Virtual sections have no data in the object image, so leave pData = 0 if (!IsVirtual) pData = data.data(); // Zero-initialize or copy the data from the image if (IsZeroInit || IsVirtual) memset(Addr, 0, DataSize); else memcpy(Addr, pData, DataSize); DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", pData) << " new addr: " << format("%p", Addr) << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"); Obj.updateSectionAddress(Section, (uint64_t)Addr); } else { // Even if we didn't load the section, we need to record an entry for it // to handle later processing (and by 'handle' I mean don't do anything // with these sections). Allocate = 0; Addr = 0; DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", data.data()) << " new addr: 0" << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"); } Sections.push_back(SectionEntry(Name, Addr, Allocate, DataSize, (uintptr_t)pData)); return SectionID; }
unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, const SectionRef &Section, bool IsCode) { unsigned StubBufSize = 0, StubSize = getMaxStubSize(); error_code err; const ObjectFile *ObjFile = Obj.getObjectFile(); // FIXME: this is an inefficient way to handle this. We should computed the // necessary section allocation size in loadObject by walking all the sections // once. if (StubSize > 0) { for (section_iterator SI = ObjFile->begin_sections(), SE = ObjFile->end_sections(); SI != SE; SI.increment(err), Check(err)) { section_iterator RelSecI = SI->getRelocatedSection(); if (!(RelSecI == Section)) continue; for (relocation_iterator I = SI->begin_relocations(), E = SI->end_relocations(); I != E; I.increment(err), Check(err)) { StubBufSize += StubSize; } } } StringRef data; uint64_t Alignment64; Check(Section.getContents(data)); Check(Section.getAlignment(Alignment64)); unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; bool IsRequired; bool IsVirtual; bool IsZeroInit; bool IsReadOnly; uint64_t DataSize; StringRef Name; Check(Section.isRequiredForExecution(IsRequired)); Check(Section.isVirtual(IsVirtual)); Check(Section.isZeroInit(IsZeroInit)); Check(Section.isReadOnlyData(IsReadOnly)); Check(Section.getSize(DataSize)); Check(Section.getName(Name)); if (StubSize > 0) { unsigned StubAlignment = getStubAlignment(); unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment); if (StubAlignment > EndAlignment) StubBufSize += StubAlignment - EndAlignment; } unsigned Allocate; unsigned SectionID = Sections.size(); uint8_t *Addr; const char *pData = 0; // Some sections, such as debug info, don't need to be loaded for execution. // Leave those where they are. if (IsRequired) { Allocate = DataSize + StubBufSize; Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID) : MemMgr->allocateDataSection(Allocate, Alignment, SectionID, IsReadOnly); if (!Addr) report_fatal_error("Unable to allocate section memory!"); // Virtual sections have no data in the object image, so leave pData = 0 if (!IsVirtual) pData = data.data(); // Zero-initialize or copy the data from the image if (IsZeroInit || IsVirtual) memset(Addr, 0, DataSize); else memcpy(Addr, pData, DataSize); DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", pData) << " new addr: " << format("%p", Addr) << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"); Obj.updateSectionAddress(Section, (uint64_t)Addr); } else { // Even if we didn't load the section, we need to record an entry for it // to handle later processing (and by 'handle' I mean don't do anything // with these sections). Allocate = 0; Addr = 0; DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", data.data()) << " new addr: 0" << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"); } Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData)); return SectionID; }
unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, const SectionRef &Section, bool IsCode) { StringRef data; uint64_t Alignment64; Check(Section.getContents(data)); Check(Section.getAlignment(Alignment64)); unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; bool IsRequired; bool IsVirtual; bool IsZeroInit; bool IsReadOnly; uint64_t DataSize; unsigned PaddingSize = 0; unsigned StubBufSize = 0; StringRef Name; Check(Section.isRequiredForExecution(IsRequired)); Check(Section.isVirtual(IsVirtual)); Check(Section.isZeroInit(IsZeroInit)); Check(Section.isReadOnlyData(IsReadOnly)); Check(Section.getSize(DataSize)); Check(Section.getName(Name)); StubBufSize = computeSectionStubBufSize(Obj, Section); // The .eh_frame section (at least on Linux) needs an extra four bytes padded // with zeroes added at the end. For MachO objects, this section has a // slightly different name, so this won't have any effect for MachO objects. if (Name == ".eh_frame") PaddingSize = 4; uintptr_t Allocate; unsigned SectionID = Sections.size(); uint8_t *Addr; const char *pData = 0; // Some sections, such as debug info, don't need to be loaded for execution. // Leave those where they are. if (IsRequired) { Allocate = DataSize + PaddingSize + StubBufSize; Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID, Name) : MemMgr->allocateDataSection(Allocate, Alignment, SectionID, Name, IsReadOnly); if (!Addr) report_fatal_error("Unable to allocate section memory!"); // Virtual sections have no data in the object image, so leave pData = 0 if (!IsVirtual) pData = data.data(); // Zero-initialize or copy the data from the image if (IsZeroInit || IsVirtual) memset(Addr, 0, DataSize); else memcpy(Addr, pData, DataSize); // Fill in any extra bytes we allocated for padding if (PaddingSize != 0) { memset(Addr + DataSize, 0, PaddingSize); // Update the DataSize variable so that the stub offset is set correctly. DataSize += PaddingSize; } DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", pData) << " new addr: " << format("%p", Addr) << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"); Obj.updateSectionAddress(Section, (uint64_t)Addr); } else { // Even if we didn't load the section, we need to record an entry for it // to handle later processing (and by 'handle' I mean don't do anything // with these sections). Allocate = 0; Addr = 0; DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", data.data()) << " new addr: 0" << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"); } Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData)); return SectionID; }
error_or<std::string> getName(const SectionRef &sec) { StringRef name; if (error_code ec = sec.getName(name)) return failure(ec.message()); return success(name.str()); }