Skip to content

Commit

Permalink
pw_build_info: Fix linux build ID compatibility
Browse files Browse the repository at this point in the history
Fixes the GN integration for build ID build sysetem integration.

Change-Id: I88446566b53357dae48da1eb1cbb7cdddc5aab8d
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/105520
Reviewed-by: Alexei Frolov <[email protected]>
Pigweed-Auto-Submit: Armando Montanez <[email protected]>
Commit-Queue: Auto-Submit <[email protected]>
  • Loading branch information
armandomontanez authored and CQ Bot Account committed Aug 15, 2022
1 parent 53df37a commit 93a7ca6
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 16 deletions.
18 changes: 18 additions & 0 deletions pw_build_info/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
load(
"//pw_build:pigweed.bzl",
"pw_cc_library",
"pw_cc_test",
)

package(default_visibility = ["//visibility:public"])
Expand All @@ -30,8 +31,25 @@ pw_cc_library(
"public/pw_build_info/build_id.h",
],
includes = ["public"],
linkopts = [
"-Lpw_build_info",
"-T$(location add_build_id_to_default_linker_script.ld)",
"-Wl,--build-id=sha1",
],
deps = [
":add_build_id_to_default_linker_script.ld",
":build_id_linker_snippet.ld",
"//pw_preprocessor",
"//pw_span",
],
)

pw_cc_test(
name = "build_id_test",
srcs = ["build_id_test.cc"],
deps = [
":build_id",
"//pw_span",
"//pw_unit_test",
],
)
19 changes: 16 additions & 3 deletions pw_build_info/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ config("linker_script") {
# default linker script instead of overriding it.
ldflags = [
"-T",
rebase_path("add_build_id_to_default_script.ld", root_build_dir),
rebase_path("add_build_id_to_default_linker_script.ld", root_build_dir),
]
lib_dirs = [ "." ]

inputs += [ "add_build_id_to_default_script.ld" ]
inputs += [ "add_build_id_to_default_linker_script.ld" ]
}
visibility = [ ":*" ]
}
Expand Down Expand Up @@ -68,8 +68,21 @@ if (current_os != "mac" && current_os != "win") {

pw_doc_group("docs") {
sources = [ "docs.rst" ]
inputs = [ "build_id_linker_snippet.ld" ]
inputs = [
"add_build_id_to_default_linker_script.ld",
"build_id_linker_snippet.ld",
]
}

pw_test_group("tests") {
tests = [ ":build_id_test" ]
}

pw_test("build_id_test") {
enable_if = current_os == "linux"
deps = [
":build_id",
"$dir_pw_span",
]
sources = [ "build_id_test.cc" ]
}
30 changes: 30 additions & 0 deletions pw_build_info/build_id_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2022 The Pigweed Authors
//
// 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
//
// https://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.

#include "pw_build_info/build_id.h"

#include "gtest/gtest.h"
#include "pw_span/span.h"

namespace pw::build_info {
namespace {

TEST(BuildId, BuildIdSize) {
span build_id = BuildId();
EXPECT_GT(build_id.size(), 0u);
EXPECT_LE(build_id.size(), kMaxBuildIdSizeBytes);
}

} // namespace
} // namespace pw::build_info
97 changes: 84 additions & 13 deletions pw_build_info/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pw_build_info
=============

.. warning::
This module is under construction and may not be ready for use.
This module is incomplete, but the build ID integration is ready for use.

pw_build_info provides tooling, build integration, and libraries for generating,
embedding, and parsing build-related information that is embedded into
Expand All @@ -16,7 +16,7 @@ simplifies the process of integrating rich version metadata to answer more
complex questions about compiled binaries.

-------------
GNU Build IDs
GNU build IDs
-------------
This module provides C++ and python libraries for reading GNU build IDs
generated by the link step of a C++ executable. These build IDs are essentially
Expand All @@ -28,20 +28,91 @@ Linux executables that depend on the ``build_id`` GN target will automatically
generate GNU build IDs. Windows and macOS binaries cannot use this target as
the implementation of GNU build IDs depends on the ELF file format.

Embedded targets must first explicitly place the GNU build ID section into a
non-info section of their linker script that is readable by the firmware. The
following linker snippet may be copied into a read-only section (just like the
.rodata or .text sections):
Getting started
===============
To generate GNU build IDs as part of your firmware image, you'll need to update
your embedded target's linker script.

Updating your linker script
---------------------------
If your project has a custom linker scipt, you'll need to update it to include
a section to contain the generated build ID. This section should be placed
alongside the ``.text`` and ``.rodata`` sections, and named
``.note.gnu.build-id``.

.. code-block:: none
/* Main executable code. */
.code : ALIGN(8)
{
. = ALIGN(8);
/* Application code. */
*(.text)
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
...
} >FLASH
/* GNU build ID section. */
.note.gnu.build-id :
{
. = ALIGN(4);
gnu_build_id_begin = .;
*(.note.gnu.build-id);
} >FLASH
/* Explicitly initialized global and static data. (.data) */
.static_init_ram : ALIGN(8)
{
*(.data)
*(.data*)
...
} >RAM AT> FLASH
Alternatively, you can copy the following linker snippet into a pre-existing
section. This makes reading the build ID slower, so whenever possibe prefer
creating a dedicated section for the build ID.

.. literalinclude:: build_id_linker_snippet.ld

This snippet may be placed directly into an existing section, as it is not
required to live in its own dedicated section. When opting to create a
dedicated section for the build ID to reside in, Pigweed recommends naming the
section ``.note.gnu.build-id`` as it makes it slightly easier for tools to
parse the build ID out of a binary. After the linker script has been properly
set up, the ``build_id`` GN target may be used to read the build ID at
runtime.
An example of directly inserting a build ID into an existing section is
provided below:

.. code-block:: none
/* Main executable code. */
.code : ALIGN(8)
{
. = ALIGN(8);
/* Application code. */
*(.text)
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
. = ALIGN(4);
gnu_build_id_begin = .;
*(.note.gnu.build-id);
...
} >FLASH
If your linker script is auto-generated, you may be able to use the
``INSERT AFTER`` linker script directive to append the build ID as seen in the
Linux host support for pw_build_info's build ID integration:

.. literalinclude:: add_build_id_to_default_linker_script.ld

Generating the build ID
-----------------------
When you depend on ``"$dir_pw_build_info:build_id``, a GNU build ID will be
generated at the final link step of any binaries that depend on that library
(whether directly or transitively). Those binaries will be able to read the
build ID by calling ``pw::build_info::BuildId()``. Note that the build ID
is not a string, but raw binary data, so to print it you'll need to convert
it to hex or base64.

Python API reference
====================
Expand Down

0 comments on commit 93a7ca6

Please sign in to comment.