public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Reserving specified size of RUNPATH entry in the dynamic section during linking
@ 2021-11-27 22:05 Jacob Kroon
  2021-11-27 22:27 ` Tom Kacvinsky
  2021-11-28 11:44 ` Florian Weimer
  0 siblings, 2 replies; 9+ messages in thread
From: Jacob Kroon @ 2021-11-27 22:05 UTC (permalink / raw)
  To: gcc-help

Hi,

As part of an effort to make binaries reproducible regardless of their
build path, I need to enforce the same size of the RUNPATH entry in the
dynamic section during linking, even though I don't fill it completely.
Is it possible to give some flag to gnu ld that allows me to set it to a
specific size ? Or is there a way to patch the elf file after linking,
so that the entry has a specified size ?

Regards
Jacob

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Reserving specified size of RUNPATH entry in the dynamic section during linking
  2021-11-27 22:05 Reserving specified size of RUNPATH entry in the dynamic section during linking Jacob Kroon
@ 2021-11-27 22:27 ` Tom Kacvinsky
  2021-11-28 14:24   ` Jacob Kroon
  2021-11-28 11:44 ` Florian Weimer
  1 sibling, 1 reply; 9+ messages in thread
From: Tom Kacvinsky @ 2021-11-27 22:27 UTC (permalink / raw)
  To: Jacob Kroon; +Cc: gcc-help

On Sat, Nov 27, 2021 at 5:05 PM Jacob Kroon via Gcc-help <
gcc-help@gcc.gnu.org> wrote:

> Hi,
>
> As part of an effort to make binaries reproducible regardless of their
> build path, I need to enforce the same size of the RUNPATH entry in the
> dynamic section during linking, even though I don't fill it completely.
> Is it possible to give some flag to gnu ld that allows me to set it to a
> specific size ? Or is there a way to patch the elf file after linking,
> so that the entry has a specified size ?
>

This tool doesn't quite do what you'd like (set a fixed size for the
RUNPATH entry in the dynamic table), but I have found it quite
useful:

https://github.com/NixOS/patchelf

Tom

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Reserving specified size of RUNPATH entry in the dynamic section during linking
  2021-11-27 22:05 Reserving specified size of RUNPATH entry in the dynamic section during linking Jacob Kroon
  2021-11-27 22:27 ` Tom Kacvinsky
@ 2021-11-28 11:44 ` Florian Weimer
  2021-11-28 14:31   ` Jacob Kroon
  1 sibling, 1 reply; 9+ messages in thread
From: Florian Weimer @ 2021-11-28 11:44 UTC (permalink / raw)
  To: Jacob Kroon via Gcc-help

* Jacob Kroon via Gcc-help:

> As part of an effort to make binaries reproducible regardless of their
> build path, I need to enforce the same size of the RUNPATH entry in the
> dynamic section during linking, even though I don't fill it completely.
> Is it possible to give some flag to gnu ld that allows me to set it to a
> specific size ? Or is there a way to patch the elf file after linking,
> so that the entry has a specified size ?

Do you want to allocate specific size so that you can patch in a
different value later?

The RUNPATH strings are in the string table, so it's necessary to
allocate space there, and be able to find it during patching.

Solaris offers this mechanism:

| DT_SUNW_STRPAD
| 
|     The total size, in bytes, of the unused reserved space at the end of
|     the dynamic string table. If DT_SUNW_STRPAD is not present in an
|     object, no reserved space is available.

Would that help in your case as well?

Thanks,
Florian


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Reserving specified size of RUNPATH entry in the dynamic section during linking
  2021-11-27 22:27 ` Tom Kacvinsky
@ 2021-11-28 14:24   ` Jacob Kroon
  0 siblings, 0 replies; 9+ messages in thread
From: Jacob Kroon @ 2021-11-28 14:24 UTC (permalink / raw)
  To: Tom Kacvinsky; +Cc: gcc-help

