blob: 38d9b8f2f7123280b5891b1ed8273e1a0500ed83 [file] [log] [blame]
// Copyright 2020 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BLOATY_LINK_MAP_H_
#define BLOATY_LINK_MAP_H_
#include <cstddef>
#include <cstdint>
#include <optional>
#include <string>
#include <tuple>
#include <vector>
namespace bloaty_link_map {
struct Symbol {
std::string name;
std::string compile_unit;
std::string section;
uint64_t addr;
uint64_t size;
};
// Parses a linker map file in lld v1 format.
//
// This function is adapted from
// https://chromium.googlesource.com/chromium/src.git/+/master/tools/binary_size/libsupersize/linker_map_parser.py
//
// Args:
// content: Contents of the link map, the first line of which is the header.
//
// Returns:
// A vector of symbols.
//
// Example format:
// VMA LMA Size Align Out In Symbol
// 194 194 13 1 .interp
// 194 194 13 1 <internal>:(.interp)
// 1a8 1a8 22d8 4 .ARM.exidx
// 1b0 1b0 8 4 obj/sandbox/syscall.o:(.ARM.exidx)
// 400 400 123400 64 .text
// 600 600 14 4 ...:(.text.OUTLINED_FUNCTION_0)
// 600 600 0 1 $x.3
// 600 600 14 1 OUTLINED_FUNCTION_0
// 123800 123800 20000 256 .rodata
// 123800 123800 4 4 ...:o:(.rodata._ZN3fooE.llvm.1234)
// 123800 123800 4 1 foo (.llvm.1234)
// 123804 123804 4 4 ...:o:(.rodata.bar.llvm.1234)
// 123804 123804 4 1 bar.llvm.1234
//
// Notes:
// - `VMA` and `LMA` are mostly identical.
// - In a position-independent executable, the base address is zero.
// Hence the minimum value of the addresses is quite small.
// - Stripping of the binary will not relocate symbols, hence the addresses
// will be the same between a stripped and unstripped binary.
std::vector<Symbol> ParseLldLinkMap(const std::string& content);
struct Section {
std::string name;
uint64_t addr;
uint64_t size;
};
std::vector<Section> ParseLldLinkMapSections(const std::string& content);
// Transform the compile unit path parsed from link maps to a format
// easier to organize, specialized to a Fuchsia build.
// If the compile unit could not be understood by the transformer, it will
// return `std::nullopt`. Since bloaty can still recover some compile unit
// information from DWARF, we do not have to cover 100% here. For Rust however,
// this allows setting a reasonable fallback compile unit at the crate level.
// Therefore, the output of this transform should be inserted after the
// usual DWARF-based compile unit data source.
//
// Examples:
//
// `./exe.unstripped/component_manager.alloc-54127f36ba192482.alloc.4k1iwrm2-cgu.0.rcgu.o.rcgu.o`
// becomes `[crate: alloc]`.
//
// `./exe.unstripped/component_manager.libcomponent_manager_lib.component_manager_lib.3a1fbbbh-cgu.2.rcgu.o.rcgu.o`
// becomes `[crate: component_manager_lib]`.
//
// `./exe.unstripped/component_manager.libcm_fidl_translator.cm_fidl_translator.3a1fbbbh-cgu.0.rcgu.o.rcgu.o`
// becomes `[crate: cm_fidl_translator]`.
//
// `./exe.unstripped/component_manager.component_manager.7rcbfp3g-cgu.0.rcgu.o`
// becomes `[crate: component_manager]`.
//
// `./exe.unstripped/component_manager.libfidl_fuchsia_io.fidl_fuchsia_io.3a1fbbbh-cgu.0.rcgu.o.rcgu.o`
// becomes `[crate: fidl_fuchsia_io]`.
//
// `/usr/local/google/home/yifeit/vg/out/default/obj/third_party/rust_crates/libregex_syntax-579ced0738b0164d.rlib(libregex_syntax-579ced0738b0164d-579ced0738b0164d.regex_syntax.c02sfxfu-cgu.13.rcgu.o)`
// becomes `[crate: regex_syntax]`.
//
// `/usr/local/google/home/yifeit/vg/out/default.zircon/user-arm64-clang.shlib/obj/system/ulib/c/crt1.Scrt1.cc.o`
// becomes `../../zircon/system/ulib/c/Scrt1.cc`.
//
// `obj/out/default/fidling/gen/sdk/fidl/fuchsia.hardware.block/fuchsia.hardware.block_tables.fuchsia.hardware.block.fidl.tables.c.o`
// becomes `fidling/gen/sdk/fidl/fuchsia.hardware.block/fuchsia.hardware.block.fidl.tables.c`.
//
// `obj/zircon/public/lib/fidl_base/libfidl_base.a(libfidl_base.decoding.cc.o)`
// becomes `../../zircon/system/ulib/fidl/decoding.cc`
//
// `obj/zircon/system/uapp/blobfs/blobfs.main.cc.o`
// becomes `../../zircon/system/uapp/blobfs/main.cc`
//
// `obj/zircon/system/ulib/trace-provider/libtrace-provider-with-fdio.a(libtrace-provider-with-fdio.fdio_connect.cc.o)`
// is not suppported.
//
// `obj/zircon/public/lib/lz4/liblz4.a(liblz4.lz4hc.c.o)` is not supported.
std::optional<std::tuple<std::string, std::optional<std::string>>> TransformCompileUnitForFuchsia(
const std::string& compile_unit);
} // namespace bloaty_link_map
#endif // BLOATY_LINK_MAP_H_