[PATCH] ld: ensure build-id is placed near ELF headers
H.J. Lu
hjl.tools@gmail.com
Fri Sep 20 03:45:48 GMT 2024
On Fri, Sep 20, 2024 at 10:52 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Fri, Sep 20, 2024 at 4:54 AM Sam James <sam@gentoo.org> wrote:
> >
> > Nick Clifton <nickc@redhat.com> writes:
> >
> > > Hi Andrew,
> > >
> > > [Sorry for being so late in responding to your email]
> > >
> > >> When an executable is built with the --rosegment option GDB is no
> > >> longer able to find the build-id of the executable from a core file.
> > >
> > > For problems like this it really helps if you create a bug report
> > > using the Sourceware bugzilla system. This allows us to track the
> > > problem and any discussion surrounding it. It also means that we
> > > can refer to the bug ID in comments in the code.
> > >
> > > In order to save you time however, I have gone ahead and created
> > > a bug report for you:
> > >
> > > https://sourceware.org/bugzilla/show_bug.cgi?id=32100
> > >
> > >> This patch aims to fix this by placing the build-id first. The
> > >> build-id will then be included within the same LOAD-able segment as
> > >> the executable content, just as the ELF headers are. With this patch
> > >> in place GDB is once again able to find the build-id from a core
> > >> file.
> > >
> > > Unfortunately that patch breaks the intention of the --rosegment
> > > option by restoring two loadable, read-only segments to the executable.
> > >
> > > Here is an example:
> > >
> > > $ cat hello.c
> > >
> > > extern int printf (const char *, ...);
> > > int i = 42;
> > > const int * j = & i;
> > > int main (void) { return printf ("hello world %d\n", * j); }
> > >
> > > $ gcc -fPIC -Wl,-z,noseparate-code hello.c
> > > $ readelf -lW a.out | grep LOAD
> > >
> > > LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0006d4 0x0006d4 R E 0x1000
> > > LOAD 0x000df8 0x0000000000401df8 0x0000000000401df8 0x000228 0x000230 RW 0x1000
> > >
> > > $ gcc -fPIX -Wl,-z,separate-code hello.c
> > > $ readelf -lW a.out | grep LOAD
> > >
> > > LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x000510 0x000510 R 0x1000
> > > LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x000155 0x000155 R E 0x1000
> > > LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x0000dc 0x0000dc R 0x1000
> > > LOAD 0x002df8 0x0000000000403df8 0x0000000000403df8 0x000228 0x000230 RW 0x1000
> > >
> > > $ gcc -fPIX -Wl,-z,separate-code -Wl,--rosegment hello.c
> > > $ readelf -lW a.out | grep LOAD
> > >
> > > LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x00115d 0x00115d R E 0x1000
> > > LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x0002d4 0x0002d4 R 0x1000
> > > LOAD 0x002df8 0x0000000000403df8 0x0000000000403df8 0x000220 0x000228 RW 0x1000
> > >
> > > $ gcc -fPIX -Wl,-z,separate-code -Wl,--rosegment hello.c -fuse-ld=patched-linker
> > > $ readelf -lW a.out | grep LOAD
> > >
> > > LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x00039c 0x00039c R 0x1000
> > > LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x00015d 0x00015d R E 0x1000
> > > LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x00024c 0x00024c R 0x1000
> > > LOAD 0x002df8 0x0000000000403df8 0x0000000000403df8 0x000220 0x000228 RW 0x1000
> > >
> > > (I invented the "-fuse-ld=patched-linker" option to keep the presentation simple. In
> > > reality I used a full path to a linker built with your proposed patch applied).
> > >
> > > The section to segment mapping is changed by using --rosegment, but with your patch
> > > applied we still get an early read-only segment containing the note sections.
> > >
> > > I think that what is needed is a patch to move all of the read-only segments to
> > > before the read-execute segment. But this weill need testing.
> >
> > I'm reading over the rest of the thread, so apologies if this got
> > addressed later, but did we add a testcase like this?
>
> Hi Andrew,
>
> Why does GDB need the build-id to be placed close to the ELF header?
> Can't GDB read the program header and search for the build-id in PT_NOTE
> segment? If GDB needs help, we can add a PT_BUILD_ID segment.
>
Why doesn't elfobj_grok_gnu_build_id work for GDB?
--
H.J.
More information about the Binutils
mailing list