Loading...
mach_o/Archive.cpp dyld-1340 /dev/null
--- dyld/dyld-1340/mach_o/Archive.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (c) 2022 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 <TargetConditionals.h>
-
-#if !TARGET_OS_EXCLAVEKIT
-
-#include "Archive.h"
-
-// stl
-#include <string_view>
-
-// Darwin
-#include <ar.h>
-#include <mach-o/ranlib.h>
-#include <mach/mach.h>
-#include <mach/vm_map.h>
-
-namespace mach_o {
-
-constexpr std::string_view AR_EFMT1_SV(AR_EFMT1);
-
-static inline uint64_t align(uint64_t addr, uint8_t p2)
-{
-    uint64_t mask = (1 << p2);
-    return (addr + mask - 1) & (-mask);
-}
-
-uint64_t Entry::extendedFormatNameSize(std::string_view name)
-{
-    // In extended format the name is stored after the member header.
-    // It's always \0 terminated, it's padded to 8 bytes and also contains
-    // an extra padding for the member header. This makes sure that member
-    // contents are always 8 bytes aligned.
-    return align(name.size() + 1, 3) + align(sizeof(Entry), 3) - sizeof(Entry);
-}
-
-uint64_t Entry::entrySize(bool extendedFormatNames, std::string_view name, uint64_t contentSize)
-{
-    if ( extendedFormatNames ) {
-        return sizeof(Entry) + extendedFormatNameSize(name) + align(contentSize, 3);
-    }
-    return sizeof(Entry) + align(contentSize, 3);
-}
-
-size_t Entry::write(std::span<uint8_t> buffer, bool extendedFormatNames, std::string_view name, uint64_t mktime, std::span<const uint8_t> content)
-{
-    Entry* entry = (Entry*)buffer.data();
-
-    const uint64_t alignedNameSize       = extendedFormatNames ? extendedFormatNameSize(name) : 0;
-    // Content is 8-bytes aligned and padded with \n characters.
-    const uint64_t alignedContentSize   = align(content.size(), 3);
-    const uint64_t headerSize           = sizeof(Entry) + alignedNameSize;
-    const uint64_t totalSize            = headerSize + alignedContentSize;
-    assert(totalSize == entrySize(extendedFormatNames, name, content.size()));
-    assert(buffer.size() >= (totalSize));
-    bzero(buffer.data(), (size_t)headerSize);
-
-    snprintf(entry->ar_date, sizeof(Entry::ar_date), "%llu", mktime);
-    memcpy(entry->ar_fmag, ARFMAG, sizeof(Entry::ar_fmag));
-
-    if ( extendedFormatNames ) {
-        snprintf(entry->ar_size, sizeof(Entry::ar_size), "%llu", alignedContentSize + alignedNameSize);
-        snprintf(entry->ar_name, sizeof(Entry::ar_name), AR_EFMT1 "%llu", alignedNameSize);
-
-        char* nameBuffer = (char*)(entry + 1);
-        memcpy(nameBuffer, name.data(), name.size());
-        nameBuffer[name.size()] = 0;
-    } else {
-        snprintf(entry->ar_size, sizeof(Entry::ar_size), "%llu", alignedContentSize);
-
-        // Note that the truncated name doesn't need to be \0 terminated
-        std::string_view shortName = name.substr(0, sizeof(Entry::ar_name));
-        memcpy(entry->ar_name, shortName.data(), shortName.size());
-    }
-
-    uint8_t* contentStart = buffer.data() + sizeof(Entry) + alignedNameSize;
-    memcpy(contentStart, content.data(), content.size());
-    // Pad content alignment with \n characters
-    if ( content.size() != alignedContentSize )
-        memset(contentStart + content.size(), '\n', (size_t)alignedContentSize - content.size());
-
-    return (size_t)totalSize;
-}
-
-bool Entry::hasLongName() const
-{
-    return std::string_view(ar_name, AR_EFMT1_SV.size()) == AR_EFMT1_SV;
-}
-
-uint64_t Entry::getLongNameSpace() const
-{
-    char* endptr;
-    return strtoull(&ar_name[AR_EFMT1_SV.size()], &endptr, 10);
-}
-
-void Entry::getName(char *buf, int bufsz) const
-{
-  if ( hasLongName() ) {
-      uint64_t len = getLongNameSpace();
-      assert(bufsz >= len+1);
-      strncpy(buf, ((char*)this)+sizeof(ar_hdr), (size_t)len);
-      buf[len] = '\0';
-  } else {
-      assert(bufsz >= 16+1);
-      strncpy(buf, ar_name, 16);
-      buf[16] = '\0';
-      char* space = strchr(buf, ' ');
-      if ( space != NULL )
-          *space = '\0';
-  }
-}
-
-uint64_t Entry::modificationTime() const
-{
-    char temp[14];
-    strncpy(temp, ar_date, 12);
-    temp[12] = '\0';
-    char* endptr;
-    return strtoull(temp, &endptr, 10);
-}
-
-Error Entry::content(std::span<const uint8_t>& content) const
-{
-    char temp[12];
-    strncpy(temp, ar_size, 10);
-    temp[10] = 0;
-    char* endptr = nullptr;
-    uint64_t size = strtoull(temp, &endptr, 10);
-    if ( *endptr != 0 && *endptr != ' ' )
-        return Error("archive member size contains non-numeric characters: '%s'", (const char*)temp);
-
-    const uint8_t* data;
-    // long name is included in ar_size
-    if ( hasLongName() ) {
-        uint64_t space = getLongNameSpace();
-        assert(size >= space);
-        size -= space;
-        data = ((const uint8_t*)this) + sizeof(ar_hdr) + space;
-    } else {
-        data = ((const uint8_t*)this) + sizeof(ar_hdr);
-    }
-
-    content = std::span(data, (size_t)size);
-    return Error::none();
-}
-
-Error Entry::next(Entry*& next) const
-{
-    next = nullptr;
-    std::span<const uint8_t> content;
-    if (Error err = this->content(content) )
-        return err;
-
-    const uint8_t* p = content.data() + content.size();
-    p = (uint8_t*)align((uint64_t)p, 2); // 4-byte align
-    next = (Entry*)p;
-    return Error::none();
-}
-
-Error Entry::valid() const
-{
-    if ( memcmp(ar_fmag, ARFMAG, sizeof(ar_fmag)) == 0 ) {
-        return Error::none();
-    }
-
-    return Error("archive member invalid control bits");
-}
-
-std::optional<Archive> Archive::isArchive(std::span<const uint8_t> buffer)
-{
-    if ( buffer.size() >= archive_magic.size()
-        && std::string_view((const char*)buffer.data(), archive_magic.size()) == archive_magic ) {
-        return Archive(buffer);
-    }
-    return std::nullopt;
-}
-
-Error Archive::forEachMember(void (^handler)(const Member&, bool& stop)) const
-{
-    const Entry* current = (Entry*)(buffer.data() + archive_magic.size());
-    const Entry* const end = (Entry*)(buffer.data() + buffer.size());
-
-    std::array<char, 256> nameBuffer;
-    bool stop = false;
-    unsigned memberIndex = 1;
-    while ( !stop && current < end ) {
-        if ( (current + 1) > end )
-            return Error("malformed archive, member exceeds file size");
-
-        if ( Error err = current->valid() )
-            return err;
-
-        std::span<const uint8_t> content;
-        if ( Error err = current->content(content) )
-            return err;
-
-        Entry* next;
-        if ( Error err = current->next(next) )
-            return err;
-        if ( next > end )
-            return Error("malformed archive, member exceeds file size");
-
-        current->getName(nameBuffer.data(), nameBuffer.size());
-        handler(Member{ nameBuffer.data(), content, current->modificationTime(), memberIndex }, stop);
-        current = next;
-        memberIndex++;
-    }
-
-    return Error::none();
-}
-
-static bool isBitCodeHeader(std::span<const uint8_t> contents)
-{
-    return (contents[0] == 0xDE) && (contents[1] == 0xC0) && (contents[2] == 0x17) && (contents[3] == 0x0B);
-}
-
-Error Archive::forEachMachO(void (^handler)(const Member&, const mach_o::Header*, bool& stop)) const
-{
-    __block Error err = Error::none();
-    __block bool hadSymdefFile = false;
-
-    Error iterErr = forEachMember(^(const Member& member, bool &stop) {
-        if ( const Header* header = Header::isMachO(member.contents) ) {
-            handler(std::move(member), header, stop);
-        }
-        else if ( isBitCodeHeader(member.contents) ) {
-            handler(std::move(member), nullptr, stop);
-        }
-        else {
-            if ( member.name == SYMDEF || member.name == SYMDEF_SORTED ||
-                    member.name == SYMDEF_64 || member.name == SYMDEF_64_SORTED ) {
-                if ( hadSymdefFile ) {
-                    err = Error("multiple SYMDEF member files found in an archive");
-                } else {
-                    hadSymdefFile = true;
-                    return;
-                }
-            } else {
-                err = Error("archive member '%s' not a mach-o file", member.name.data()) ;
-            }
-            stop = true;
-        }
-    });
-
-    if ( iterErr )
-        return iterErr;
-
-    return std::move(err);
-}
-
-}
-
-#endif // !TARGET_OS_EXCLAVEKIT