[-- Attachment #1: Type: text/plain, Size: 1064 bytes --]

On 11/27/21 23:27, Tom Kacvinsky wrote:
> 
> 
> On Sat, Nov 27, 2021 at 5:05 PM Jacob Kroon via Gcc-help
> <gcc-help@gcc.gnu.org <mailto:gcc-help@gcc.gnu.org>> wrote:
> 
>     Hi,
> 
>     As part of an effort to make binaries reproducible regardless of their
>     build path, I need to enforce the same size of the RUNPATH entry in the
>     dynamic section during linking, even though I don't fill it completely.
>     Is it possible to give some flag to gnu ld that allows me to set it to a
>     specific size ? Or is there a way to patch the elf file after linking,
>     so that the entry has a specified size ?
> 
> 
> This tool doesn't quite do what you'd like (set a fixed size for the
> RUNPATH entry in the dynamic table), but I have found it quite
> useful:
> 
> https://github.com/NixOS/patchelf <https://github.com/NixOS/patchelf>
> 

Thanks for the tip, but I can't get patchelf to produce identical
binaries, unless the rpath is already padded up to a common size in both
of the binaries.

I've attached a small Makefile I use to test with.

Jacob

[-- Attachment #2: reproducible.mk --]
[-- Type: text/x-makefile, Size: 596 bytes --]

workdir := $(shell mktemp -d)

all : compare

compare : $(workdir)/test-a $(workdir)/test-b
	diffoscope $(workdir)/test-a $(workdir)/test-b

rpath-a = "/foobar              "
rpath-b = "/a/much/longer/foobar"

$(workdir)/test-% : $(workdir)/%/test.c
	gcc -O2 $< -o $@ -Wl,--build-id=none -Wl,--rpath=$(rpath-$*)
	#chrpath -r "replacement" $@
	patchelf --set-rpath "my-new-rpath" $@

define sourcecode
#include <stdio.h>

int main() {
	printf("HelloWorld");
	return 0;
}
endef

define newline


endef

$(workdir)/%/test.c :
	mkdir -p $(dir $@)
	echo -e '$(subst $(newline),\n,$(sourcecode))' > $@

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Reserving specified size of RUNPATH entry in the dynamic section during linking
  2021-11-28 11:44 ` Florian Weimer
@ 2021-11-28 14:31   ` Jacob Kroon
  2021-11-28 15:09     ` Dan Kegel
  2021-11-28 15:17     ` Florian Weimer
  0 siblings, 2 replies; 9+ messages in thread
From: Jacob Kroon @ 2021-11-28 14:31 UTC (permalink / raw)
  To: Florian Weimer, Jacob Kroon via Gcc-help

On 11/28/21 12:44, Florian Weimer wrote:
> * Jacob Kroon via Gcc-help:
> 
>> As part of an effort to make binaries reproducible regardless of their
>> build path, I need to enforce the same size of the RUNPATH entry in the
>> dynamic section during linking, even though I don't fill it completely.
>> Is it possible to give some flag to gnu ld that allows me to set it to a
>> specific size ? Or is there a way to patch the elf file after linking,
>> so that the entry has a specified size ?
> 
> Do you want to allocate specific size so that you can patch in a
> different value later?
> 

Yes exactly, but see below.

> The RUNPATH strings are in the string table, so it's necessary to
> allocate space there, and be able to find it during patching.
> 
> Solaris offers this mechanism:
> 
> | DT_SUNW_STRPAD
> | 
> |     The total size, in bytes, of the unused reserved space at the end of
> |     the dynamic string table. If DT_SUNW_STRPAD is not present in an
> |     object, no reserved space is available.
> 
> Would that help in your case as well?
> 

The problem is that for two different build I pass two different
-Wl,--rpath=<path>, and they are of different length. So I'd like to
reserve a maximum size, at link-time, which becomes the same in both
builds, so that when I later remove the rpath's, the binaries become
identical.

Jacob

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Reserving specified size of RUNPATH entry in the dynamic section during linking
  2021-11-28 14:31   ` Jacob Kroon
@ 2021-11-28 15:09     ` Dan Kegel
  2021-11-28 15:17     ` Florian Weimer
  1 sibling, 0 replies; 9+ messages in thread
From: Dan Kegel @ 2021-11-28 15:09 UTC (permalink / raw)
  To: Jacob Kroon; +Cc: Florian Weimer, Jacob Kroon via Gcc-help

I used to do this by padding initially with extra dots and slashes.

(On Mac, the linker had a flag -headerpad_max_install_names that did
something similar.)


On Sun, Nov 28, 2021, 06:32 Jacob Kroon via Gcc-help <gcc-help@gcc.gnu.org>
wrote:

> On 11/28/21 12:44, Florian Weimer wrote:
> > * Jacob Kroon via Gcc-help:
> >
> >> As part of an effort to make binaries reproducible regardless of their
> >> build path, I need to enforce the same size of the RUNPATH entry in the
> >> dynamic section during linking, even though I don't fill it completely.
> >> Is it possible to give some flag to gnu ld that allows me to set it to a
> >> specific size ? Or is there a way to patch the elf file after linking,
> >> so that the entry has a specified size ?
> >
> > Do you want to allocate specific size so that you can patch in a
> > different value later?
> >
>
> Yes exactly, but see below.
>
> > The RUNPATH strings are in the string table, so it's necessary to
> > allocate space there, and be able to find it during patching.
> >
> > Solaris offers this mechanism:
> >
> > | DT_SUNW_STRPAD
> > |
> > |     The total size, in bytes, of the unused reserved space at the end
> of
> > |     the dynamic string table. If DT_SUNW_STRPAD is not present in an
> > |     object, no reserved space is available.
> >
> > Would that help in your case as well?
> >
>
> The problem is that for two different build I pass two different
> -Wl,--rpath=<path>, and they are of different length. So I'd like to
> reserve a maximum size, at link-time, which becomes the same in both
> builds, so that when I later remove the rpath's, the binaries become
> identical.
>
> Jacob
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Reserving specified size of RUNPATH entry in the dynamic section during linking
  2021-11-28 14:31   ` Jacob Kroon
  2021-11-28 15:09     ` Dan Kegel
@ 2021-11-28 15:17     ` Florian Weimer
  2021-11-28 15:54       ` Jacob Kroon
  1 sibling, 1 reply; 9+ messages in thread
From: Florian Weimer @ 2021-11-28 15:17 UTC (permalink / raw)
  To: Jacob Kroon; +Cc: Jacob Kroon via Gcc-help

* Jacob Kroon:

>> The RUNPATH strings are in the string table, so it's necessary to
>> allocate space there, and be able to find it during patching.
>> 
>> Solaris offers this mechanism:
>> 
>> | DT_SUNW_STRPAD
>> | 
>> |     The total size, in bytes, of the unused reserved space at the end of
>> |     the dynamic string table. If DT_SUNW_STRPAD is not present in an
>> |     object, no reserved space is available.
>> 
>> Would that help in your case as well?
>> 
>
> The problem is that for two different build I pass two different
> -Wl,--rpath=<path>, and they are of different length. So I'd like to
> reserve a maximum size, at link-time, which becomes the same in both
> builds, so that when I later remove the rpath's, the binaries become
> identical.

In the file, there is no array of some number of characters that
contains the null-terminated RUNPATH string, an array to which just more
null bytes could be added at the end.  DT_RUNPATH contains an offset
into the string table.  The null-terminated string could be used for
something else.  For example, if the RUNPATH is
"/usr/lib64/sys/library.so.3", and the link edit needs the string
"library.so.3" for something else, it can point into the RUNPATH string
to get that.  So it's not valid in general to patch the string in-place,
let alone change its length.

That's why I think something like the Solaris approach is needed: The
new RUNPATH value would come from the reservation, the offset in
DT_RUNPATH points to it, and the original string table is not modified
at all.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Reserving specified size of RUNPATH entry in the dynamic section during linking
  2021-11-28 15:17     ` Florian Weimer
@ 2021-11-28 15:54       ` Jacob Kroon
  2021-11-28 17:06         ` Florian Weimer
  0 siblings, 1 reply; 9+ messages in thread
From: Jacob Kroon @ 2021-11-28 15:54 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Jacob Kroon via Gcc-help

On 11/28/21 16:17, Florian Weimer wrote:
> * Jacob Kroon:
> 
>>> The RUNPATH strings are in the string table, so it's necessary to
>>> allocate space there, and be able to find it during patching.
>>>
>>> Solaris offers this mechanism:
>>>
>>> | DT_SUNW_STRPAD
>>> | 
>>> |     The total size, in bytes, of the unused reserved space at the end of
>>> |     the dynamic string table. If DT_SUNW_STRPAD is not present in an
>>> |     object, no reserved space is available.
>>>
>>> Would that help in your case as well?
>>>
>>
>> The problem is that for two different build I pass two different
>> -Wl,--rpath=<path>, and they are of different length. So I'd like to
>> reserve a maximum size, at link-time, which becomes the same in both
>> builds, so that when I later remove the rpath's, the binaries become
>> identical.
> 
> In the file, there is no array of some number of characters that
> contains the null-terminated RUNPATH string, an array to which just more
> null bytes could be added at the end.  DT_RUNPATH contains an offset
> into the string table.  The null-terminated string could be used for
> something else.  For example, if the RUNPATH is
> "/usr/lib64/sys/library.so.3", and the link edit needs the string
> "library.so.3" for something else, it can point into the RUNPATH string
> to get that.  So it's not valid in general to patch the string in-place,
> let alone change its length.
> 
> That's why I think something like the Solaris approach is needed: The
> new RUNPATH value would come from the reservation, the offset in
> DT_RUNPATH points to it, and the original string table is not modified
> at all.
> 

Aha, thank you for explaining.

I suppose gnu ld doesn't try to optimize for usage of substrings in
RUNPATH, thus making if fairly easy to change it post linking.

But can I then specify during link time that RUNTIME should go in a
"reserved" area, whose size I can also control ? I hope I understood you
correctly.

Jacob

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Reserving specified size of RUNPATH entry in the dynamic section during linking
  2021-11-28 15:54       ` Jacob Kroon
@ 2021-11-28 17:06         ` Florian Weimer
  0 siblings, 0 replies; 9+ messages in thread
From: Florian Weimer @ 2021-11-28 17:06 UTC (permalink / raw)
  To: Jacob Kroon; +Cc: Jacob Kroon via Gcc-help

* Jacob Kroon:

> I suppose gnu ld doesn't try to optimize for usage of substrings in
> RUNPATH, thus making if fairly easy to change it post linking.

I think it does, it's just that RUNPATH with an overlapping tail is just
rare in practice because of its contents.

Try this:

$ gcc -nostartfiles -shared -Wl,-rpath,one-long-string,-soname,one-long-string  
$ readelf -dW a.out

Dynamic section at offset 0x1f20 contains 9 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [one-long-string]
 0x000000000000001d (RUNPATH)            Library runpath: [one-long-string]
 0x000000006ffffef5 (GNU_HASH)           0x180
 0x0000000000000005 (STRTAB)             0x1b8
 0x0000000000000006 (SYMTAB)             0x1a0
 0x000000000000000a (STRSZ)              27 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000000 (NULL)               0x0

But if you look at the file with a hex editor, you'll notice that the
string is only there once:

000001b0: 0000 0000 0000 0000 006c 6962 632e 736f  .........libc.so
000001c0: 2e36 006f 6e65 2d6c 6f6e 672d 7374 7269  .6.one-long-stri
000001d0: 6e67 0000 0000 0000 0000 0000 0000 0000  ng..............

> But can I then specify during link time that RUNTIME should go in a
> "reserved" area, whose size I can also control ? I hope I understood you
> correctly.

I think GNU ld doesn't have this feature today.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-11-28 17:06 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-27 22:05 Reserving specified size of RUNPATH entry in the dynamic section during linking Jacob Kroon
2021-11-27 22:27 ` Tom Kacvinsky
2021-11-28 14:24   ` Jacob Kroon
2021-11-28 11:44 ` Florian Weimer
2021-11-28 14:31   ` Jacob Kroon
2021-11-28 15:09     ` Dan Kegel
2021-11-28 15:17     ` Florian Weimer
2021-11-28 15:54       ` Jacob Kroon
2021-11-28 17:06         ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).