12994040e0
For other architectures, a __eh_frame section is generated like for non-MacOS platforms. TEST=vm/dart/unwinding_information_test Issue: https://github.com/dart-lang/sdk/issues/60307 Change-Id: I46c6ff1357c222f73a129e1becd9b12b3fb6ef9c 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-aot-linux-release-simarm_x64-try,vm-gcc-linux-try,vm-ubsan-linux-release-arm64-try,vm-aot-win-release-arm64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/433020 Reviewed-by: Slava Egorov <vegorov@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com>
123 lines
4.5 KiB
C++
123 lines
4.5 KiB
C++
// Copyright (c) 2025, 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_DWARF_SO_WRITER_H_
|
|
#define RUNTIME_VM_DWARF_SO_WRITER_H_
|
|
|
|
#include "platform/globals.h"
|
|
|
|
#if defined(DART_PRECOMPILER)
|
|
|
|
#include "vm/datastream.h"
|
|
#include "vm/dwarf.h"
|
|
#include "vm/so_writer.h"
|
|
|
|
namespace dart {
|
|
|
|
class DwarfSharedObjectStream : public DwarfWriteStream {
|
|
public:
|
|
DwarfSharedObjectStream(Zone* zone, NonStreamingWriteStream* stream)
|
|
: zone_(ASSERT_NOTNULL(zone)),
|
|
stream_(ASSERT_NOTNULL(stream)),
|
|
relocations_(new (zone) SharedObjectWriter::RelocationArray()) {}
|
|
|
|
static constexpr intptr_t kInitialBufferSize = 64 * KB;
|
|
|
|
const uint8_t* buffer() const { return stream_->buffer(); }
|
|
intptr_t bytes_written() const { return stream_->bytes_written(); }
|
|
intptr_t Position() const { return stream_->Position(); }
|
|
|
|
void sleb128(intptr_t value) override { stream_->WriteSLEB128(value); }
|
|
void uleb128(uintptr_t value) override { stream_->WriteLEB128(value); }
|
|
void u1(uint8_t value) override { stream_->WriteByte(value); }
|
|
void u2(uint16_t value) override { stream_->WriteFixed(value); }
|
|
void u4(uint32_t value) override { stream_->WriteFixed(value); }
|
|
void u8(uint64_t value) override { stream_->WriteFixed(value); }
|
|
void string(const char* cstr) override { // NOLINT
|
|
// Unlike stream_->WriteString(), we want the null terminator written.
|
|
stream_->WriteBytes(cstr, strlen(cstr) + 1);
|
|
}
|
|
// The prefix is ignored for DwarfSharedObjectStreams.
|
|
void WritePrefixedLength(const char* unused,
|
|
std::function<void()> body) override {
|
|
const intptr_t fixup = stream_->Position();
|
|
// We assume DWARF v2 currently, so all sizes are 32-bit.
|
|
u4(0);
|
|
// All sizes for DWARF sections measure the size of the section data _after_
|
|
// the size value.
|
|
const intptr_t start = stream_->Position();
|
|
body();
|
|
const intptr_t end = stream_->Position();
|
|
stream_->SetPosition(fixup);
|
|
u4(end - start);
|
|
stream_->SetPosition(end);
|
|
}
|
|
// Shorthand for when working directly with DwarfSharedObjectStreams.
|
|
void WritePrefixedLength(std::function<void()> body) {
|
|
WritePrefixedLength(nullptr, body);
|
|
}
|
|
|
|
void OffsetFromSymbol(intptr_t label,
|
|
intptr_t offset,
|
|
size_t size = kAddressSize) override {
|
|
ASSERT(size > 0);
|
|
ASSERT(size <= static_cast<size_t>(kInt64Size));
|
|
relocations_->Add({size, stream_->Position(),
|
|
SharedObjectWriter::Relocation::kSnapshotRelative, 0,
|
|
label, offset});
|
|
const uint64_t placeholder = 0; // Resolved later.
|
|
stream_->WriteBytes(&placeholder, size);
|
|
}
|
|
void InitializeAbstractOrigins(intptr_t size) override {
|
|
abstract_origins_size_ = size;
|
|
abstract_origins_ = zone_->Alloc<uint32_t>(abstract_origins_size_);
|
|
}
|
|
void RegisterAbstractOrigin(intptr_t index) override {
|
|
ASSERT(abstract_origins_ != nullptr);
|
|
ASSERT(index < abstract_origins_size_);
|
|
abstract_origins_[index] = stream_->Position();
|
|
}
|
|
void AbstractOrigin(intptr_t index) override { u4(abstract_origins_[index]); }
|
|
|
|
// Generates the offset of the virtual address corresponding to the given
|
|
// symbol label from the current position in the output. That is, if
|
|
// X = the virtual address of the current position
|
|
// Y = the virtual address of the symbol
|
|
// then the value at the current position in the output is Y - X.
|
|
//
|
|
// If no size is provided, the size of the offset in the stream is
|
|
// the native word size.
|
|
void RelativeSymbolOffset(intptr_t label, size_t size = kAddressSize) {
|
|
relocations_->Add({size, stream_->Position(),
|
|
SharedObjectWriter::Relocation::kSelfRelative, 0, label,
|
|
0});
|
|
const uint64_t placeholder = 0; // Resolved later.
|
|
stream_->WriteBytes(&placeholder, size);
|
|
}
|
|
|
|
intptr_t Align(intptr_t alignment, intptr_t offset = 0) {
|
|
return stream_->Align(alignment, offset);
|
|
}
|
|
|
|
const SharedObjectWriter::RelocationArray* relocations() const {
|
|
return relocations_;
|
|
}
|
|
|
|
protected:
|
|
Zone* const zone_;
|
|
NonStreamingWriteStream* const stream_;
|
|
SharedObjectWriter::RelocationArray* const relocations_ = nullptr;
|
|
uint32_t* abstract_origins_ = nullptr;
|
|
intptr_t abstract_origins_size_ = -1;
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(DwarfSharedObjectStream);
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // DART_PRECOMPILER
|
|
|
|
#endif // RUNTIME_VM_DWARF_SO_WRITER_H_
|