6b53073eae
This is a reland of commit 38ef28a058
Fixes:
* Fix comparisons in ASSERT_EQUAL statements on 32-bit architectures.
* Take simulated architectures into account when deciding whether
to use dlopen() for native shared object formats.
* Fix struct/field name collision for GCC.
* Use CPU_TYPE_ANY/CPU_SUBTYPE_ANY for architectures that do not
have more specific cpu_type_t/cpu_subtype_t constants defined.
Original change's description:
> [vm, gen_snapshot] Add app-aot-macho-dylib option for AOT snapshots.
>
> This is the initial framework for creating snapshots as Mach-O dynamic
> libraries. Note that this framework is not 100% feature complete
> compared to generating Mach-O snapshots via assembly. In particular,
> the directly-compiled Mach-O dylib does not yet contain compact
> unwinding information.
>
> Other changes:
>
> * Adds UuidCommand to the native_stack_traces package's Mach-O reader,
> which now appropriately returns the UUID as the build ID for Mach-O
> shared objects.
>
> * Adds Utils::Basename(path) for portably retrieving the basename
> from a path. (Returns nullptr for all arguments where it is not
> currently implemented on Fuchsia or Windows.)
>
> * Adjusts vm/timeline.h to avoid pulling in <mach_o/loader.h> on MacOS,
> as that interferes with uses of the namespaced Mach-O definitions
> in platform/mach_o.h.
>
> * Only attempt to dlopen() a snapshot if ELF is the native format
> for the host platform or the snapshot is not an ELF shared object.
> If dlopen() is used, report the error message if it fails rather
> than attempting to manually load the snapshot as an ELF shared object.
>
> * Fix the magic number stored in DylibAppSnapshot for loaded non-ELF
> dynamic libraries.
>
> * Remove the detection of reverse-endian Mach-O magic numbers in
> DartUtils::SniffForMagicNumber(), since all our Mach-O related code
> assumes host-endian Mach-O files and so there's no point other than
> to give a slightly better error message when failing.
>
> TEST=vm/dart/exported_symbols_test
> vm/dart/unobfuscated_static_symbols_test
> vm/dart/use_dwarf_stack_traces_flag_test
> vm/cc/CanDetectMachOFiles
>
> Issue: https://github.com/dart-lang/sdk/issues/60307
> Change-Id: Idf5b49d6c6d035ab033509613212b95520d65965
> Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-x64-try,vm-mac-release-arm64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-dwarf-linux-product-x64-try,vm-linux-debug-x64-try,vm-mac-debug-arm64-try,vm-fuchsia-release-x64-try,vm-fuchsia-release-arm64-try
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/415020
> Reviewed-by: Slava Egorov <vegorov@google.com>
> Commit-Queue: Tess Strickland <sstrickl@google.com>
TEST=vm/dart/exported_symbols_test
vm/dart/unobfuscated_static_symbols_test
vm/dart/use_dwarf_stack_traces_flag_test
vm/cc/CanDetectMachOFiles
ci on trybots that failed on the original CL
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-x64-try,vm-mac-release-arm64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-dwarf-linux-product-x64-try,vm-linux-debug-x64-try,vm-mac-debug-arm64-try,vm-fuchsia-release-x64-try,vm-fuchsia-release-arm64-try,vm-linux-debug-ia32-try,vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-debug-simriscv32-try,vm-aot-linux-debug-simriscv64-try,vm-aot-linux-release-simarm_x64-try,vm-gcc-linux-try,vm-ubsan-linux-release-arm64-try
Change-Id: Iaffea0ddc6173100c8b5b2a9fe46c45f4f611a2e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/431240
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
120 lines
3.8 KiB
C++
120 lines
3.8 KiB
C++
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef RUNTIME_VM_ELF_H_
|
|
#define RUNTIME_VM_ELF_H_
|
|
|
|
#include "platform/globals.h"
|
|
|
|
#if defined(DART_PRECOMPILER)
|
|
#include "vm/allocation.h"
|
|
#include "vm/compiler/runtime_api.h"
|
|
#include "vm/datastream.h"
|
|
#include "vm/growable_array.h"
|
|
#include "vm/so_writer.h"
|
|
#include "vm/zone.h"
|
|
#endif
|
|
|
|
namespace dart {
|
|
|
|
// The max page size on all supported architectures. Used to determine
|
|
// the alignment of load segments, so that they are guaranteed page-aligned,
|
|
// and no shared object section or segment should have a larger alignment.
|
|
#if defined(DART_TARGET_OS_LINUX) && defined(TARGET_ARCH_ARM64)
|
|
// Some Linux distributions on ARM64 select 64 KB page size.
|
|
// Follow LLVM (https://reviews.llvm.org/D25079) and set maximum page size
|
|
// to 64 KB for ARM64 Linux builds.
|
|
static constexpr intptr_t kElfPageSize = 64 * KB;
|
|
#elif defined(DART_TARGET_OS_ANDROID) && defined(TARGET_ARCH_IS_64_BIT)
|
|
static constexpr intptr_t kElfPageSize = 64 * KB;
|
|
#else
|
|
static constexpr intptr_t kElfPageSize = 16 * KB;
|
|
#endif
|
|
|
|
#if defined(DART_PRECOMPILER)
|
|
|
|
class ProgramTable;
|
|
class SectionTable;
|
|
class ElfSymbolTable;
|
|
|
|
class ElfWriter : public SharedObjectWriter {
|
|
public:
|
|
ElfWriter(Zone* zone,
|
|
BaseWriteStream* stream,
|
|
Type type,
|
|
Dwarf* dwarf = nullptr);
|
|
|
|
static constexpr intptr_t kPageSize = kElfPageSize;
|
|
intptr_t page_size() const override { return kPageSize; }
|
|
|
|
Output output() const override { return Output::Elf; }
|
|
|
|
const ElfSymbolTable& symtab() const {
|
|
ASSERT(symtab_ != nullptr);
|
|
return *symtab_;
|
|
}
|
|
const SectionTable& section_table() const { return *section_table_; }
|
|
|
|
void AddText(const char* name,
|
|
intptr_t label,
|
|
const uint8_t* bytes,
|
|
intptr_t size,
|
|
const SharedObjectWriter::RelocationArray* relocations,
|
|
const SharedObjectWriter::SymbolDataArray* symbol) override;
|
|
void AddROData(const char* name,
|
|
intptr_t label,
|
|
const uint8_t* bytes,
|
|
intptr_t size,
|
|
const SharedObjectWriter::RelocationArray* relocations,
|
|
const SharedObjectWriter::SymbolDataArray* symbols) override;
|
|
|
|
void Finalize() override;
|
|
|
|
void AssertConsistency(const SharedObjectWriter* debug) const override {
|
|
if (auto* const debug_elf = debug->AsElfWriter()) {
|
|
AssertConsistency(this, debug_elf);
|
|
} else {
|
|
FATAL("Expected both snapshot and debug to be ELF");
|
|
}
|
|
}
|
|
|
|
const ElfWriter* AsElfWriter() const override { return this; }
|
|
|
|
private:
|
|
static void AssertConsistency(const ElfWriter* snapshot,
|
|
const ElfWriter* debug_info);
|
|
|
|
static constexpr const char kBuildIdNoteName[] = ".note.gnu.build-id";
|
|
static constexpr const char kTextName[] = ".text";
|
|
static constexpr const char kDataName[] = ".rodata";
|
|
static constexpr const char kBssName[] = ".bss";
|
|
static constexpr const char kDynamicTableName[] = ".dynamic";
|
|
|
|
void CreateBSS();
|
|
void GenerateBuildId();
|
|
void InitializeSymbolTables();
|
|
void FinalizeDwarfSections();
|
|
void FinalizeEhFrame();
|
|
void ComputeOffsets();
|
|
|
|
// Contains all sections that will have entries in the section header table.
|
|
SectionTable* const section_table_;
|
|
|
|
// Contains all segments in the program header table. Set after finalizing
|
|
// the section table.
|
|
ProgramTable* program_table_ = nullptr;
|
|
|
|
// The static tables are always created for use in relocation calculations,
|
|
// even though they may not end up in the final ELF file.
|
|
ElfSymbolTable* symtab_ = nullptr;
|
|
|
|
friend class SectionTable; // For section name static fields.
|
|
};
|
|
|
|
#endif // DART_PRECOMPILER
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_ELF_H_
|