2017-03-20 20:02:41 +00:00
|
|
|
// Copyright (c) 2017, 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/dwarf.h"
|
|
|
|
|
2021-02-02 11:35:00 +00:00
|
|
|
#include "vm/code_comments.h"
|
2017-03-20 20:02:41 +00:00
|
|
|
#include "vm/code_descriptors.h"
|
2019-05-28 18:48:57 +00:00
|
|
|
#include "vm/elf.h"
|
2019-10-25 11:53:14 +00:00
|
|
|
#include "vm/image_snapshot.h"
|
2017-03-20 20:02:41 +00:00
|
|
|
#include "vm/object_store.h"
|
|
|
|
|
|
|
|
namespace dart {
|
|
|
|
|
2020-06-22 09:29:45 +00:00
|
|
|
#if defined(DART_PRECOMPILER)
|
|
|
|
|
2021-04-26 11:44:47 +00:00
|
|
|
DEFINE_FLAG(bool,
|
|
|
|
resolve_dwarf_paths,
|
|
|
|
false,
|
|
|
|
"Resolve script URIs to absolute or relative file paths in DWARF");
|
|
|
|
|
2021-02-02 11:35:00 +00:00
|
|
|
DEFINE_FLAG(charp,
|
|
|
|
write_code_comments_as_synthetic_source_to,
|
|
|
|
nullptr,
|
|
|
|
"Print comments associated with instructions into the given file");
|
|
|
|
|
2020-06-22 09:29:45 +00:00
|
|
|
class DwarfPosition {
|
|
|
|
public:
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
DwarfPosition(int32_t line, int32_t column) : line_(line), column_(column) {
|
2020-06-22 09:29:45 +00:00
|
|
|
// Should only have no line information if also no column information.
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
ASSERT(line_ > kNoLine || column_ <= kNoColumn);
|
2020-06-22 09:29:45 +00:00
|
|
|
}
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
// CodeSourceMaps start the line and column registers at -1, not at 0, and
|
|
|
|
// the arguments passed to ChangePosition are retrieved from CodeSourceMaps.
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
explicit DwarfPosition(int32_t line) : DwarfPosition(line, -1) {}
|
|
|
|
constexpr DwarfPosition() : line_(-1), column_(-1) {}
|
2020-06-22 09:29:45 +00:00
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
// The DWARF standard uses 0 to denote missing line or column
|
|
|
|
// information.
|
|
|
|
static constexpr int32_t kNoLine = 0;
|
|
|
|
static constexpr int32_t kNoColumn = 0;
|
|
|
|
|
|
|
|
int32_t line() const { return line_ > kNoLine ? line_ : kNoLine; }
|
|
|
|
int32_t column() const { return column_ > kNoColumn ? column_ : kNoColumn; }
|
|
|
|
|
|
|
|
// Adjusts the contents given the arguments to a ChangePosition instruction
|
|
|
|
// from CodeSourceMaps.
|
|
|
|
void ChangePosition(int32_t line_delta, int32_t new_column) {
|
|
|
|
line_ = Utils::AddWithWrapAround(line_, line_delta);
|
|
|
|
column_ = new_column;
|
|
|
|
}
|
2020-06-22 09:29:45 +00:00
|
|
|
|
|
|
|
private:
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
int32_t line_;
|
|
|
|
int32_t column_;
|
2020-06-22 09:29:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static constexpr auto kNoDwarfPositionInfo = DwarfPosition();
|
2017-03-20 20:02:41 +00:00
|
|
|
|
|
|
|
class InliningNode : public ZoneAllocated {
|
|
|
|
public:
|
|
|
|
InliningNode(const Function& function,
|
2020-06-22 09:29:45 +00:00
|
|
|
const DwarfPosition& position,
|
2017-03-20 20:02:41 +00:00
|
|
|
int32_t start_pc_offset)
|
|
|
|
: function(function),
|
2020-06-22 09:29:45 +00:00
|
|
|
position(position),
|
2017-03-20 20:02:41 +00:00
|
|
|
start_pc_offset(start_pc_offset),
|
|
|
|
end_pc_offset(-1),
|
|
|
|
children_head(NULL),
|
|
|
|
children_tail(NULL),
|
2018-02-09 18:49:39 +00:00
|
|
|
children_next(NULL) {
|
2018-02-16 20:48:59 +00:00
|
|
|
RELEASE_ASSERT(!function.IsNull());
|
|
|
|
RELEASE_ASSERT(function.IsNotTemporaryScopedHandle());
|
2018-02-09 18:49:39 +00:00
|
|
|
}
|
2017-03-20 20:02:41 +00:00
|
|
|
|
|
|
|
void AppendChild(InliningNode* child) {
|
|
|
|
if (children_tail == NULL) {
|
|
|
|
children_head = children_tail = child;
|
|
|
|
} else {
|
|
|
|
children_tail->children_next = child;
|
|
|
|
children_tail = child;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const Function& function;
|
2020-06-22 09:29:45 +00:00
|
|
|
DwarfPosition position;
|
2017-03-20 20:02:41 +00:00
|
|
|
int32_t start_pc_offset;
|
|
|
|
int32_t end_pc_offset;
|
|
|
|
InliningNode* children_head;
|
|
|
|
InliningNode* children_tail;
|
|
|
|
InliningNode* children_next;
|
|
|
|
};
|
|
|
|
|
2019-12-18 14:14:41 +00:00
|
|
|
template <typename T>
|
|
|
|
Trie<T>* Trie<T>::AddString(Zone* zone,
|
|
|
|
Trie<T>* trie,
|
|
|
|
const char* key,
|
|
|
|
const T* value) {
|
|
|
|
ASSERT(key != nullptr);
|
|
|
|
if (trie == nullptr) {
|
|
|
|
trie = new (zone) Trie<T>();
|
|
|
|
}
|
|
|
|
if (*key == '\0') {
|
|
|
|
ASSERT(trie->value_ == nullptr);
|
|
|
|
trie->value_ = value;
|
|
|
|
} else {
|
|
|
|
auto const index = ChildIndex(*key);
|
|
|
|
ASSERT(index >= 0 && index < kNumValidChars);
|
|
|
|
trie->children_[index] =
|
|
|
|
AddString(zone, trie->children_[index], key + 1, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return trie;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
const T* Trie<T>::Lookup(const Trie<T>* trie, const char* key, intptr_t* end) {
|
|
|
|
intptr_t i = 0;
|
|
|
|
for (; key[i] != '\0'; i++) {
|
|
|
|
auto const index = ChildIndex(key[i]);
|
|
|
|
ASSERT(index < kNumValidChars);
|
|
|
|
if (index < 0) {
|
|
|
|
if (end == nullptr) return nullptr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Still find the longest valid trie prefix when no stored value.
|
|
|
|
if (trie == nullptr) continue;
|
|
|
|
trie = trie->children_[index];
|
|
|
|
}
|
|
|
|
if (end != nullptr) {
|
|
|
|
*end = i;
|
|
|
|
}
|
|
|
|
if (trie == nullptr) return nullptr;
|
|
|
|
return trie->value_;
|
|
|
|
}
|
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
Dwarf::Dwarf(Zone* zone)
|
2017-03-20 20:02:41 +00:00
|
|
|
: zone_(zone),
|
2019-12-18 14:14:41 +00:00
|
|
|
reverse_obfuscation_trie_(CreateReverseObfuscationTrie(zone)),
|
2017-03-20 20:02:41 +00:00
|
|
|
codes_(zone, 1024),
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
code_to_name_(zone),
|
2017-03-20 20:02:41 +00:00
|
|
|
functions_(zone, 1024),
|
|
|
|
function_to_index_(zone),
|
|
|
|
scripts_(zone, 1024),
|
|
|
|
script_to_index_(zone),
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
temp_(0) {}
|
|
|
|
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
void Dwarf::AddCode(const Code& orig_code, const char* name) {
|
2020-06-12 11:34:02 +00:00
|
|
|
ASSERT(!orig_code.IsNull());
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
ASSERT(name != nullptr);
|
|
|
|
|
|
|
|
if (auto const old_pair = code_to_name_.Lookup(&orig_code)) {
|
|
|
|
// Dwarf objects can be shared, so we may get the same information for a
|
|
|
|
// given code object in different calls. In DEBUG mode, make sure the
|
|
|
|
// information is the same before returning.
|
|
|
|
ASSERT(old_pair->value != nullptr);
|
|
|
|
ASSERT_EQUAL(strcmp(old_pair->value, name), 0);
|
|
|
|
return;
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
}
|
2020-03-13 14:14:01 +00:00
|
|
|
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
// Generate an appropriately zoned ZoneHandle for storing.
|
2021-01-15 23:32:02 +00:00
|
|
|
const auto& code = Code::ZoneHandle(zone_, orig_code.ptr());
|
2020-03-13 14:14:01 +00:00
|
|
|
codes_.Add(&code);
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
// Currently assumes the name has the same lifetime as the Zone of the
|
|
|
|
// Dwarf object (which is currently true). Otherwise, need to copy.
|
|
|
|
code_to_name_.Insert({&code, name});
|
|
|
|
|
2021-02-22 10:46:28 +00:00
|
|
|
if (code.IsFunctionCode() && !code.IsUnknownDartCode()) {
|
2017-03-20 20:02:41 +00:00
|
|
|
const Function& function = Function::Handle(zone_, code.function());
|
|
|
|
AddFunction(function);
|
|
|
|
}
|
|
|
|
const Array& inline_functions =
|
|
|
|
Array::Handle(zone_, code.inlined_id_to_function());
|
|
|
|
if (!inline_functions.IsNull()) {
|
|
|
|
Function& function = Function::Handle(zone_);
|
|
|
|
for (intptr_t i = 0; i < inline_functions.Length(); i++) {
|
|
|
|
function ^= inline_functions.At(i);
|
|
|
|
AddFunction(function);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
intptr_t Dwarf::AddFunction(const Function& function) {
|
2018-02-09 18:49:39 +00:00
|
|
|
RELEASE_ASSERT(!function.IsNull());
|
2017-03-20 20:02:41 +00:00
|
|
|
FunctionIndexPair* pair = function_to_index_.Lookup(&function);
|
|
|
|
if (pair != NULL) {
|
|
|
|
return pair->index_;
|
|
|
|
}
|
|
|
|
intptr_t index = functions_.length();
|
2021-01-15 23:32:02 +00:00
|
|
|
const Function& zone_func = Function::ZoneHandle(zone_, function.ptr());
|
2017-03-20 20:02:41 +00:00
|
|
|
function_to_index_.Insert(FunctionIndexPair(&zone_func, index));
|
|
|
|
functions_.Add(&zone_func);
|
|
|
|
const Script& script = Script::Handle(zone_, function.script());
|
|
|
|
AddScript(script);
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
intptr_t Dwarf::AddScript(const Script& script) {
|
2018-02-16 20:48:59 +00:00
|
|
|
RELEASE_ASSERT(!script.IsNull());
|
2017-03-20 20:02:41 +00:00
|
|
|
ScriptIndexPair* pair = script_to_index_.Lookup(&script);
|
|
|
|
if (pair != NULL) {
|
|
|
|
return pair->index_;
|
|
|
|
}
|
|
|
|
// DWARF file numbers start from 1.
|
|
|
|
intptr_t index = scripts_.length() + 1;
|
2021-01-15 23:32:02 +00:00
|
|
|
const Script& zone_script = Script::ZoneHandle(zone_, script.ptr());
|
2017-03-20 20:02:41 +00:00
|
|
|
script_to_index_.Insert(ScriptIndexPair(&zone_script, index));
|
|
|
|
scripts_.Add(&zone_script);
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
intptr_t Dwarf::LookupFunction(const Function& function) {
|
2018-02-16 20:48:59 +00:00
|
|
|
RELEASE_ASSERT(!function.IsNull());
|
2017-03-20 20:02:41 +00:00
|
|
|
FunctionIndexPair* pair = function_to_index_.Lookup(&function);
|
|
|
|
if (pair == NULL) {
|
|
|
|
FATAL1("Function detected too late during DWARF generation: %s",
|
|
|
|
function.ToCString());
|
|
|
|
}
|
|
|
|
return pair->index_;
|
|
|
|
}
|
|
|
|
|
|
|
|
intptr_t Dwarf::LookupScript(const Script& script) {
|
2018-02-16 20:48:59 +00:00
|
|
|
RELEASE_ASSERT(!script.IsNull());
|
2017-03-20 20:02:41 +00:00
|
|
|
ScriptIndexPair* pair = script_to_index_.Lookup(&script);
|
|
|
|
if (pair == NULL) {
|
|
|
|
FATAL1("Script detected too late during DWARF generation: %s",
|
|
|
|
script.ToCString());
|
|
|
|
}
|
|
|
|
return pair->index_;
|
|
|
|
}
|
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
void Dwarf::WriteAbbreviations(DwarfWriteStream* stream) {
|
2019-05-28 18:48:57 +00:00
|
|
|
// Dwarf data mostly takes the form of a tree, whose nodes are called
|
|
|
|
// DIEs. Each DIE begins with an abbreviation code, and the abbreviation
|
|
|
|
// describes the attributes of that DIE and their representation.
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->uleb128(kCompilationUnit); // Abbrev code.
|
|
|
|
stream->uleb128(DW_TAG_compile_unit); // Type.
|
|
|
|
stream->u1(DW_CHILDREN_yes);
|
|
|
|
stream->uleb128(DW_AT_name); // Start of attributes.
|
|
|
|
stream->uleb128(DW_FORM_string);
|
|
|
|
stream->uleb128(DW_AT_producer);
|
|
|
|
stream->uleb128(DW_FORM_string);
|
|
|
|
stream->uleb128(DW_AT_comp_dir);
|
|
|
|
stream->uleb128(DW_FORM_string);
|
|
|
|
stream->uleb128(DW_AT_low_pc);
|
|
|
|
stream->uleb128(DW_FORM_addr);
|
|
|
|
stream->uleb128(DW_AT_high_pc);
|
|
|
|
stream->uleb128(DW_FORM_addr);
|
|
|
|
stream->uleb128(DW_AT_stmt_list);
|
|
|
|
stream->uleb128(DW_FORM_sec_offset);
|
|
|
|
stream->uleb128(0);
|
|
|
|
stream->uleb128(0); // End of attributes.
|
|
|
|
|
|
|
|
stream->uleb128(kAbstractFunction); // Abbrev code.
|
|
|
|
stream->uleb128(DW_TAG_subprogram); // Type.
|
|
|
|
stream->u1(DW_CHILDREN_yes);
|
|
|
|
stream->uleb128(DW_AT_name); // Start of attributes.
|
|
|
|
stream->uleb128(DW_FORM_string);
|
|
|
|
stream->uleb128(DW_AT_decl_file);
|
|
|
|
stream->uleb128(DW_FORM_udata);
|
|
|
|
stream->uleb128(DW_AT_inline);
|
|
|
|
stream->uleb128(DW_FORM_udata);
|
|
|
|
stream->uleb128(0);
|
|
|
|
stream->uleb128(0); // End of attributes.
|
|
|
|
|
|
|
|
stream->uleb128(kConcreteFunction); // Abbrev code.
|
|
|
|
stream->uleb128(DW_TAG_subprogram); // Type.
|
|
|
|
stream->u1(DW_CHILDREN_yes);
|
|
|
|
stream->uleb128(DW_AT_abstract_origin); // Start of attributes.
|
|
|
|
stream->uleb128(DW_FORM_ref4);
|
|
|
|
stream->uleb128(DW_AT_low_pc);
|
|
|
|
stream->uleb128(DW_FORM_addr);
|
|
|
|
stream->uleb128(DW_AT_high_pc);
|
|
|
|
stream->uleb128(DW_FORM_addr);
|
2021-04-27 23:31:02 +00:00
|
|
|
stream->uleb128(DW_AT_artificial);
|
|
|
|
stream->uleb128(DW_FORM_flag);
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->uleb128(0);
|
|
|
|
stream->uleb128(0); // End of attributes.
|
|
|
|
|
|
|
|
stream->uleb128(kInlinedFunction); // Abbrev code.
|
|
|
|
stream->uleb128(DW_TAG_inlined_subroutine); // Type.
|
|
|
|
stream->u1(DW_CHILDREN_yes);
|
|
|
|
stream->uleb128(DW_AT_abstract_origin); // Start of attributes.
|
|
|
|
stream->uleb128(DW_FORM_ref4);
|
|
|
|
stream->uleb128(DW_AT_low_pc);
|
|
|
|
stream->uleb128(DW_FORM_addr);
|
|
|
|
stream->uleb128(DW_AT_high_pc);
|
|
|
|
stream->uleb128(DW_FORM_addr);
|
|
|
|
stream->uleb128(DW_AT_call_file);
|
|
|
|
stream->uleb128(DW_FORM_udata);
|
|
|
|
stream->uleb128(DW_AT_call_line);
|
|
|
|
stream->uleb128(DW_FORM_udata);
|
[vm/aot] Reland "Keep column information when possible for precompiled mode."
Changes:
Doing this always in precompiled mode meant increased data segment sizes
when CodeSourceMaps are stored, since encoded line/column information is
larger in the LEB-like encoding used. Now we only store column
information when we produce non-symbolic stacks, since the increased
space needed to store the columns is instead in DWARF sections and can
be stripped or elided.
Original description:
Previously, we passed line number information to the stack trace printer
and to DWARF by changing the non-special positions in the CodeSourceMap
to line numbers in precompiled mode. However, doing this lost column
information.
We get the column information back in the majority of cases by encoding
the line number and column information when neither is too large to pack
together into 30 bits. (Here, 20 bits for line and 10 bits for column.)
Otherwise, we just store the line information as before, though due to
using a bit to encode whether column info exists, it's reduced to 30
bits. If the line info is too big for that, we just return kNoSourcePos.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: Ia8baee71468da6100a170fa305d03059ffd17f78
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151822
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-06-19 13:50:03 +00:00
|
|
|
stream->uleb128(DW_AT_call_column);
|
|
|
|
stream->uleb128(DW_FORM_udata);
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->uleb128(0);
|
|
|
|
stream->uleb128(0); // End of attributes.
|
|
|
|
|
|
|
|
stream->uleb128(0); // End of abbreviations.
|
2017-03-20 20:02:41 +00:00
|
|
|
}
|
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
void Dwarf::WriteDebugInfo(DwarfWriteStream* stream) {
|
2019-05-28 18:48:57 +00:00
|
|
|
// 7.5.1.1 Compilation Unit Header
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
// Unit length.
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
stream->WritePrefixedLength("cu", [&]() {
|
|
|
|
stream->u2(2); // DWARF version 2
|
|
|
|
stream->u4(0); // debug_abbrev_offset
|
|
|
|
stream->u1(compiler::target::kWordSize); // address_size
|
|
|
|
|
|
|
|
// Compilation Unit DIE. We describe the entire Dart program as a single
|
|
|
|
// compilation unit. Note we write attributes in the same order we declared
|
|
|
|
// them in our abbreviation above in WriteAbbreviations.
|
|
|
|
stream->uleb128(kCompilationUnit);
|
|
|
|
const Library& root_library = Library::Handle(
|
|
|
|
zone_, IsolateGroup::Current()->object_store()->root_library());
|
|
|
|
const String& root_uri = String::Handle(zone_, root_library.url());
|
|
|
|
stream->string(root_uri.ToCString()); // DW_AT_name
|
|
|
|
stream->string("Dart VM"); // DW_AT_producer
|
|
|
|
stream->string(""); // DW_AT_comp_dir
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
// DW_AT_low_pc
|
|
|
|
// The lowest instruction address in this object file that is part of our
|
|
|
|
// compilation unit. Dwarf consumers use this to quickly decide which
|
|
|
|
// compilation unit DIE to consult for a given pc.
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
stream->OffsetFromSymbol(kIsolateSnapshotInstructionsAsmSymbol, 0);
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
// DW_AT_high_pc
|
|
|
|
// The highest instruction address in this object file that is part of our
|
|
|
|
// compilation unit. Dwarf consumers use this to quickly decide which
|
|
|
|
// compilation unit DIE to consult for a given pc.
|
|
|
|
if (codes_.is_empty()) {
|
|
|
|
// No code objects in this program, so set high_pc to same as low_pc.
|
|
|
|
stream->OffsetFromSymbol(kIsolateSnapshotInstructionsAsmSymbol, 0);
|
|
|
|
} else {
|
|
|
|
const Code& last_code = *codes_.Last();
|
|
|
|
auto const last_code_name = code_to_name_.LookupValue(&last_code);
|
|
|
|
ASSERT(last_code_name != nullptr);
|
|
|
|
stream->OffsetFromSymbol(last_code_name, last_code.Size());
|
|
|
|
}
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
// DW_AT_stmt_list (offset into .debug_line)
|
|
|
|
// Indicates which line number program is associated with this compilation
|
|
|
|
// unit. We only emit a single line number program.
|
|
|
|
stream->u4(0);
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
WriteAbstractFunctions(stream);
|
|
|
|
WriteConcreteFunctions(stream);
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
stream->uleb128(0); // End of children.
|
|
|
|
|
|
|
|
stream->uleb128(0); // End of entries.
|
|
|
|
});
|
2017-03-20 20:02:41 +00:00
|
|
|
}
|
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
void Dwarf::WriteAbstractFunctions(DwarfWriteStream* stream) {
|
2017-03-20 20:02:41 +00:00
|
|
|
Script& script = Script::Handle(zone_);
|
|
|
|
String& name = String::Handle(zone_);
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->InitializeAbstractOrigins(functions_.length());
|
2020-05-13 15:43:11 +00:00
|
|
|
// By the point we're creating DWARF information, scripts have already lost
|
[vm/aot] Reland "Keep column information when possible for precompiled mode."
Changes:
Doing this always in precompiled mode meant increased data segment sizes
when CodeSourceMaps are stored, since encoded line/column information is
larger in the LEB-like encoding used. Now we only store column
information when we produce non-symbolic stacks, since the increased
space needed to store the columns is instead in DWARF sections and can
be stripped or elided.
Original description:
Previously, we passed line number information to the stack trace printer
and to DWARF by changing the non-special positions in the CodeSourceMap
to line numbers in precompiled mode. However, doing this lost column
information.
We get the column information back in the majority of cases by encoding
the line number and column information when neither is too large to pack
together into 30 bits. (Here, 20 bits for line and 10 bits for column.)
Otherwise, we just store the line information as before, though due to
using a bit to encode whether column info exists, it's reduced to 30
bits. If the line info is too big for that, we just return kNoSourcePos.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: Ia8baee71468da6100a170fa305d03059ffd17f78
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151822
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-06-19 13:50:03 +00:00
|
|
|
// their token stream and we can't look up their line number or column
|
|
|
|
// information, hence the lack of DW_AT_decl_line and DW_AT_decl_column.
|
2017-03-20 20:02:41 +00:00
|
|
|
for (intptr_t i = 0; i < functions_.length(); i++) {
|
|
|
|
const Function& function = *(functions_[i]);
|
|
|
|
name = function.QualifiedUserVisibleName();
|
|
|
|
script = function.script();
|
2019-12-18 14:14:41 +00:00
|
|
|
const intptr_t file = LookupScript(script);
|
|
|
|
auto const name_cstr = Deobfuscate(name.ToCString());
|
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->RegisterAbstractOrigin(i);
|
|
|
|
stream->uleb128(kAbstractFunction);
|
|
|
|
stream->string(name_cstr); // DW_AT_name
|
|
|
|
stream->uleb128(file); // DW_AT_decl_file
|
|
|
|
stream->uleb128(DW_INL_inlined); // DW_AT_inline
|
|
|
|
stream->uleb128(0); // End of children.
|
2017-03-20 20:02:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
void Dwarf::WriteConcreteFunctions(DwarfWriteStream* stream) {
|
2017-03-20 20:02:41 +00:00
|
|
|
Function& function = Function::Handle(zone_);
|
|
|
|
Script& script = Script::Handle(zone_);
|
|
|
|
for (intptr_t i = 0; i < codes_.length(); i++) {
|
|
|
|
const Code& code = *(codes_[i]);
|
2018-02-16 20:48:59 +00:00
|
|
|
RELEASE_ASSERT(!code.IsNull());
|
2021-02-22 10:46:28 +00:00
|
|
|
if (!code.IsFunctionCode() || code.IsUnknownDartCode()) {
|
2017-03-20 20:02:41 +00:00
|
|
|
continue;
|
|
|
|
}
|
2019-05-28 18:48:57 +00:00
|
|
|
|
2017-03-20 20:02:41 +00:00
|
|
|
function = code.function();
|
|
|
|
intptr_t function_index = LookupFunction(function);
|
|
|
|
script = function.script();
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
const char* asm_name = code_to_name_.LookupValue(&code);
|
|
|
|
ASSERT(asm_name != nullptr);
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->uleb128(kConcreteFunction);
|
2017-03-20 20:02:41 +00:00
|
|
|
// DW_AT_abstract_origin
|
|
|
|
// References a node written above in WriteAbstractFunctions.
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->AbstractOrigin(function_index);
|
2017-03-20 20:02:41 +00:00
|
|
|
|
|
|
|
// DW_AT_low_pc
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->OffsetFromSymbol(asm_name, 0);
|
|
|
|
// DW_AT_high_pc
|
|
|
|
stream->OffsetFromSymbol(asm_name, code.Size());
|
2021-04-27 23:31:02 +00:00
|
|
|
// DW_AT_artificial
|
|
|
|
stream->u1(function.is_visible() ? 0 : 1);
|
2017-03-20 20:02:41 +00:00
|
|
|
|
|
|
|
InliningNode* node = ExpandInliningTree(code);
|
|
|
|
if (node != NULL) {
|
|
|
|
for (InliningNode* child = node->children_head; child != NULL;
|
|
|
|
child = child->children_next) {
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
WriteInliningNode(stream, child, asm_name, script);
|
2017-03-20 20:02:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->uleb128(0); // End of children.
|
2017-03-20 20:02:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Our state machine encodes position metadata such that we don't know the
|
|
|
|
// end pc for an inlined function until it is popped, but DWARF DIEs encode
|
|
|
|
// it where the function is pushed. We expand the state transitions into
|
|
|
|
// an in-memory tree to do the conversion.
|
|
|
|
InliningNode* Dwarf::ExpandInliningTree(const Code& code) {
|
|
|
|
const CodeSourceMap& map =
|
|
|
|
CodeSourceMap::Handle(zone_, code.code_source_map());
|
|
|
|
if (map.IsNull()) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
const Array& functions = Array::Handle(zone_, code.inlined_id_to_function());
|
2018-02-09 18:49:39 +00:00
|
|
|
const Function& root_function = Function::ZoneHandle(zone_, code.function());
|
2018-02-16 23:18:11 +00:00
|
|
|
if (root_function.IsNull()) {
|
|
|
|
FATAL1("Wherefore art thou functionless code, %s?\n", code.ToCString());
|
|
|
|
}
|
2017-03-20 20:02:41 +00:00
|
|
|
|
|
|
|
GrowableArray<InliningNode*> node_stack(zone_, 4);
|
2020-06-22 09:29:45 +00:00
|
|
|
GrowableArray<DwarfPosition> token_positions(zone_, 4);
|
2017-03-20 20:02:41 +00:00
|
|
|
|
|
|
|
NoSafepointScope no_safepoint;
|
|
|
|
ReadStream stream(map.Data(), map.Length());
|
|
|
|
|
|
|
|
int32_t current_pc_offset = 0;
|
2020-06-22 09:29:45 +00:00
|
|
|
token_positions.Add(kNoDwarfPositionInfo);
|
2017-03-20 20:02:41 +00:00
|
|
|
InliningNode* root_node =
|
2020-06-22 09:29:45 +00:00
|
|
|
new (zone_) InliningNode(root_function, token_positions.Last(), 0);
|
2017-03-20 20:02:41 +00:00
|
|
|
root_node->end_pc_offset = code.Size();
|
|
|
|
node_stack.Add(root_node);
|
|
|
|
|
|
|
|
while (stream.PendingBytes() > 0) {
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
int32_t arg1;
|
|
|
|
int32_t arg2 = -1;
|
|
|
|
const uint8_t opcode = CodeSourceMapOps::Read(&stream, &arg1, &arg2);
|
2017-03-20 20:02:41 +00:00
|
|
|
switch (opcode) {
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
case CodeSourceMapOps::kChangePosition: {
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
DwarfPosition& pos = token_positions[token_positions.length() - 1];
|
|
|
|
pos.ChangePosition(arg1, arg2);
|
2017-03-20 20:02:41 +00:00
|
|
|
break;
|
|
|
|
}
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
case CodeSourceMapOps::kAdvancePC: {
|
|
|
|
current_pc_offset += arg1;
|
2017-03-20 20:02:41 +00:00
|
|
|
break;
|
|
|
|
}
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
case CodeSourceMapOps::kPushFunction: {
|
2017-03-20 20:02:41 +00:00
|
|
|
const Function& child_func =
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
Function::ZoneHandle(zone_, Function::RawCast(functions.At(arg1)));
|
2020-06-22 09:29:45 +00:00
|
|
|
InliningNode* child_node = new (zone_)
|
|
|
|
InliningNode(child_func, token_positions.Last(), current_pc_offset);
|
2017-03-20 20:02:41 +00:00
|
|
|
node_stack.Last()->AppendChild(child_node);
|
|
|
|
node_stack.Add(child_node);
|
2020-06-22 09:29:45 +00:00
|
|
|
token_positions.Add(kNoDwarfPositionInfo);
|
2017-03-20 20:02:41 +00:00
|
|
|
break;
|
|
|
|
}
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
case CodeSourceMapOps::kPopFunction: {
|
2017-03-20 20:02:41 +00:00
|
|
|
// We never pop the root function.
|
|
|
|
ASSERT(node_stack.length() > 1);
|
|
|
|
ASSERT(token_positions.length() > 1);
|
|
|
|
node_stack.Last()->end_pc_offset = current_pc_offset;
|
|
|
|
node_stack.RemoveLast();
|
|
|
|
token_positions.RemoveLast();
|
|
|
|
break;
|
|
|
|
}
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
case CodeSourceMapOps::kNullCheck: {
|
2018-04-26 20:33:15 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-03-20 20:02:41 +00:00
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (node_stack.length() > 1) {
|
|
|
|
node_stack.Last()->end_pc_offset = current_pc_offset;
|
|
|
|
node_stack.RemoveLast();
|
|
|
|
token_positions.RemoveLast();
|
|
|
|
}
|
|
|
|
ASSERT(node_stack[0] == root_node);
|
|
|
|
return root_node;
|
|
|
|
}
|
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
void Dwarf::WriteInliningNode(DwarfWriteStream* stream,
|
|
|
|
InliningNode* node,
|
|
|
|
const char* root_asm_name,
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
const Script& parent_script) {
|
2017-03-20 20:02:41 +00:00
|
|
|
intptr_t file = LookupScript(parent_script);
|
|
|
|
intptr_t function_index = LookupFunction(node->function);
|
|
|
|
const Script& script = Script::Handle(zone_, node->function.script());
|
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->uleb128(kInlinedFunction);
|
2017-03-20 20:02:41 +00:00
|
|
|
// DW_AT_abstract_origin
|
|
|
|
// References a node written above in WriteAbstractFunctions.
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->AbstractOrigin(function_index);
|
2019-10-25 11:53:14 +00:00
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
// DW_AT_low_pc
|
|
|
|
stream->OffsetFromSymbol(root_asm_name, node->start_pc_offset);
|
|
|
|
// DW_AT_high_pc
|
|
|
|
stream->OffsetFromSymbol(root_asm_name, node->end_pc_offset);
|
2017-03-20 20:02:41 +00:00
|
|
|
// DW_AT_call_file
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->uleb128(file);
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
|
2017-03-20 20:02:41 +00:00
|
|
|
// DW_AT_call_line
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
stream->uleb128(node->position.line());
|
[vm/aot] Reland "Keep column information when possible for precompiled mode."
Changes:
Doing this always in precompiled mode meant increased data segment sizes
when CodeSourceMaps are stored, since encoded line/column information is
larger in the LEB-like encoding used. Now we only store column
information when we produce non-symbolic stacks, since the increased
space needed to store the columns is instead in DWARF sections and can
be stripped or elided.
Original description:
Previously, we passed line number information to the stack trace printer
and to DWARF by changing the non-special positions in the CodeSourceMap
to line numbers in precompiled mode. However, doing this lost column
information.
We get the column information back in the majority of cases by encoding
the line number and column information when neither is too large to pack
together into 30 bits. (Here, 20 bits for line and 10 bits for column.)
Otherwise, we just store the line information as before, though due to
using a bit to encode whether column info exists, it's reduced to 30
bits. If the line info is too big for that, we just return kNoSourcePos.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: Ia8baee71468da6100a170fa305d03059ffd17f78
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151822
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-06-19 13:50:03 +00:00
|
|
|
// DW_at_call_column
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
stream->uleb128(node->position.column());
|
2017-03-20 20:02:41 +00:00
|
|
|
|
|
|
|
for (InliningNode* child = node->children_head; child != NULL;
|
|
|
|
child = child->children_next) {
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
WriteInliningNode(stream, child, root_asm_name, script);
|
2017-03-20 20:02:41 +00:00
|
|
|
}
|
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
stream->uleb128(0); // End of children.
|
2017-03-20 20:02:41 +00:00
|
|
|
}
|
|
|
|
|
2021-02-02 11:35:00 +00:00
|
|
|
// Helper class for tracking state of DWARF registers and emitting
|
|
|
|
// line number program commands to set these registers to the right
|
|
|
|
// state.
|
|
|
|
class LineNumberProgramWriter {
|
|
|
|
public:
|
|
|
|
explicit LineNumberProgramWriter(DwarfWriteStream* stream)
|
|
|
|
: stream_(stream) {}
|
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
void EmitRow(intptr_t file,
|
|
|
|
intptr_t line,
|
|
|
|
intptr_t column,
|
|
|
|
const char* asm_name,
|
|
|
|
intptr_t pc_offset) {
|
|
|
|
if (AddRow(file, line, column, asm_name, pc_offset)) {
|
|
|
|
// Address register must be updated from 0 before emitting an LNP row
|
|
|
|
// (dartbug.com/41756).
|
|
|
|
stream_->u1(Dwarf::DW_LNS_copy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Associates the given file, line, and column information for the instruction
|
|
|
|
// at the pc_offset into the instructions payload of the Code object with the
|
|
|
|
// symbol asm_name. Returns whether any changes were made to the stream.
|
|
|
|
bool AddRow(intptr_t file,
|
|
|
|
intptr_t line,
|
|
|
|
intptr_t column,
|
|
|
|
const char* asm_name,
|
|
|
|
intptr_t pc_offset) {
|
|
|
|
ASSERT_EQUAL(end_sequence_, false);
|
|
|
|
bool source_info_changed = false;
|
|
|
|
// Note that files are 1-indexed.
|
|
|
|
ASSERT(file >= 1);
|
2021-02-02 11:35:00 +00:00
|
|
|
if (file != file_) {
|
|
|
|
stream_->u1(Dwarf::DW_LNS_set_file);
|
|
|
|
stream_->uleb128(file);
|
|
|
|
file_ = file;
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
source_info_changed = true;
|
2021-02-02 11:35:00 +00:00
|
|
|
}
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
ASSERT(line >= DwarfPosition::kNoLine);
|
2021-02-02 11:35:00 +00:00
|
|
|
if (line != line_) {
|
|
|
|
stream_->u1(Dwarf::DW_LNS_advance_line);
|
|
|
|
stream_->sleb128(line - line_);
|
|
|
|
line_ = line;
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
source_info_changed = true;
|
2021-02-02 11:35:00 +00:00
|
|
|
}
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
ASSERT(column >= DwarfPosition::kNoColumn);
|
2021-02-02 11:35:00 +00:00
|
|
|
if (column != column_) {
|
|
|
|
stream_->u1(Dwarf::DW_LNS_set_column);
|
|
|
|
stream_->uleb128(column);
|
|
|
|
column_ = column;
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
source_info_changed = true;
|
|
|
|
}
|
|
|
|
// If the file, line, and column information match that for the previous
|
|
|
|
// AddRow call, no change is made to the stream. This is because all
|
|
|
|
// addresses between two line number program rows inherit the source
|
|
|
|
// information from the first.
|
|
|
|
if (source_info_changed) {
|
|
|
|
SetCurrentPosition(asm_name, pc_offset);
|
2021-02-02 11:35:00 +00:00
|
|
|
}
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
return source_info_changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MarkEnd() {
|
|
|
|
ASSERT_EQUAL(end_sequence_, false);
|
|
|
|
// End of contiguous machine code.
|
|
|
|
stream_->u1(0); // This is an extended opcode
|
|
|
|
stream_->u1(1); // that is 1 byte long
|
|
|
|
stream_->u1(Dwarf::DW_LNE_end_sequence);
|
|
|
|
end_sequence_ = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MarkEnd(const char* asm_name, intptr_t pc_offset) {
|
|
|
|
ASSERT_EQUAL(end_sequence_, false);
|
|
|
|
SetCurrentPosition(asm_name, pc_offset);
|
|
|
|
MarkEnd();
|
2021-02-02 11:35:00 +00:00
|
|
|
}
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
private:
|
|
|
|
void SetCurrentPosition(const char* asm_name, intptr_t pc_offset) {
|
|
|
|
// Each LNP row is either in a different function from the previous row
|
|
|
|
// or is at an increasing PC offset into the same function.
|
|
|
|
ASSERT(asm_name != nullptr);
|
|
|
|
ASSERT(pc_offset >= 0);
|
|
|
|
ASSERT(asm_name_ != asm_name || pc_offset > pc_offset_);
|
|
|
|
if (asm_name_ != asm_name) {
|
|
|
|
// Set the address register to the given offset into the new code payload.
|
2021-02-02 11:35:00 +00:00
|
|
|
auto const instr_size = 1 + compiler::target::kWordSize;
|
|
|
|
stream_->u1(0); // This is an extended opcode
|
|
|
|
stream_->u1(instr_size); // that is 5 or 9 bytes long
|
|
|
|
stream_->u1(Dwarf::DW_LNE_set_address);
|
|
|
|
stream_->OffsetFromSymbol(asm_name, pc_offset);
|
|
|
|
} else {
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
// Change the address register by the difference in the two offsets.
|
2021-02-02 11:35:00 +00:00
|
|
|
stream_->u1(Dwarf::DW_LNS_advance_pc);
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
stream_->uleb128(pc_offset - pc_offset_);
|
2021-02-02 11:35:00 +00:00
|
|
|
}
|
|
|
|
asm_name_ = asm_name;
|
|
|
|
pc_offset_ = pc_offset;
|
|
|
|
}
|
2017-03-20 20:02:41 +00:00
|
|
|
|
2021-02-02 11:35:00 +00:00
|
|
|
DwarfWriteStream* const stream_;
|
|
|
|
// The initial values for the line number program state machine registers
|
|
|
|
// according to the DWARF standard.
|
|
|
|
intptr_t pc_offset_ = 0;
|
|
|
|
intptr_t file_ = 1;
|
|
|
|
intptr_t line_ = 1;
|
|
|
|
intptr_t column_ = 0;
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
intptr_t end_sequence_ = false;
|
2017-03-20 20:02:41 +00:00
|
|
|
|
2021-02-02 11:35:00 +00:00
|
|
|
// Other info not stored in the state machine registers.
|
|
|
|
const char* asm_name_ = nullptr;
|
|
|
|
};
|
2017-03-20 20:02:41 +00:00
|
|
|
|
2021-02-02 11:35:00 +00:00
|
|
|
void Dwarf::WriteSyntheticLineNumberProgram(LineNumberProgramWriter* writer) {
|
|
|
|
// We emit it last after all other scripts.
|
|
|
|
const intptr_t comments_file_index = scripts_.length() + 1;
|
2017-03-20 20:02:41 +00:00
|
|
|
|
2021-02-02 11:35:00 +00:00
|
|
|
auto file_open = Dart::file_open_callback();
|
|
|
|
auto file_write = Dart::file_write_callback();
|
|
|
|
auto file_close = Dart::file_close_callback();
|
|
|
|
if ((file_open == nullptr) || (file_write == nullptr) ||
|
|
|
|
(file_close == nullptr)) {
|
2021-09-02 19:47:45 +00:00
|
|
|
OS::PrintErr("warning: Could not access file callbacks.");
|
2021-02-02 11:35:00 +00:00
|
|
|
return;
|
|
|
|
}
|
2019-12-18 14:14:41 +00:00
|
|
|
|
2021-02-02 11:35:00 +00:00
|
|
|
TextBuffer comments_buffer(128 * KB);
|
|
|
|
|
2021-09-02 19:47:45 +00:00
|
|
|
const char* filename = FLAG_write_code_comments_as_synthetic_source_to;
|
|
|
|
void* comments_file = file_open(filename, /*write=*/true);
|
2021-02-02 11:35:00 +00:00
|
|
|
if (comments_file == nullptr) {
|
2021-09-02 19:47:45 +00:00
|
|
|
OS::PrintErr("warning: Failed to write code comments source: %s\n",
|
|
|
|
filename);
|
2021-02-02 11:35:00 +00:00
|
|
|
return;
|
2019-05-28 18:48:57 +00:00
|
|
|
}
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
// Lines in DWARF are 1-indexed.
|
|
|
|
intptr_t current_line = 1;
|
2017-03-20 20:02:41 +00:00
|
|
|
|
2021-02-02 11:35:00 +00:00
|
|
|
for (intptr_t i = 0; i < codes_.length(); i++) {
|
|
|
|
const Code& code = *(codes_[i]);
|
|
|
|
auto const asm_name = code_to_name_.LookupValue(&code);
|
|
|
|
ASSERT(asm_name != nullptr);
|
|
|
|
|
|
|
|
auto& comments = code.comments();
|
|
|
|
for (intptr_t i = 0, len = comments.Length(); i < len;) {
|
|
|
|
intptr_t current_pc_offset = comments.PCOffsetAt(i);
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
writer->AddRow(comments_file_index, current_line,
|
|
|
|
DwarfPosition::kNoColumn, asm_name, current_pc_offset);
|
2021-02-02 11:35:00 +00:00
|
|
|
while (i < len && current_pc_offset == comments.PCOffsetAt(i)) {
|
|
|
|
comments_buffer.AddString(comments.CommentAt(i));
|
|
|
|
comments_buffer.AddChar('\n');
|
|
|
|
current_line++;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
file_write(comments_buffer.buffer(), comments_buffer.length(), comments_file);
|
|
|
|
file_close(comments_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Dwarf::WriteLineNumberProgramFromCodeSourceMaps(
|
|
|
|
LineNumberProgramWriter* writer) {
|
2017-03-20 20:02:41 +00:00
|
|
|
Function& root_function = Function::Handle(zone_);
|
|
|
|
Script& script = Script::Handle(zone_);
|
|
|
|
CodeSourceMap& map = CodeSourceMap::Handle(zone_);
|
|
|
|
Array& functions = Array::Handle(zone_);
|
|
|
|
GrowableArray<const Function*> function_stack(zone_, 8);
|
2020-06-22 09:29:45 +00:00
|
|
|
GrowableArray<DwarfPosition> token_positions(zone_, 8);
|
2017-03-20 20:02:41 +00:00
|
|
|
|
|
|
|
for (intptr_t i = 0; i < codes_.length(); i++) {
|
|
|
|
const Code& code = *(codes_[i]);
|
[vm] Simplify symbol naming/address retrieval.
Before, picking a symbol name for a Code object when generating
assembly required adding a placeholder entry in the Dwarf object,
because the Dwarf object separately used a SnapshotTextObjectNamer
to determine the appropriate symbol name to use in relocations.
Instead, now the ImageWriter subclasses are entirely responsible for
creating the symbol name for a given Code object, and that name is
passed when adding the Code object to the Dwarf object.
For Elf output, we eagerly create symbols for sections and Code objects
again in the appropriate symbol table, and so looking up the start of a
given section or Code object can be done simply by asking for the
corresponding symbol's address, removing special case methods and other
workarounds.
We also clean up the generated static and dynamic symbol tables by
only generating local symbols for Code objects and BSS sections (these
are local in assembly output also), and only adding global symbols to
the dynamic symbol table.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-release-x64-try
Change-Id: Ie40c0c836681e98f345483136bb6860e5588ef30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166002
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-10-06 17:10:05 +00:00
|
|
|
auto const asm_name = code_to_name_.LookupValue(&code);
|
|
|
|
ASSERT(asm_name != nullptr);
|
2019-05-28 18:48:57 +00:00
|
|
|
|
2017-03-20 20:02:41 +00:00
|
|
|
map = code.code_source_map();
|
|
|
|
if (map.IsNull()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
root_function = code.function();
|
|
|
|
functions = code.inlined_id_to_function();
|
|
|
|
|
|
|
|
NoSafepointScope no_safepoint;
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
ReadStream code_map_stream(map.Data(), map.Length());
|
2017-03-20 20:02:41 +00:00
|
|
|
|
|
|
|
function_stack.Clear();
|
|
|
|
token_positions.Clear();
|
|
|
|
|
2021-11-10 17:52:03 +00:00
|
|
|
// CodeSourceMap might start in the following way:
|
|
|
|
//
|
|
|
|
// ChangePosition function.token_pos()
|
|
|
|
// AdvancePC 0
|
|
|
|
// ChangePosition x
|
|
|
|
// AdvancePC y
|
|
|
|
//
|
|
|
|
// This entry is emitted to ensure correct symbolization of
|
|
|
|
// function listener frames produced by async unwinding.
|
|
|
|
// (See EmitFunctionEntrySourcePositionDescriptorIfNeeded).
|
|
|
|
// Directly interpreting this sequence would cause us to emit
|
|
|
|
// multiple with the same pc into line number table and different
|
|
|
|
// position information. To avoid this will make an adjustment for
|
|
|
|
// the second record we emit: if position x is a synthetic one we will
|
|
|
|
// simply drop the second record, if position x is real then we will
|
|
|
|
// emit row with a slightly adjusted PC (by 1 byte). This would not
|
|
|
|
// affect symbolization (you can't have a call that is 1 byte long)
|
|
|
|
// but will avoid line number table entries with the same PC.
|
|
|
|
bool function_entry_position_was_emitted = false;
|
|
|
|
|
2017-03-20 20:02:41 +00:00
|
|
|
int32_t current_pc_offset = 0;
|
|
|
|
function_stack.Add(&root_function);
|
2020-06-22 09:29:45 +00:00
|
|
|
token_positions.Add(kNoDwarfPositionInfo);
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm/aot] Rework Dwarf object to be output-agnostic.
Previously, we created a separate DWARF object for each possible output.
For the most part, the information stored in each DWARF object was the
same, but the DWARF object was responsible for keeping track of abstract
origin addresses (in the non-assembly case) and for actually generating
the desired output (assembly or binary).
Instead, abstract out the output formatting into a DwarfWriteStream,
whose subclasses handle both the final output format and certain details
that differ between assembly and binary outputs. With this, the DWARF
class no longer depends on having direct access to the ELF file if being
used to generate ELF sections, and as such is output agnostic.
Now, if we have one or more outputs that contain DWARF information, we
only generate a single DWARF object that is shared across these outputs.
The only additional change required is in Dwarf::AddCode(), which now
handles being called multiple times for the same Code object.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try
Change-Id: I71de887a07a673164b3ccfa7fbbab2ccef80c576
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150302
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-06-11 08:57:59 +00:00
|
|
|
while (code_map_stream.PendingBytes() > 0) {
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
int32_t arg1;
|
|
|
|
int32_t arg2 = -1;
|
|
|
|
const uint8_t opcode =
|
|
|
|
CodeSourceMapOps::Read(&code_map_stream, &arg1, &arg2);
|
2017-03-20 20:02:41 +00:00
|
|
|
switch (opcode) {
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
case CodeSourceMapOps::kChangePosition: {
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
DwarfPosition& pos = token_positions[token_positions.length() - 1];
|
|
|
|
pos.ChangePosition(arg1, arg2);
|
2017-03-20 20:02:41 +00:00
|
|
|
break;
|
|
|
|
}
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
case CodeSourceMapOps::kAdvancePC: {
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
// Emit a row for the previous PC value if the source location
|
|
|
|
// changed since the last row was emitted.
|
2017-03-20 20:02:41 +00:00
|
|
|
const Function& function = *(function_stack.Last());
|
|
|
|
script = function.script();
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
const intptr_t file = LookupScript(script);
|
|
|
|
const intptr_t line = token_positions.Last().line();
|
|
|
|
const intptr_t column = token_positions.Last().column();
|
2021-11-10 17:52:03 +00:00
|
|
|
intptr_t pc_offset_adjustment = 0;
|
|
|
|
bool should_emit = true;
|
|
|
|
|
|
|
|
// If we are at the function entry and have already emitted a row
|
|
|
|
// then adjust current_pc_offset to avoid duplicated entries.
|
|
|
|
// See the comment below which explains why this code is here.
|
|
|
|
if (current_pc_offset == 0 && function_entry_position_was_emitted) {
|
|
|
|
pc_offset_adjustment = 1;
|
|
|
|
// Ignore synthetic positions. Function entry position gives
|
|
|
|
// more information anyway.
|
|
|
|
should_emit = !(line == 0 && column == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (should_emit) {
|
|
|
|
writer->EmitRow(file, line, column, asm_name,
|
|
|
|
current_pc_offset + pc_offset_adjustment);
|
|
|
|
}
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
|
|
|
|
current_pc_offset += arg1;
|
2021-11-10 17:52:03 +00:00
|
|
|
if (arg1 == 0) { // Special case of AdvancePC 0.
|
|
|
|
ASSERT(current_pc_offset == 0);
|
|
|
|
ASSERT(!function_entry_position_was_emitted);
|
|
|
|
function_entry_position_was_emitted = true;
|
|
|
|
}
|
2017-03-20 20:02:41 +00:00
|
|
|
break;
|
|
|
|
}
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
case CodeSourceMapOps::kPushFunction: {
|
2021-02-02 11:35:00 +00:00
|
|
|
auto child_func =
|
|
|
|
&Function::Handle(zone_, Function::RawCast(functions.At(arg1)));
|
|
|
|
function_stack.Add(child_func);
|
2020-06-22 09:29:45 +00:00
|
|
|
token_positions.Add(kNoDwarfPositionInfo);
|
2017-03-20 20:02:41 +00:00
|
|
|
break;
|
|
|
|
}
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
case CodeSourceMapOps::kPopFunction: {
|
2017-03-20 20:02:41 +00:00
|
|
|
// We never pop the root function.
|
|
|
|
ASSERT(function_stack.length() > 1);
|
|
|
|
ASSERT(token_positions.length() > 1);
|
|
|
|
function_stack.RemoveLast();
|
|
|
|
token_positions.RemoveLast();
|
|
|
|
break;
|
|
|
|
}
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
case CodeSourceMapOps::kNullCheck: {
|
2018-04-26 20:33:15 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-03-20 20:02:41 +00:00
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-02-02 11:35:00 +00:00
|
|
|
}
|
|
|
|
|
2021-04-26 22:44:28 +00:00
|
|
|
static constexpr char kResolvedFileRoot[] = "file:///";
|
2021-04-26 11:44:47 +00:00
|
|
|
static constexpr intptr_t kResolvedFileRootLen = sizeof(kResolvedFileRoot) - 1;
|
|
|
|
static constexpr char kResolvedSdkRoot[] = "org-dartlang-sdk:///sdk/";
|
|
|
|
static constexpr intptr_t kResolvedSdkRootLen = sizeof(kResolvedSdkRoot) - 1;
|
2022-04-27 13:07:21 +00:00
|
|
|
static constexpr char kResolvedGoogle3Root[] = "google3:///";
|
|
|
|
static constexpr intptr_t kResolvedGoogle3RootLen =
|
|
|
|
sizeof(kResolvedGoogle3Root) - 1;
|
2021-04-26 11:44:47 +00:00
|
|
|
|
|
|
|
static const char* ConvertResolvedURI(const char* str) {
|
|
|
|
const intptr_t len = strlen(str);
|
|
|
|
if (len > kResolvedFileRootLen &&
|
|
|
|
strncmp(str, kResolvedFileRoot, kResolvedFileRootLen) == 0) {
|
2021-07-02 19:06:45 +00:00
|
|
|
#if defined(DART_HOST_OS_WINDOWS)
|
2021-04-26 22:44:28 +00:00
|
|
|
return str + kResolvedFileRootLen; // Strip off the entire prefix.
|
|
|
|
#else
|
|
|
|
return str + kResolvedFileRootLen - 1; // Leave a '/' on the front.
|
|
|
|
#endif
|
2021-04-26 11:44:47 +00:00
|
|
|
}
|
|
|
|
if (len > kResolvedSdkRootLen &&
|
|
|
|
strncmp(str, kResolvedSdkRoot, kResolvedSdkRootLen) == 0) {
|
|
|
|
// Leave "sdk/" as a prefix in the returned path.
|
|
|
|
return str + (kResolvedSdkRootLen - 4);
|
|
|
|
}
|
2022-04-27 13:07:21 +00:00
|
|
|
if (len > kResolvedGoogle3RootLen &&
|
|
|
|
strncmp(str, kResolvedGoogle3Root, kResolvedGoogle3RootLen) == 0) {
|
|
|
|
return str + kResolvedGoogle3RootLen; // Strip off the entire prefix.
|
|
|
|
}
|
2021-04-26 11:44:47 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-02-02 11:35:00 +00:00
|
|
|
void Dwarf::WriteLineNumberProgram(DwarfWriteStream* stream) {
|
|
|
|
// 6.2.4 The Line Number Program Header
|
|
|
|
|
|
|
|
// 1. unit_length. This encoding implies 32-bit DWARF.
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
stream->WritePrefixedLength("line", [&]() {
|
|
|
|
stream->u2(2); // 2. DWARF version 2
|
|
|
|
|
|
|
|
// 3. header_length
|
|
|
|
stream->WritePrefixedLength("lineheader", [&]() {
|
|
|
|
stream->u1(1); // 4. minimum_instruction_length
|
|
|
|
stream->u1(1); // 5. default_is_stmt (true for dsymutil compatibility).
|
|
|
|
stream->u1(0); // 6. line_base
|
|
|
|
stream->u1(1); // 7. line_range
|
|
|
|
stream->u1(13); // 8. opcode_base (12 standard opcodes in Dwarf 2)
|
|
|
|
|
|
|
|
// 9. standard_opcode_lengths
|
|
|
|
stream->u1(0); // DW_LNS_copy, 0 operands
|
|
|
|
stream->u1(1); // DW_LNS_advance_pc, 1 operands
|
|
|
|
stream->u1(1); // DW_LNS_advance_list, 1 operands
|
|
|
|
stream->u1(1); // DW_LNS_set_file, 1 operands
|
|
|
|
stream->u1(1); // DW_LNS_set_column, 1 operands
|
|
|
|
stream->u1(0); // DW_LNS_negate_stmt, 0 operands
|
|
|
|
stream->u1(0); // DW_LNS_set_basic_block, 0 operands
|
|
|
|
stream->u1(0); // DW_LNS_const_add_pc, 0 operands
|
|
|
|
stream->u1(1); // DW_LNS_fixed_advance_pc, 1 operands
|
|
|
|
stream->u1(0); // DW_LNS_set_prolog_end, 0 operands
|
|
|
|
stream->u1(0); // DW_LNS_set_epligoue_begin, 0 operands
|
|
|
|
stream->u1(1); // DW_LNS_set_isa, 1 operands
|
|
|
|
|
|
|
|
// 10. include_directories (sequence of path names)
|
|
|
|
// We don't emit any because we use full paths below.
|
|
|
|
stream->u1(0);
|
|
|
|
|
|
|
|
// 11. file_names (sequence of file entries)
|
|
|
|
String& uri = String::Handle(zone_);
|
|
|
|
for (intptr_t i = 0; i < scripts_.length(); i++) {
|
|
|
|
const Script& script = *(scripts_[i]);
|
|
|
|
if (FLAG_resolve_dwarf_paths) {
|
|
|
|
uri = script.resolved_url();
|
|
|
|
// Strictly enforce this to catch unresolvable cases.
|
|
|
|
if (uri.IsNull()) {
|
|
|
|
FATAL("no resolved URI for Script %s available",
|
|
|
|
script.ToCString());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
uri = script.url();
|
|
|
|
}
|
|
|
|
ASSERT(!uri.IsNull());
|
|
|
|
auto uri_cstr = Deobfuscate(uri.ToCString());
|
|
|
|
if (FLAG_resolve_dwarf_paths) {
|
|
|
|
auto const converted_cstr = ConvertResolvedURI(uri_cstr);
|
2022-07-12 19:35:22 +00:00
|
|
|
// Strictly enforce this to catch inconvertible cases.
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
if (converted_cstr == nullptr) {
|
|
|
|
FATAL("cannot convert resolved URI %s", uri_cstr);
|
|
|
|
}
|
|
|
|
uri_cstr = converted_cstr;
|
|
|
|
}
|
|
|
|
RELEASE_ASSERT(strlen(uri_cstr) != 0);
|
|
|
|
|
|
|
|
stream->string(uri_cstr); // NOLINT
|
|
|
|
stream->uleb128(0); // Include directory index.
|
|
|
|
stream->uleb128(0); // File modification time.
|
|
|
|
stream->uleb128(0); // File length.
|
2021-04-26 11:44:47 +00:00
|
|
|
}
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
if (FLAG_write_code_comments_as_synthetic_source_to != nullptr) {
|
|
|
|
stream->string( // NOLINT
|
|
|
|
FLAG_write_code_comments_as_synthetic_source_to);
|
|
|
|
stream->uleb128(0); // Include directory index.
|
|
|
|
stream->uleb128(0); // File modification time.
|
|
|
|
stream->uleb128(0); // File length.
|
2021-04-26 11:44:47 +00:00
|
|
|
}
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
stream->u1(0); // End of file names.
|
|
|
|
});
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
// 6.2.5 The Line Number Program
|
|
|
|
LineNumberProgramWriter lnp_writer(stream);
|
|
|
|
if (FLAG_write_code_comments_as_synthetic_source_to != nullptr) {
|
|
|
|
WriteSyntheticLineNumberProgram(&lnp_writer);
|
|
|
|
} else {
|
|
|
|
WriteLineNumberProgramFromCodeSourceMaps(&lnp_writer);
|
|
|
|
}
|
2017-03-20 20:02:41 +00:00
|
|
|
|
[vm] Lazily calculate ELF relocations and symbols.
This removes the need for the image snapshot writer to know the
starting memory offset of any ELF sections. Instead, relocation
and symbol information are recorded in the ELF writer to be
resolved during finalization.
This is a step towards being able to reorder sections in the
ELF memory space for better packing into segments. Delaying
relocation and symbol resolution also moves towards merging
multiple text or data sections into a single section if desired.
In addition, this CL removes redundant rows from the DWARF line
number program matrix to reduce the size of debugging information.
Originally, rows were written for every PC offset visited by the
CodeSourceMap. However, no row is needed if the source information
(file, line, column) is the same as the previously written row.
There are also fixes to Utils::{IsInt,IsUint,IsAbsoluteUint} to
allow N >= the bit size of the value.
TEST=Refactoring, so existing tests.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-dwarf-linux-product-x64-try
Change-Id: I09f87cea214bca06b6fca60cd66138dae6da9e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203766
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2021-07-02 08:52:49 +00:00
|
|
|
// Advance pc to end of the compilation unit if not already there.
|
|
|
|
if (codes_.length() != 0) {
|
|
|
|
const intptr_t last_code_index = codes_.length() - 1;
|
|
|
|
const Code& last_code = *(codes_[last_code_index]);
|
|
|
|
const intptr_t last_pc_offset = last_code.Size();
|
|
|
|
const char* last_asm_name = code_to_name_.LookupValue(&last_code);
|
|
|
|
ASSERT(last_asm_name != nullptr);
|
|
|
|
lnp_writer.MarkEnd(last_asm_name, last_pc_offset);
|
|
|
|
} else {
|
|
|
|
lnp_writer.MarkEnd();
|
|
|
|
}
|
|
|
|
});
|
2017-03-20 20:02:41 +00:00
|
|
|
}
|
|
|
|
|
2019-12-18 14:14:41 +00:00
|
|
|
const char* Dwarf::Deobfuscate(const char* cstr) {
|
|
|
|
if (reverse_obfuscation_trie_ == nullptr) return cstr;
|
|
|
|
TextBuffer buffer(256);
|
|
|
|
// Used to avoid Zone-allocating strings if no deobfuscation was performed.
|
|
|
|
bool changed = false;
|
|
|
|
intptr_t i = 0;
|
|
|
|
while (cstr[i] != '\0') {
|
|
|
|
intptr_t offset;
|
|
|
|
auto const value = reverse_obfuscation_trie_->Lookup(cstr + i, &offset);
|
|
|
|
if (offset == 0) {
|
|
|
|
// The first character was an invalid key element (that isn't the null
|
|
|
|
// terminator due to the while condition), copy it and skip to the next.
|
|
|
|
buffer.AddChar(cstr[i++]);
|
|
|
|
} else if (value != nullptr) {
|
|
|
|
changed = true;
|
|
|
|
buffer.AddString(value);
|
|
|
|
} else {
|
|
|
|
buffer.AddRaw(reinterpret_cast<const uint8_t*>(cstr + i), offset);
|
|
|
|
}
|
|
|
|
i += offset;
|
|
|
|
}
|
|
|
|
if (!changed) return cstr;
|
2020-08-07 18:09:35 +00:00
|
|
|
return OS::SCreate(zone_, "%s", buffer.buffer());
|
2019-12-18 14:14:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Trie<const char>* Dwarf::CreateReverseObfuscationTrie(Zone* zone) {
|
2021-01-06 11:12:40 +00:00
|
|
|
auto const map_array = IsolateGroup::Current()->obfuscation_map();
|
2019-12-18 14:14:41 +00:00
|
|
|
if (map_array == nullptr) return nullptr;
|
|
|
|
|
|
|
|
Trie<const char>* trie = nullptr;
|
|
|
|
for (intptr_t i = 0; map_array[i] != nullptr; i += 2) {
|
|
|
|
auto const key = map_array[i];
|
|
|
|
auto const value = map_array[i + 1];
|
|
|
|
ASSERT(value != nullptr);
|
|
|
|
// Don't include identity mappings.
|
|
|
|
if (strcmp(key, value) == 0) continue;
|
|
|
|
// Otherwise, any value in the obfuscation map should be a valid key.
|
|
|
|
ASSERT(Trie<const char>::IsValidKey(value));
|
|
|
|
trie = Trie<const char>::AddString(zone, trie, value, key);
|
|
|
|
}
|
|
|
|
return trie;
|
|
|
|
}
|
|
|
|
|
2017-03-20 20:02:41 +00:00
|
|
|
#endif // DART_PRECOMPILER
|
|
|
|
|
|
|
|
} // namespace dart
|