Expose the kernel's build-ID through sysctl
After our migration (of certain architectures) to lld the kernel is built with a unique build-ID. Make it available via a sysctl and uname(1) to allow the user to identify their running kernel. Submitted by: Ali Mashtizadeh <ali_mashtizadeh.com> MFC after: 2 weeks Relnotes: Yes Event: Waterloo Hackathon 2019 Differential Revision: https://reviews.freebsd.org/D20326
This commit is contained in:
parent
01b5874679
commit
7236018555
@ -74,6 +74,11 @@ SECTIONS
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
|
||||
|
@ -27,6 +27,11 @@ SECTIONS
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.rel.text :
|
||||
{ *(.rel.text) *(.rel.gnu.linkonce.t*) }
|
||||
.rela.text :
|
||||
|
@ -27,6 +27,11 @@ SECTIONS
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.rel.text :
|
||||
{ *(.rel.text) *(.rel.gnu.linkonce.t*) }
|
||||
.rela.text :
|
||||
|
@ -62,6 +62,11 @@ SECTIONS
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
|
||||
|
@ -63,6 +63,11 @@ SECTIONS
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.rel.init : { *(.rel.init) }
|
||||
.rela.init : { *(.rela.init) }
|
||||
.rel.text :
|
||||
|
@ -192,6 +192,11 @@ SECTIONS
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.reginfo : { *(.reginfo) }
|
||||
.sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
|
||||
.sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
|
||||
|
@ -176,6 +176,11 @@ SECTIONS
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.reginfo : { *(.reginfo) }
|
||||
.sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
|
||||
.sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
|
||||
|
@ -23,6 +23,12 @@ SECTIONS {
|
||||
*(.rodata)
|
||||
. = ALIGN(32);
|
||||
}
|
||||
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
|
||||
.data : {
|
||||
_rwdata = .;
|
||||
|
@ -55,6 +55,11 @@ SECTIONS
|
||||
.fini : { *(.fini) } =0
|
||||
.rodata : { *(.rodata) *(.gnu.linkonce.r*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.sdata2 : { *(.sdata2) }
|
||||
.sbss2 : { *(.sbss2) }
|
||||
/* Adjust the address for the data segment to the next page up. */
|
||||
|
@ -46,6 +46,11 @@ SECTIONS
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.rela.text :
|
||||
{ *(.rela.text) *(.rela.gnu.linkonce.t*) }
|
||||
.rela.data :
|
||||
|
@ -55,6 +55,11 @@ SECTIONS
|
||||
.fini : { *(.fini) } =0
|
||||
.rodata : { *(.rodata) *(.gnu.linkonce.r*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.sdata2 : { *(.sdata2) }
|
||||
.sbss2 : { *(.sbss2) }
|
||||
/* Adjust the address for the data segment to the next page up. */
|
||||
|
@ -27,6 +27,11 @@ SECTIONS
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.rel.text :
|
||||
{ *(.rel.text) *(.rel.gnu.linkonce.t*) }
|
||||
.rela.text :
|
||||
|
@ -146,6 +146,11 @@ SECTIONS
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.note.gnu.build-id : {
|
||||
PROVIDE (__build_id_start = .);
|
||||
*(.note.gnu.build-id)
|
||||
PROVIDE (__build_id_end = .);
|
||||
}
|
||||
.sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
|
||||
.sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
|
||||
. = ALIGN(0x2000) + (. & (0x2000 - 1));
|
||||
|
@ -481,6 +481,54 @@ SYSCTL_PROC(_kern, KERN_OSRELDATE, osreldate,
|
||||
CTLTYPE_INT | CTLFLAG_CAPRD | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
NULL, 0, sysctl_osreldate, "I", "Kernel release date");
|
||||
|
||||
/*
|
||||
* The build-id is copied from the ELF section .note.gnu.build-id. The linker
|
||||
* script defines two variables to expose the beginning and end. LLVM
|
||||
* currently uses a SHA-1 hash, but other formats can be supported by checking
|
||||
* the length of the section.
|
||||
*/
|
||||
|
||||
extern char __build_id_start[];
|
||||
extern char __build_id_end[];
|
||||
|
||||
#define BUILD_ID_HEADER_LEN 0x10
|
||||
#define BUILD_ID_HASH_MAXLEN 0x14
|
||||
|
||||
static int
|
||||
sysctl_build_id(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
uintptr_t sectionlen = (uintptr_t)(__build_id_end - __build_id_start);
|
||||
int hashlen;
|
||||
char buf[2*BUILD_ID_HASH_MAXLEN+1];
|
||||
|
||||
/*
|
||||
* The ELF note section has a four byte length for the vendor name,
|
||||
* four byte length for the value, and a four byte vendor specific
|
||||
* type. The name for the build id is "GNU\0". We skip the first 16
|
||||
* bytes to read the build hash. We will return the remaining bytes up
|
||||
* to 20 (SHA-1) hash size. If the hash happens to be a custom number
|
||||
* of bytes we will pad the value with zeros, as the section should be
|
||||
* four byte aligned.
|
||||
*/
|
||||
if (sectionlen <= BUILD_ID_HEADER_LEN ||
|
||||
sectionlen > (BUILD_ID_HEADER_LEN + BUILD_ID_HASH_MAXLEN)) {
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
|
||||
hashlen = sectionlen - BUILD_ID_HEADER_LEN;
|
||||
for (int i = 0; i < hashlen; i++) {
|
||||
uint8_t c = __build_id_start[i+BUILD_ID_HEADER_LEN];
|
||||
snprintf(&buf[2*i], 3, "%02x", c);
|
||||
}
|
||||
|
||||
return (SYSCTL_OUT(req, buf, strlen(buf) + 1));
|
||||
}
|
||||
|
||||
SYSCTL_PROC(_kern, OID_AUTO, build_id,
|
||||
CTLTYPE_STRING | CTLFLAG_CAPRD | CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
NULL, 0, sysctl_build_id, "A", "Operating system build-id");
|
||||
|
||||
SYSCTL_NODE(_kern, OID_AUTO, features, CTLFLAG_RD, 0, "Kernel Features");
|
||||
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
|
Loading…
Reference in New Issue
Block a user