Loading...
/* * Copyright (c) 2021 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include <assert.h> #include <limits.h> #include <stdlib.h> #include <string.h> // mach_o #include "Misc.h" // mach_o_writer #include "FunctionStartsWriter.h" namespace mach_o { FunctionStartsWriter::FunctionStartsWriter(uint64_t prefLoadAddr, std::span<const uint64_t> functionAddresses) : FunctionStarts(nullptr, 0) { uint64_t lastAddr = prefLoadAddr; for (uint64_t addr : functionAddresses) { // firmwares can built with an out of VM addr order of segments assert(addr >= lastAddr || lastAddr == prefLoadAddr && "function addresses not sorted"); // <rdar://problem/10422823> filter out zero-length atoms, so LC_FUNCTION_STARTS address can't spill into next section if ( addr == lastAddr) continue; // FIXME: for 32-bit arm need to check thumbness uint64_t delta = addr - lastAddr; append_uleb128(delta); lastAddr = addr; } // terminate delta encoded list _bytes.push_back(0); // 8-byte align while ( (_bytes.size() % 8) != 0 ) _bytes.push_back(0); // set up pointers to data can be parsed _funcStartsBegin = _bytes.data(); _funcStartsEnd = _bytes.data()+_bytes.size(); } void FunctionStartsWriter::append_uleb128(uint64_t value) { uint8_t byte; do { byte = value & 0x7F; value &= ~0x7F; if ( value != 0 ) byte |= 0x80; _bytes.push_back(byte); value = value >> 7; } while( byte >= 0x80 ); } } // namespace mach_o |