diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:48:50 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:48:50 +0000 |
commit | 1c98619801a5705c688e683be3ef9d70169a0686 (patch) | |
tree | 8422105cd1a94c368315f2db16b9ac746cf7c000 /lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp | |
parent | f4f3ce4613680903220815690ad79fc7ba0a2e26 (diff) |
Notes
Diffstat (limited to 'lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp')
-rw-r--r-- | lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp index 1013d3ddaef3..a17de5be1742 100644 --- a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp +++ b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp @@ -53,7 +53,7 @@ namespace mach_o { namespace normalized { // Utility to call a lambda expression on each load command. -static std::error_code forEachLoadCommand( +static llvm::Error forEachLoadCommand( StringRef lcRange, unsigned lcCount, bool isBig, bool is64, std::function<bool(uint32_t cmd, uint32_t size, const char *lc)> func) { const char* p = lcRange.begin(); @@ -67,15 +67,15 @@ static std::error_code forEachLoadCommand( slc = &lcCopy; } if ( (p + slc->cmdsize) > lcRange.end() ) - return make_error_code(llvm::errc::executable_format_error); + return llvm::make_error<GenericError>("Load command exceeds range"); if (func(slc->cmd, slc->cmdsize, p)) - return std::error_code(); + return llvm::Error(); p += slc->cmdsize; } - return std::error_code(); + return llvm::Error(); } static std::error_code appendRelocations(Relocations &relocs, StringRef buffer, @@ -199,7 +199,7 @@ bool sliceFromFatFile(MemoryBufferRef mb, MachOLinkingContext::Arch arch, } /// Reads a mach-o file and produces an in-memory normalized view. -ErrorOr<std::unique_ptr<NormalizedFile>> +llvm::Expected<std::unique_ptr<NormalizedFile>> readBinary(std::unique_ptr<MemoryBuffer> &mb, const MachOLinkingContext::Arch arch) { // Make empty NormalizedFile. @@ -220,7 +220,7 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, // Determine endianness and pointer size for mach-o file. bool is64, isBig; if (!isMachOHeader(mh, is64, isBig)) - return make_error_code(llvm::errc::executable_format_error); + return llvm::make_error<GenericError>("File is not a mach-o"); // Endian swap header, if needed. mach_header headerCopy; @@ -237,12 +237,13 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, start + (is64 ? sizeof(mach_header_64) : sizeof(mach_header)); StringRef lcRange(lcStart, smh->sizeofcmds); if (lcRange.end() > (start + objSize)) - return make_error_code(llvm::errc::executable_format_error); + return llvm::make_error<GenericError>("Load commands exceed file size"); // Get architecture from mach_header. f->arch = MachOLinkingContext::archFromCpuType(smh->cputype, smh->cpusubtype); if (f->arch != arch) { - return make_dynamic_error_code(Twine("file is wrong architecture. Expected " + return llvm::make_error<GenericError>( + Twine("file is wrong architecture. Expected " "(" + MachOLinkingContext::nameFromArch(arch) + ") found (" + MachOLinkingContext::nameFromArch(f->arch) @@ -256,9 +257,9 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, // Pre-scan load commands looking for indirect symbol table. uint32_t indirectSymbolTableOffset = 0; uint32_t indirectSymbolTableCount = 0; - std::error_code ec = forEachLoadCommand(lcRange, lcCount, isBig, is64, - [&](uint32_t cmd, uint32_t size, - const char *lc) -> bool { + auto ec = forEachLoadCommand(lcRange, lcCount, isBig, is64, + [&](uint32_t cmd, uint32_t size, + const char *lc) -> bool { if (cmd == LC_DYSYMTAB) { const dysymtab_command *d = reinterpret_cast<const dysymtab_command*>(lc); indirectSymbolTableOffset = read32(&d->indirectsymoff, isBig); @@ -268,7 +269,7 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, return false; }); if (ec) - return ec; + return std::move(ec); // Walk load commands looking for segments/sections and the symbol table. const data_in_code_entry *dataInCode = nullptr; @@ -380,11 +381,11 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, reinterpret_cast<const nlist_64 *>(start + symOffset); // Convert each nlist_64 to a lld::mach_o::normalized::Symbol. for(uint32_t i=0; i < symCount; ++i) { - const nlist_64 *sin = &symbols[i]; nlist_64 tempSym; - if (isBig != llvm::sys::IsBigEndianHost) { - tempSym = *sin; swapStruct(tempSym); sin = &tempSym; - } + memcpy(&tempSym, &symbols[i], sizeof(nlist_64)); + const nlist_64 *sin = &tempSym; + if (isBig != llvm::sys::IsBigEndianHost) + swapStruct(tempSym); Symbol sout; if (sin->n_strx > strSize) return true; @@ -471,11 +472,20 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, case LC_DYLD_INFO_ONLY: dyldInfo = reinterpret_cast<const dyld_info_command*>(lc); break; + case LC_VERSION_MIN_MACOSX: + case LC_VERSION_MIN_IPHONEOS: + case LC_VERSION_MIN_WATCHOS: + case LC_VERSION_MIN_TVOS: + // If we are emitting an object file, then we may take the load command + // kind from these commands and pass it on to the output + // file. + f->minOSVersionKind = (LoadCommandType)cmd; + break; } return false; }); if (ec) - return ec; + return std::move(ec); if (dataInCode) { // Convert on-disk data_in_code_entry array to DataInCode vector. |