Files
sdk/runtime/vm/so_writer.cc
T
Tess Strickland bc021bbc01 [vm] Output accompaning relocatable object for Mach-O snapshots.
In order to appropriately generate .dSYMs for a snapshot and allow
the strip tool to be used on the snapshot afterwards, add a mode that
not only outputs the snapshot (sans DWARF information) but also
an associated relocatable object file that contains the program's DWARF
information. That allows dsymutil to retrieve the DWARF information
from the relocatable object when run on the snapshot prior to stripping.

To specify that the relocatable object file should be output, use
the new --macho-object command line argument to gen_snapshot
to specify where the object file should be written.

This CL also adds an additional command line argument,
--macho-reduce-padding, which reduces the alignment used for segments
and the text/const sections in Mach-O outputs from 16KB to 64 bytes.
The larger padding is needed for some uses, like non-native loading
of Mach-O objects, but can be elided for other uses like Flutter builds.

TEST=vm/dart/use_dwarf_stack_traces_flag_test
     vm/dart/use_macho_reduce_padding_flag_test

Change-Id: I2bf4bacb70c41299b8b6fdb7635c2374acf7a07d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/457420
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2025-11-19 07:45:52 -08:00

85 lines
2.8 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.
#include "vm/so_writer.h"
#if defined(DART_PRECOMPILER)
#include "vm/image_snapshot.h"
namespace dart {
void SharedObjectWriter::WriteStream::WriteRelocatableValue(
intptr_t address,
const Relocation& reloc,
intptr_t reloc_index) {
intptr_t source_address = reloc.source_offset;
switch (reloc.source_label) {
case Relocation::kSelfRelative:
source_address += address;
break;
case Relocation::kSnapshotRelative:
// No change to source_address.
break;
default:
ASSERT(reloc.source_label > 0);
source_address += FindValueForLabel(reloc.source_label);
}
ASSERT(reloc.size_in_bytes <= kWordSize);
word to_write = reloc.target_offset - source_address;
switch (reloc.target_label) {
case Relocation::kSelfRelative:
to_write += address;
break;
case Relocation::kSnapshotRelative:
// No change to to_write.
break;
default: {
ASSERT(reloc.target_label > 0);
intptr_t value;
if (HasValueForLabel(reloc.target_label, &value)) {
to_write += value;
} else {
ASSERT_EQUAL(reloc.target_label, kBuildIdLabel);
ASSERT_EQUAL(reloc.target_offset, 0);
ASSERT_EQUAL(reloc.source_offset, 0);
ASSERT_EQUAL(reloc.size_in_bytes, compiler::target::kWordSize);
// TODO(dartbug.com/43516): Special case for snapshots with deferred
// sections that handles the build ID relocation in an
// InstructionsSection when there is no build ID.
to_write = Image::kNoRelocatedAddress;
}
}
}
ASSERT(Utils::IsInt(reloc.size_in_bytes * kBitsPerByte, to_write));
WriteBytes(reinterpret_cast<const uint8_t*>(&to_write), reloc.size_in_bytes);
}
void SharedObjectWriter::WriteStream::WriteBytesWithRelocations(
const uint8_t* bytes,
intptr_t size,
intptr_t start_address,
const RelocationArray& relocations) {
// Resolve relocations as we write.
intptr_t current_pos = 0;
for (intptr_t i = 0; i < relocations.length(); i++) {
const auto& reloc = relocations[i];
// We assume here that the relocations are sorted in increasing order,
// with unique section offsets.
const intptr_t preceding = reloc.section_offset - current_pos;
if (preceding > 0) {
WriteBytes(bytes + current_pos, preceding);
current_pos += preceding;
}
ASSERT_EQUAL(current_pos, reloc.section_offset);
WriteRelocatableValue(start_address + current_pos, reloc, i);
current_pos += reloc.size_in_bytes;
}
WriteBytes(bytes + current_pos, size - current_pos);
}
} // namespace dart
#endif // DART_PRECOMPILER