[RFC PATCH libinput] tools: run list-quirks from the git data when running from the builddir
Peter Hutterer
peter.hutterer at who-t.net
Wed Jul 4 01:08:16 UTC 2018
On Mon, Jun 25, 2018 at 11:06:36AM +0300, Pekka Paalanen wrote:
> On Fri, 22 Jun 2018 12:48:53 +1000
> Peter Hutterer <peter.hutterer at who-t.net> wrote:
>
> > I'd like some comment on this from someone who knows this stuff better than
> > I do. The main goal is to have the same binary default to different search
> > paths, depending whether it's the installed version or the one run from the
> > build directory. This is the only solution I could come up with and it
> > works, but I'm not sure how much of that is coincidence vs "yes, this is how
> > ELF stripping works".
> >
> > Any comments welcome. Or other solutions to this. Thanks
> >
> > ---
> >
> > Push the git data directory into a special variable in a custom ELF section.
> > Then after install, strip that ELF section out. The result is that when we're
> > running from the builddir, the data path is set and we read from there. When
> > running from the system install, the data path is zeroes only and we're
> > running with the defaults.
>
> Hi Peter,
>
> this is certainly interesting. I don't know about the correctness, but
> I have been wondering about how to disable the test suite scaffolding
> (e.g. WESTON_MODULE_MAP env var) in an installed weston instance.
>
> I've also been thinking about how to expose private functions from a
> library for a test suite but prevent those from being accessed in an
> installed version. Maybe that could be an array of function pointers
> declared in a special section like you did, so it would disappear on
> install.
Ok, with Dodji Seketeli's help I figured out the trick and the various
pieces needed to get this working correctly.
Part 1, the const char in the custom section:
static const char valuestring[]
__attribute__ ((section ("custom_section_name")))
= "SOME VALUE";
Part 2, accessing that value:
volatile const char *foo = valuestring;
if (*foo == '\0') printf("section was removed\n");
Note that foo must be declared volatile, otherwise the compiler will
optimise the code and replace *foo with the first character of the string
('S' in this case) and this all fails. This happens even at gcc -O0 but the
above is correct for -O0 and -O2 (after staring at the disassembly).
If you pass the lot into a function like e.g. strlen() this is not an issue
because the compiler won't optimise that out. But I didn't check that in
detail.
Part 3, removal of the section:
dd if=/dev/zero of=zeroes.bin bs=8 count=1
objcopy --update-section custom_section_name=zeroes.bin $file $file.tmp
mv $file.tmp $file
This *replaces* the content of the section with 8 zero bytes. Which should
be enough to avoid accidental access of the subsequent region.
I don't have any immediate use for it because for list-quirks I went with
the "subtract the prefix" approach. But it'll come in handy one day to
remove traces of the test scaffolding.
Cheers,
Peter
> > Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> > ---
> > meson.build | 5 +++++
> > tools/libinput-list-quirks.c | 12 ++++++++++++
> > tools/strip-builddir-section.sh | 18 ++++++++++++++++++
> > 3 files changed, 35 insertions(+)
> > create mode 100644 tools/strip-builddir-section.sh
> >
> > diff --git a/meson.build b/meson.build
> > index b650bbde..0b9dc751 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -479,6 +479,11 @@ libinput_list_quirks = executable('libinput-list-quirks',
> > install_dir : libinput_tool_path,
> > install : true
> > )
> > +meson.add_install_script('tools/strip-builddir-section.sh',
> > + libinput_tool_path,
> > + 'libinput-list-quirks')
> > +
> > +
> > test('validate-quirks',
> > libinput_list_quirks,
> > args: ['--validate-only', '--data-dir=@0@'.format(join_paths(meson.source_root(), 'data'))]
> > diff --git a/tools/libinput-list-quirks.c b/tools/libinput-list-quirks.c
> > index 533c4f3a..1207ade3 100644
> > --- a/tools/libinput-list-quirks.c
> > +++ b/tools/libinput-list-quirks.c
> > @@ -207,6 +207,13 @@ usage(void)
> > " Validate the database\n");
> > }
> >
> > +/* When running from builddir, we use the git data tree by default.
> > + This section is stripped on install.
> > + */
> > +static const char builddir_data_path[]
> > + __attribute__ ((section ("builddir_section")))
> > + = LIBINPUT_DATA_SRCDIR;
> > +
> > int
> > main(int argc, char **argv)
> > {
> > @@ -219,6 +226,11 @@ main(int argc, char **argv)
> > struct quirks_context *quirks;
> > bool validate = false;
> >
> > + /* After the section is stripped, builddir_data_path is zeroes */
> > + data_path = builddir_data_path;
> > + if (data_path && strlen(data_path) == 0)
> > + data_path = NULL;
> > +
> > while (1) {
> > int c;
> > int option_index = 0;
> > diff --git a/tools/strip-builddir-section.sh b/tools/strip-builddir-section.sh
> > new file mode 100644
> > index 00000000..dbae7964
> > --- /dev/null
> > +++ b/tools/strip-builddir-section.sh
> > @@ -0,0 +1,18 @@
> > +#!/bin/bash
> > +#
> > +# Usage: strip-builddir-section /path/to/libexec/libinput file1 file2
> > +
> > +directory=$1
> > +shift
> > +
> > +files="$@"
> > +
> > +pushd $directory > /dev/null
> > +for file in $files; do
> > + if test -e $file; then
> > + echo "Stripping file $directory/$file"
> > + objcopy --remove-section builddir_section $file $file.tmp
> > + mv $file.tmp $file
> > + fi
> > +done
> > +popd > /dev/null
>
More information about the wayland-devel
mailing list