1--- 2title: Package Metadata for Core Files 3category: Interfaces 4layout: default 5SPDX-License-Identifier: LGPL-2.1-or-later 6--- 7 8# Package Metadata for Core Files 9 10*Intended audience: hackers working on userspace subsystems that create ELF binaries 11or parse ELF core files.* 12 13## Motivation 14 15ELF binaries get stamped with a unique, build-time generated hex string identifier called 16`build-id`, [which gets embedded as an ELF note called `.note.gnu.build-id`](https://fedoraproject.org/wiki/Releases/FeatureBuildId). 17In most cases, this allows to associate a stripped binary with its debugging information. 18It is used, for example, to dynamically fetch DWARF symbols from a debuginfo server, or 19to query the local package manager and find out the package metadata or, again, the DWARF 20symbols or program sources. 21 22However, this usage of the `build-id` requires either local metadata, usually set up by 23the package manager, or access to a remote server over the network. Both of those might 24be unavailable or forbidden. 25 26Thus it becomes desirable to add additional metadata to a binary at build time, so that 27`systemd-coredump` and other services analyzing core files are able to extract said 28metadata simply from the core file itself, without external dependencies. 29 30## Implementation 31 32This document will attempt to define a common metadata format specification, so that 33multiple implementers might use it when building packages, or core file analyzers, and 34so on. 35 36The metadata will be embedded in a single, new, 4-bytes-aligned, allocated, 0-padded, 37read-only ELF header section, in a name-value JSON object format. Implementers working on parsing 38core files should not assume a specific list of names, but parse anything that is included 39in the section, and should look for the note using the `note type`. Implementers working on 40build tools should strive to use the same names, for consistency. The most common will be 41listed here. When corresponding to the content of os-release, the values should match, again for consistency. 42 43If available, the metadata should also include the debuginfod server URL that can provide 44the original executable, debuginfo and sources, to further facilitate debugging. 45 46* Section header 47 48``` 49SECTION: `.note.package` 50note type: `0xcafe1a7e` 51Owner: `FDO` (FreeDesktop.org) 52Value: a single JSON object encoded as a zero-terminated UTF-8 string 53``` 54 55* JSON payload 56 57```json 58{ 59 "type":"rpm", # this provides a namespace for the package+package-version fields 60 "os":"fedora", 61 "osVersion":"33", 62 "name":"coreutils", 63 "version":"4711.0815.fc13", 64 "architecture":"arm32", 65 "osCpe": "cpe:/o:fedoraproject:fedora:33", # A CPE name for the operating system, `CPE_NAME` from os-release is a good default 66 "debugInfoUrl": "https://debuginfod.fedoraproject.org/" 67} 68``` 69 70The format is a single JSON object, encoded as a zero-terminated `UTF-8` string. 71Each name in the object shall be unique as per recommendations of 72[RFC8259](https://datatracker.ietf.org/doc/html/rfc8259#section-4). Strings shall 73not contain any control character, nor use `\uXXX` escaping. 74 75When it comes to JSON numbers, this specification assumes that JSON parsers 76processing this information are capable of reproducing the full signed 53bit 77integer range (i.e. -2⁵³+1…+2⁵³-1) as well as the full 64bit IEEE floating 78point number range losslessly (with the exception of NaN/-inf/+inf, since JSON 79cannot encode that), as per recommendations of 80[RFC8259](https://datatracker.ietf.org/doc/html/rfc8259#page-8). Fields in 81these JSON objects are thus permitted to encode numeric values from these 82ranges as JSON numbers, and should not use numeric values not covered by these 83types and ranges. 84 85A reference implementations of a [build-time tool is provided](https://github.com/systemd/package-notes) 86and can be used to generate a linker script, which can then be used at build time via 87```LDFLAGS="-Wl,-T,/path/to/generated/script"``` to include the note in the binary. 88 89Generator: 90```console 91$ ./generate-package-notes.py --rpm systemd-248~rc2-1.fc33.arm32 --cpe cpe:/o:fedoraproject:fedora:33 92SECTIONS 93{ 94 .note.package (READONLY) : ALIGN(4) { 95 LONG(0x0004) /* Length of Owner including NUL */ 96 LONG(0x007b) /* Length of Value including NUL */ 97 LONG(0xcafe1a7e) /* Note ID */ 98 BYTE(0x46) BYTE(0x44) BYTE(0x4f) BYTE(0x00) /* Owner: 'FDO\x00' */ 99 BYTE(0x7b) BYTE(0x22) BYTE(0x74) BYTE(0x79) /* Value: '{"type":"rpm","name":"systemd","version":"248~rc2-1.fc33","architecture":"arm32","osCpe":"cpe:/o:fedoraproject:fedora:33"}\x00\x00' */ 100 BYTE(0x70) BYTE(0x65) BYTE(0x22) BYTE(0x3a) 101 BYTE(0x22) BYTE(0x72) BYTE(0x70) BYTE(0x6d) 102 BYTE(0x22) BYTE(0x2c) BYTE(0x22) BYTE(0x6e) 103 BYTE(0x61) BYTE(0x6d) BYTE(0x65) BYTE(0x22) 104 BYTE(0x3a) BYTE(0x22) BYTE(0x73) BYTE(0x79) 105 BYTE(0x73) BYTE(0x74) BYTE(0x65) BYTE(0x6d) 106 BYTE(0x64) BYTE(0x22) BYTE(0x2c) BYTE(0x22) 107 BYTE(0x76) BYTE(0x65) BYTE(0x72) BYTE(0x73) 108 BYTE(0x69) BYTE(0x6f) BYTE(0x6e) BYTE(0x22) 109 BYTE(0x3a) BYTE(0x22) BYTE(0x32) BYTE(0x34) 110 BYTE(0x38) BYTE(0x7e) BYTE(0x72) BYTE(0x63) 111 BYTE(0x32) BYTE(0x2d) BYTE(0x31) BYTE(0x2e) 112 BYTE(0x66) BYTE(0x63) BYTE(0x33) BYTE(0x33) 113 BYTE(0x22) BYTE(0x2c) BYTE(0x22) BYTE(0x61) 114 BYTE(0x72) BYTE(0x63) BYTE(0x68) BYTE(0x69) 115 BYTE(0x74) BYTE(0x65) BYTE(0x63) BYTE(0x74) 116 BYTE(0x75) BYTE(0x72) BYTE(0x65) BYTE(0x22) 117 BYTE(0x3a) BYTE(0x22) BYTE(0x61) BYTE(0x72) 118 BYTE(0x6d) BYTE(0x33) BYTE(0x32) BYTE(0x22) 119 BYTE(0x2c) BYTE(0x22) BYTE(0x6f) BYTE(0x73) 120 BYTE(0x43) BYTE(0x70) BYTE(0x65) BYTE(0x22) 121 BYTE(0x3a) BYTE(0x22) BYTE(0x63) BYTE(0x70) 122 BYTE(0x65) BYTE(0x3a) BYTE(0x2f) BYTE(0x6f) 123 BYTE(0x3a) BYTE(0x66) BYTE(0x65) BYTE(0x64) 124 BYTE(0x6f) BYTE(0x72) BYTE(0x61) BYTE(0x70) 125 BYTE(0x72) BYTE(0x6f) BYTE(0x6a) BYTE(0x65) 126 BYTE(0x63) BYTE(0x74) BYTE(0x3a) BYTE(0x66) 127 BYTE(0x65) BYTE(0x64) BYTE(0x6f) BYTE(0x72) 128 BYTE(0x61) BYTE(0x3a) BYTE(0x33) BYTE(0x33) 129 BYTE(0x22) BYTE(0x7d) BYTE(0x00) BYTE(0x00) 130 } 131} 132INSERT AFTER .note.gnu.build-id; 133``` 134 135## Well-known keys 136 137The metadata format is intentionally left open, so that vendors can add their own information. 138A set of well-known keys is defined here, and hopefully shared among all vendors. 139 140| Key name | Key description | Example value | 141|--------------|--------------------------------------------------------------------------|---------------------------------------| 142| type | The packaging type | rpm | 143| os | The OS name, typically corresponding to ID in os-release | fedora | 144| osVersion | The OS version, typically corresponding to VERSION_ID in os-release | 33 | 145| name | The source package name | coreutils | 146| version | The source package version | 4711.0815.fc13 | 147| architecture | The binary package architecture | arm32 | 148| osCpe | A CPE name for the OS, typically corresponding to CPE_NAME in os-release | cpe:/o:fedoraproject:fedora:33 | 149| debugInfoUrl | The debuginfod server url, if available | https://debuginfod.fedoraproject.org/ | 150