[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