[almost patch] elf(5): Add vDSO note Linux 4 0
From: Krzysztof Żelechowski <hidden>
Date: 2021-10-10 15:49:04
Please insert this almost patch somewhere under .IR n_type, maybe before .B Default/unknown namespace (e_type != ET_CORE):
.TP
.\" commit 7648b1330c335601b7c09c25f77a03cda128fcab
.B n_name = Linux (soname = linux-vdso or such)
.RS
.TP 12
.PD 0
.B n_type = 0
Linux kernel version in the desc field (ElfN_Word), to be matched against the GNU ABI tag, see vdso(7).
.PD
.RE
Signed-off-my: Christopher Yeleighton [off-list ref]
. PLEASE NOTE: for nontrivial patches, you can save the maintainers a lot of time by attending to the following:
o Describe how you obtained the information in your patch. For example, was it:
. by reading (or writing) the relevant kernel or (g)libc source code? (please provide a pointer to the relevant code)
At arch/x86/entry/vdso/vdso-note.S
. by writing a test program? (send it with the patch, but please make sure it is as simple as possible, and provide instructions on how to use and/or a demo run)
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/auxv.h>
#include <elf.h>
struct sysnames { char write [06]; } const sysnames = { "write" };
int
main (int argc, char const *const argv [])
{ Elf64_Ehdr
const *const ph = (Elf64_Ehdr const *)
getauxval (AT_SYSINFO_EHDR)
;
if (printf ("Reading vDSO at %p\n", ph)
< 0)
{ perror (sysnames .write); return EXIT_FAILURE; }
if (ph)
{
uint16_t const shnum = ph ->e_shnum, shstrndx = ph ->e_shstrndx;
; Elf64_Off const shoff = ph ->e_shoff;
Elf64_Shdr const *const sh_B
= (Elf64_Shdr const *) (
ph ->e_ident + shoff)
; Elf64_Shdr const *const
sh_E = sh_B + shnum;
char const *const shstr =
ph ->e_ident +
sh_B [shstrndx] .sh_offset
;
if (SHN_UNDEF == shstrndx || SHN_XINDEX
== shstrndx) return EXIT_FAILURE;
assert (ELFMAG0 == ph ->e_ident [EI_MAG0
]);
assert (ELFMAG1 == ph ->e_ident [EI_MAG1]);
assert (ELFMAG2 == ph ->e_ident [EI_MAG2
]);
assert (ELFMAG3
== ph ->e_ident [EI_MAG3
]);
if (printf ("%#o section(s) at offset %#o\n", shnum, shoff
) < 0)
{ perror (sysnames .write); return EXIT_FAILURE; }
for (Elf64_Shdr const *
psh
= sh_B
; psh
< sh_E
; ++ psh
) {
if (SHT_NOTE == psh ->sh_type
)
{
char const *const n_B = ph ->e_ident + psh ->sh_offset;
uint32_t sz = psh ->sh_size;
if (printf ("section %s size %#o\n"
, shstr + psh ->sh_name, sz
) < 0)
{ perror (sysnames .write); return EXIT_FAILURE; }
for (
uint32_t
o1 = 0; o1 < sz; ) {
Elf64_Nhdr const *const note =
(Elf64_Nhdr const *) (
n_B + o1
)
; Elf64_Word const nsz = note ->n_namesz, dsz = note ->n_descsz
;
if (printf ("note %#o %s(%#o) %#o\n"
, nsz,
note + 01,
note ->n_type
,
dsz
) < 0)
{ perror (sysnames .write); return EXIT_FAILURE; }
o1 +=
sizeof *note + ((nsz + 03) & ~ 03);
if (sizeof (int)
== dsz)
if (printf ("version %#o\n"
, * (int const *) (n_B + o1)) < 0)
{ perror (sysnames .write); return EXIT_FAILURE; }
if (printf ("off %#o %#o %#o %#o\n"
, sizeof *note, nsz, dsz,
o1 +=
+ ((dsz
+ 03) & ~ 03)) < 0)
{ perror (sysnames
.write); return EXIT_FAILURE
; }
}
}
}
}
return EXIT_SUCCESS; }