* [PATCH] mips: pldd: support DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL @ 2022-01-28 18:56 Xi Ruoyao 2022-01-28 20:45 ` H.J. Lu 0 siblings, 1 reply; 12+ messages in thread From: Xi Ruoyao @ 2022-01-28 18:56 UTC (permalink / raw) To: libc-alpha; +Cc: Jiaxun Yang, syq, Joseph Myers, Carlos O'Donell MIPS uses DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL for accessing r_debug, instead of DT_DEBUG. --- elf/pldd-xx.c | 67 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c index 1cdfb49c53..ec397f00e5 100644 --- a/elf/pldd-xx.c +++ b/elf/pldd-xx.c @@ -22,6 +22,12 @@ #define EW_(e, w, t) EW__(e, w, _##t) #define EW__(e, w, t) e##w##t +#if CLASS == 32 +typedef Elf32_Word E(val_type); +#else +typedef Elf64_Xword E(val_type); +#endif + struct E(link_map) { EW(Addr) l_addr; @@ -70,6 +76,35 @@ _Static_assert (offsetof (struct r_debug, r_map) == offsetof (struct E(r_debug), r_map), "r_map"); #endif +static EW(Addr) +E(r_debug_offset) (EW(Dyn) *d, int memfd, EW(Addr) d_addr) +{ +#ifdef __mips__ + EW(Addr) ptr; + + switch (d->d_tag) + { + case DT_MIPS_RLD_MAP_REL: + ptr = d_addr + d->d_un.d_val; + break; + case DT_MIPS_RLD_MAP: + ptr = d->d_un.d_ptr; + break; + default: + return 0; + } + + if (pread (memfd, &ptr, sizeof (ptr), ptr) != sizeof (ptr)) + return 0; + + return ptr; +#else + if (d->d_tag == DT_DEBUG) + return (off_t) d->d_un.d_ptr; + + return 0; +#endif +} static int @@ -126,21 +161,25 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, != p[i].p_filesz) error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); - /* Search for the DT_DEBUG entry. */ + /* Search for the r_debug struct. */ for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j) - if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) - { - struct E(r_debug) r; - if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) - != sizeof (r)) - error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); - - if (r.r_map != 0) - { - list = r.r_map; - break; - } - } + { + EW(Addr) d_addr = offset + p[i].p_vaddr + sizeof (EW(Dyn)) * j; + EW(Addr) off = E(r_debug_offset)(&dyn[j], memfd, d_addr); + if (off != 0) + { + struct E(r_debug) r; + if (pread (memfd, &r, sizeof (r), off) + != sizeof (r)) + error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); + + if (r.r_map != 0) + { + list = r.r_map; + break; + } + } + } free (dyn); break; -- 2.35.0 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] mips: pldd: support DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL 2022-01-28 18:56 [PATCH] mips: pldd: support DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL Xi Ruoyao @ 2022-01-28 20:45 ` H.J. Lu 2022-01-28 20:48 ` Adhemerval Zanella 2022-01-28 21:17 ` [PATCH v2] " Xi Ruoyao 0 siblings, 2 replies; 12+ messages in thread From: H.J. Lu @ 2022-01-28 20:45 UTC (permalink / raw) To: Xi Ruoyao; +Cc: GNU C Library, syq, Joseph Myers, Jiaxun Yang On Fri, Jan 28, 2022 at 10:57 AM Xi Ruoyao via Libc-alpha <libc-alpha@sourceware.org> wrote: > > MIPS uses DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL for accessing r_debug, > instead of DT_DEBUG. > --- > elf/pldd-xx.c | 67 ++++++++++++++++++++++++++++++++++++++++----------- > 1 file changed, 53 insertions(+), 14 deletions(-) > > diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c > index 1cdfb49c53..ec397f00e5 100644 > --- a/elf/pldd-xx.c > +++ b/elf/pldd-xx.c > @@ -22,6 +22,12 @@ > #define EW_(e, w, t) EW__(e, w, _##t) > #define EW__(e, w, t) e##w##t > > +#if CLASS == 32 > +typedef Elf32_Word E(val_type); > +#else > +typedef Elf64_Xword E(val_type); > +#endif > + > struct E(link_map) > { > EW(Addr) l_addr; > @@ -70,6 +76,35 @@ _Static_assert (offsetof (struct r_debug, r_map) > == offsetof (struct E(r_debug), r_map), "r_map"); > #endif > > +static EW(Addr) > +E(r_debug_offset) (EW(Dyn) *d, int memfd, EW(Addr) d_addr) > +{ > +#ifdef __mips__ > + EW(Addr) ptr; > + > + switch (d->d_tag) > + { > + case DT_MIPS_RLD_MAP_REL: > + ptr = d_addr + d->d_un.d_val; > + break; > + case DT_MIPS_RLD_MAP: > + ptr = d->d_un.d_ptr; > + break; > + default: > + return 0; > + } > + > + if (pread (memfd, &ptr, sizeof (ptr), ptr) != sizeof (ptr)) > + return 0; > + > + return ptr; > +#else > + if (d->d_tag == DT_DEBUG) > + return (off_t) d->d_un.d_ptr; > + > + return 0; > +#endif > +} > > static int > > @@ -126,21 +161,25 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, > != p[i].p_filesz) > error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); > > - /* Search for the DT_DEBUG entry. */ > + /* Search for the r_debug struct. */ > for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j) > - if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) > - { > - struct E(r_debug) r; > - if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) > - != sizeof (r)) > - error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); > - > - if (r.r_map != 0) > - { > - list = r.r_map; > - break; > - } > - } > + { > + EW(Addr) d_addr = offset + p[i].p_vaddr + sizeof (EW(Dyn)) * j; > + EW(Addr) off = E(r_debug_offset)(&dyn[j], memfd, d_addr); > + if (off != 0) > + { > + struct E(r_debug) r; > + if (pread (memfd, &r, sizeof (r), off) > + != sizeof (r)) > + error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); > + > + if (r.r_map != 0) > + { > + list = r.r_map; > + break; > + } > + } > + } > > free (dyn); > break; > -- > 2.35.0 > > I think a header file to access r_debug works better. MIPS can provide one to override the generic header file. -- H.J. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] mips: pldd: support DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL 2022-01-28 20:45 ` H.J. Lu @ 2022-01-28 20:48 ` Adhemerval Zanella 2022-01-28 20:50 ` Carlos O'Donell 2022-01-28 21:17 ` [PATCH v2] " Xi Ruoyao 1 sibling, 1 reply; 12+ messages in thread From: Adhemerval Zanella @ 2022-01-28 20:48 UTC (permalink / raw) To: libc-alpha On 28/01/2022 17:45, H.J. Lu via Libc-alpha wrote: > On Fri, Jan 28, 2022 at 10:57 AM Xi Ruoyao via Libc-alpha > <libc-alpha@sourceware.org> wrote: >> >> MIPS uses DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL for accessing r_debug, >> instead of DT_DEBUG. >> --- >> elf/pldd-xx.c | 67 ++++++++++++++++++++++++++++++++++++++++----------- >> 1 file changed, 53 insertions(+), 14 deletions(-) >> >> diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c >> index 1cdfb49c53..ec397f00e5 100644 >> --- a/elf/pldd-xx.c >> +++ b/elf/pldd-xx.c >> @@ -22,6 +22,12 @@ >> #define EW_(e, w, t) EW__(e, w, _##t) >> #define EW__(e, w, t) e##w##t >> >> +#if CLASS == 32 >> +typedef Elf32_Word E(val_type); >> +#else >> +typedef Elf64_Xword E(val_type); >> +#endif >> + >> struct E(link_map) >> { >> EW(Addr) l_addr; >> @@ -70,6 +76,35 @@ _Static_assert (offsetof (struct r_debug, r_map) >> == offsetof (struct E(r_debug), r_map), "r_map"); >> #endif >> >> +static EW(Addr) >> +E(r_debug_offset) (EW(Dyn) *d, int memfd, EW(Addr) d_addr) >> +{ >> +#ifdef __mips__ >> + EW(Addr) ptr; >> + >> + switch (d->d_tag) >> + { >> + case DT_MIPS_RLD_MAP_REL: >> + ptr = d_addr + d->d_un.d_val; >> + break; >> + case DT_MIPS_RLD_MAP: >> + ptr = d->d_un.d_ptr; >> + break; >> + default: >> + return 0; >> + } >> + >> + if (pread (memfd, &ptr, sizeof (ptr), ptr) != sizeof (ptr)) >> + return 0; >> + >> + return ptr; >> +#else >> + if (d->d_tag == DT_DEBUG) >> + return (off_t) d->d_un.d_ptr; >> + >> + return 0; >> +#endif >> +} >> >> static int >> >> @@ -126,21 +161,25 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, >> != p[i].p_filesz) >> error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); >> >> - /* Search for the DT_DEBUG entry. */ >> + /* Search for the r_debug struct. */ >> for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j) >> - if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) >> - { >> - struct E(r_debug) r; >> - if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) >> - != sizeof (r)) >> - error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); >> - >> - if (r.r_map != 0) >> - { >> - list = r.r_map; >> - break; >> - } >> - } >> + { >> + EW(Addr) d_addr = offset + p[i].p_vaddr + sizeof (EW(Dyn)) * j; >> + EW(Addr) off = E(r_debug_offset)(&dyn[j], memfd, d_addr); >> + if (off != 0) >> + { >> + struct E(r_debug) r; >> + if (pread (memfd, &r, sizeof (r), off) >> + != sizeof (r)) >> + error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); >> + >> + if (r.r_map != 0) >> + { >> + list = r.r_map; >> + break; >> + } >> + } >> + } >> >> free (dyn); >> break; >> -- >> 2.35.0 >> >> > > I think a header file to access r_debug works better. MIPS can provide > one to override the generic header file. > Agreed, I think we should avoid arch specific defines (__mips__) on generic code. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] mips: pldd: support DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL 2022-01-28 20:48 ` Adhemerval Zanella @ 2022-01-28 20:50 ` Carlos O'Donell 0 siblings, 0 replies; 12+ messages in thread From: Carlos O'Donell @ 2022-01-28 20:50 UTC (permalink / raw) To: Adhemerval Zanella, libc-alpha On 1/28/22 15:48, Adhemerval Zanella via Libc-alpha wrote: > > > On 28/01/2022 17:45, H.J. Lu via Libc-alpha wrote: >> On Fri, Jan 28, 2022 at 10:57 AM Xi Ruoyao via Libc-alpha >> <libc-alpha@sourceware.org> wrote: >>> >>> MIPS uses DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL for accessing r_debug, >>> instead of DT_DEBUG. >>> --- >>> elf/pldd-xx.c | 67 ++++++++++++++++++++++++++++++++++++++++----------- >>> 1 file changed, 53 insertions(+), 14 deletions(-) >>> >>> diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c >>> index 1cdfb49c53..ec397f00e5 100644 >>> --- a/elf/pldd-xx.c >>> +++ b/elf/pldd-xx.c >>> @@ -22,6 +22,12 @@ >>> #define EW_(e, w, t) EW__(e, w, _##t) >>> #define EW__(e, w, t) e##w##t >>> >>> +#if CLASS == 32 >>> +typedef Elf32_Word E(val_type); >>> +#else >>> +typedef Elf64_Xword E(val_type); >>> +#endif >>> + >>> struct E(link_map) >>> { >>> EW(Addr) l_addr; >>> @@ -70,6 +76,35 @@ _Static_assert (offsetof (struct r_debug, r_map) >>> == offsetof (struct E(r_debug), r_map), "r_map"); >>> #endif >>> >>> +static EW(Addr) >>> +E(r_debug_offset) (EW(Dyn) *d, int memfd, EW(Addr) d_addr) >>> +{ >>> +#ifdef __mips__ >>> + EW(Addr) ptr; >>> + >>> + switch (d->d_tag) >>> + { >>> + case DT_MIPS_RLD_MAP_REL: >>> + ptr = d_addr + d->d_un.d_val; >>> + break; >>> + case DT_MIPS_RLD_MAP: >>> + ptr = d->d_un.d_ptr; >>> + break; >>> + default: >>> + return 0; >>> + } >>> + >>> + if (pread (memfd, &ptr, sizeof (ptr), ptr) != sizeof (ptr)) >>> + return 0; >>> + >>> + return ptr; >>> +#else >>> + if (d->d_tag == DT_DEBUG) >>> + return (off_t) d->d_un.d_ptr; >>> + >>> + return 0; >>> +#endif >>> +} >>> >>> static int >>> >>> @@ -126,21 +161,25 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, >>> != p[i].p_filesz) >>> error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); >>> >>> - /* Search for the DT_DEBUG entry. */ >>> + /* Search for the r_debug struct. */ >>> for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j) >>> - if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) >>> - { >>> - struct E(r_debug) r; >>> - if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) >>> - != sizeof (r)) >>> - error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); >>> - >>> - if (r.r_map != 0) >>> - { >>> - list = r.r_map; >>> - break; >>> - } >>> - } >>> + { >>> + EW(Addr) d_addr = offset + p[i].p_vaddr + sizeof (EW(Dyn)) * j; >>> + EW(Addr) off = E(r_debug_offset)(&dyn[j], memfd, d_addr); >>> + if (off != 0) >>> + { >>> + struct E(r_debug) r; >>> + if (pread (memfd, &r, sizeof (r), off) >>> + != sizeof (r)) >>> + error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); >>> + >>> + if (r.r_map != 0) >>> + { >>> + list = r.r_map; >>> + break; >>> + } >>> + } >>> + } >>> >>> free (dyn); >>> break; >>> -- >>> 2.35.0 >>> >>> >> >> I think a header file to access r_debug works better. MIPS can provide >> one to override the generic header file. >> > > Agreed, I think we should avoid arch specific defines (__mips__) on generic > code. Ah! I see, the objection if about arch-defines in tests. Yes, lets clean that up. -- Cheers, Carlos. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2] mips: pldd: support DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL 2022-01-28 20:45 ` H.J. Lu 2022-01-28 20:48 ` Adhemerval Zanella @ 2022-01-28 21:17 ` Xi Ruoyao 2022-01-28 21:22 ` H.J. Lu 1 sibling, 1 reply; 12+ messages in thread From: Xi Ruoyao @ 2022-01-28 21:17 UTC (permalink / raw) To: GNU C Library; +Cc: syq, Joseph Myers, Jiaxun Yang, H.J. Lu [v2: remove useless typedef, seperate E(r_debug_offset) into a header.] MIPS uses DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL for accessing r_debug, instead of DT_DEBUG. Signed-off-by: Xi Ruoyao <xry111@mengyan1223.wang> --- elf/pldd-xx.c | 34 +++++++++++++++----------- sysdeps/generic/elf-pldd-rdebug.h | 26 ++++++++++++++++++++ sysdeps/mips/elf-pldd-rdebug.h | 40 +++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 sysdeps/generic/elf-pldd-rdebug.h create mode 100644 sysdeps/mips/elf-pldd-rdebug.h diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c index 1cdfb49c53..368528371d 100644 --- a/elf/pldd-xx.c +++ b/elf/pldd-xx.c @@ -22,6 +22,8 @@ #define EW_(e, w, t) EW__(e, w, _##t) #define EW__(e, w, t) e##w##t +#include <elf-pldd-rdebug.h> + struct E(link_map) { EW(Addr) l_addr; @@ -126,21 +128,25 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, != p[i].p_filesz) error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); - /* Search for the DT_DEBUG entry. */ + /* Search for the r_debug struct. */ for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j) - if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) - { - struct E(r_debug) r; - if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) - != sizeof (r)) - error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); - - if (r.r_map != 0) - { - list = r.r_map; - break; - } - } + { + EW(Addr) d_addr = offset + p[i].p_vaddr + sizeof (EW(Dyn)) * j; + EW(Addr) off = E(r_debug_offset)(&dyn[j], memfd, d_addr); + if (off != 0) + { + struct E(r_debug) r; + if (pread (memfd, &r, sizeof (r), off) + != sizeof (r)) + error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); + + if (r.r_map != 0) + { + list = r.r_map; + break; + } + } + } free (dyn); break; diff --git a/sysdeps/generic/elf-pldd-rdebug.h b/sysdeps/generic/elf-pldd-rdebug.h new file mode 100644 index 0000000000..6df651cd55 --- /dev/null +++ b/sysdeps/generic/elf-pldd-rdebug.h @@ -0,0 +1,26 @@ +/* Function to access r_debug structure for pldd. + Copyright (C) 2020-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +static EW(Addr) +E(r_debug_offset) (EW(Dyn) *d, int, EW(Addr)) +{ + if (d->d_tag == DT_DEBUG) + return (EW(Addr)) d->d_un.d_ptr; + + return 0; +} diff --git a/sysdeps/mips/elf-pldd-rdebug.h b/sysdeps/mips/elf-pldd-rdebug.h new file mode 100644 index 0000000000..89a20c191a --- /dev/null +++ b/sysdeps/mips/elf-pldd-rdebug.h @@ -0,0 +1,40 @@ +/* Function to access r_debug structure for pldd, MIPS specific version. + Copyright (C) 2020-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +static EW(Addr) +E(r_debug_offset) (EW(Dyn) *d, int memfd, EW(Addr) d_addr) +{ + EW(Addr) ptr; + + switch (d->d_tag) + { + case DT_MIPS_RLD_MAP_REL: + ptr = d_addr + d->d_un.d_val; + break; + case DT_MIPS_RLD_MAP: + ptr = d->d_un.d_ptr; + break; + default: + return 0; + } + + if (pread (memfd, &ptr, sizeof (ptr), ptr) != sizeof (ptr)) + return 0; + + return ptr; +} -- 2.35.0 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] mips: pldd: support DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL 2022-01-28 21:17 ` [PATCH v2] " Xi Ruoyao @ 2022-01-28 21:22 ` H.J. Lu 2022-01-28 22:04 ` [PATCH v3 0/3] mips: add target-specific r_debug offset Xi Ruoyao 0 siblings, 1 reply; 12+ messages in thread From: H.J. Lu @ 2022-01-28 21:22 UTC (permalink / raw) To: Xi Ruoyao; +Cc: GNU C Library, syq, Joseph Myers, Jiaxun Yang On Fri, Jan 28, 2022 at 1:17 PM Xi Ruoyao <xry111@mengyan1223.wang> wrote: > > [v2: remove useless typedef, seperate E(r_debug_offset) into a header.] > > MIPS uses DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL for accessing r_debug, > instead of DT_DEBUG. > > Signed-off-by: Xi Ruoyao <xry111@mengyan1223.wang> > --- > elf/pldd-xx.c | 34 +++++++++++++++----------- > sysdeps/generic/elf-pldd-rdebug.h | 26 ++++++++++++++++++++ > sysdeps/mips/elf-pldd-rdebug.h | 40 +++++++++++++++++++++++++++++++ > 3 files changed, 86 insertions(+), 14 deletions(-) > create mode 100644 sysdeps/generic/elf-pldd-rdebug.h > create mode 100644 sysdeps/mips/elf-pldd-rdebug.h > > diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c > index 1cdfb49c53..368528371d 100644 > --- a/elf/pldd-xx.c > +++ b/elf/pldd-xx.c > @@ -22,6 +22,8 @@ > #define EW_(e, w, t) EW__(e, w, _##t) > #define EW__(e, w, t) e##w##t > > +#include <elf-pldd-rdebug.h> You should drop pldd in filename and also handle tst-dlmopen4.c in the same header file. > + > struct E(link_map) > { > EW(Addr) l_addr; > @@ -126,21 +128,25 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, > != p[i].p_filesz) > error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); > > - /* Search for the DT_DEBUG entry. */ > + /* Search for the r_debug struct. */ > for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j) > - if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) > - { > - struct E(r_debug) r; > - if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) > - != sizeof (r)) > - error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); > - > - if (r.r_map != 0) > - { > - list = r.r_map; > - break; > - } > - } > + { > + EW(Addr) d_addr = offset + p[i].p_vaddr + sizeof (EW(Dyn)) * j; > + EW(Addr) off = E(r_debug_offset)(&dyn[j], memfd, d_addr); > + if (off != 0) > + { > + struct E(r_debug) r; > + if (pread (memfd, &r, sizeof (r), off) > + != sizeof (r)) > + error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); > + > + if (r.r_map != 0) > + { > + list = r.r_map; > + break; > + } > + } > + } > > free (dyn); > break; > diff --git a/sysdeps/generic/elf-pldd-rdebug.h b/sysdeps/generic/elf-pldd-rdebug.h > new file mode 100644 > index 0000000000..6df651cd55 > --- /dev/null > +++ b/sysdeps/generic/elf-pldd-rdebug.h > @@ -0,0 +1,26 @@ > +/* Function to access r_debug structure for pldd. > + Copyright (C) 2020-2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +static EW(Addr) > +E(r_debug_offset) (EW(Dyn) *d, int, EW(Addr)) > +{ > + if (d->d_tag == DT_DEBUG) > + return (EW(Addr)) d->d_un.d_ptr; > + > + return 0; > +} > diff --git a/sysdeps/mips/elf-pldd-rdebug.h b/sysdeps/mips/elf-pldd-rdebug.h > new file mode 100644 > index 0000000000..89a20c191a > --- /dev/null > +++ b/sysdeps/mips/elf-pldd-rdebug.h > @@ -0,0 +1,40 @@ > +/* Function to access r_debug structure for pldd, MIPS specific version. > + Copyright (C) 2020-2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +static EW(Addr) > +E(r_debug_offset) (EW(Dyn) *d, int memfd, EW(Addr) d_addr) > +{ > + EW(Addr) ptr; > + > + switch (d->d_tag) > + { > + case DT_MIPS_RLD_MAP_REL: > + ptr = d_addr + d->d_un.d_val; > + break; > + case DT_MIPS_RLD_MAP: > + ptr = d->d_un.d_ptr; > + break; > + default: > + return 0; > + } > + > + if (pread (memfd, &ptr, sizeof (ptr), ptr) != sizeof (ptr)) > + return 0; > + > + return ptr; > +} > -- > 2.35.0 > > -- H.J. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 0/3] mips: add target-specific r_debug offset 2022-01-28 21:22 ` H.J. Lu @ 2022-01-28 22:04 ` Xi Ruoyao 2022-01-28 22:05 ` [PATCH v3 1/3] add sysdeps/{generic,mips}/elfxx-r_debug.h Xi Ruoyao ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Xi Ruoyao @ 2022-01-28 22:04 UTC (permalink / raw) To: Carlos O'Donell, H.J. Lu, GNU C Library Cc: syq, Joseph Myers, Jiaxun Yang, xry111 On Fri, 2022-01-28 at 13:22 -0800, H.J. Lu wrote: > You should drop pldd in filename and also handle tst-dlmopen4.c > in the same header file. v3: pldd and tst-dlmopen4 change revised as a new patch series. -- Xi Ruoyao <xry111@mengyan1223.wang> School of Aerospace Science and Technology, Xidian University ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 1/3] add sysdeps/{generic,mips}/elfxx-r_debug.h 2022-01-28 22:04 ` [PATCH v3 0/3] mips: add target-specific r_debug offset Xi Ruoyao @ 2022-01-28 22:05 ` Xi Ruoyao 2022-01-28 22:08 ` [PATCH v3 3/3] elf: tst-dlmopen4: use target specific r_debug_offset function Xi Ruoyao 2022-01-28 22:07 ` [PATCH v3 2/3] pldd: use target-specific " Xi Ruoyao 2022-01-29 19:41 ` [PATCH] elf: Add <dl-r_debug.h> H.J. Lu 2 siblings, 1 reply; 12+ messages in thread From: Xi Ruoyao @ 2022-01-28 22:05 UTC (permalink / raw) To: Carlos O'Donell, H.J. Lu, GNU C Library Cc: syq, Joseph Myers, Jiaxun Yang, xry111 Some targets (notably, MIPS) have target-specific way to get the address of r_debug instead of the normal DT_DEBUG. Add a header wrapping the difference. --- sysdeps/generic/elfxx-r_debug.h | 26 ++++++++++++++++++ sysdeps/mips/elfxx-r_debug.h | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 sysdeps/generic/elfxx-r_debug.h create mode 100644 sysdeps/mips/elfxx-r_debug.h diff --git a/sysdeps/generic/elfxx-r_debug.h b/sysdeps/generic/elfxx- r_debug.h new file mode 100644 index 0000000000..7083c95e36 --- /dev/null +++ b/sysdeps/generic/elfxx-r_debug.h @@ -0,0 +1,26 @@ +/* Function to access r_debug structure. + Copyright (C) 2020-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +static EW(Addr) +E(r_debug_offset) (EW(Dyn) *d, int, EW(Addr)) +{ + if (d->d_tag == DT_DEBUG) + return (EW(Addr)) d->d_un.d_ptr; + + return 0; +} diff --git a/sysdeps/mips/elfxx-r_debug.h b/sysdeps/mips/elfxx-r_debug.h new file mode 100644 index 0000000000..a13d069c35 --- /dev/null +++ b/sysdeps/mips/elfxx-r_debug.h @@ -0,0 +1,48 @@ +/* Function to access r_debug structure, MIPS specific version. + Copyright (C) 2020-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +static EW(Addr) +E(r_debug_offset) (EW(Dyn) *d, int memfd, EW(Addr) d_addr) +{ + EW(Addr) ptr; + +#ifdef R_DEBUG_IN_PROCESS + d_addr = (EW(Addr)) d; +#endif + + switch (d->d_tag) + { + case DT_MIPS_RLD_MAP_REL: + ptr = d_addr + d->d_un.d_val; + break; + case DT_MIPS_RLD_MAP: + ptr = d->d_un.d_ptr; + break; + default: + return 0; + } + +#ifdef R_DEBUG_IN_PROCESS + ptr = *(EW(Addr) *) ptr; +#else + if (pread (memfd, &ptr, sizeof (ptr), ptr) != sizeof (ptr)) + return 0; +#endif + + return ptr; +} -- 2.35.0 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 3/3] elf: tst-dlmopen4: use target specific r_debug_offset function 2022-01-28 22:05 ` [PATCH v3 1/3] add sysdeps/{generic,mips}/elfxx-r_debug.h Xi Ruoyao @ 2022-01-28 22:08 ` Xi Ruoyao 0 siblings, 0 replies; 12+ messages in thread From: Xi Ruoyao @ 2022-01-28 22:08 UTC (permalink / raw) To: Carlos O'Donell, H.J. Lu, GNU C Library Cc: syq, Joseph Myers, Jiaxun Yang, xry111 Fix the test failure on MIPS. --- elf/tst-dlmopen4.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/elf/tst-dlmopen4.c b/elf/tst-dlmopen4.c index d8bcf7e9d5..28e052f199 100644 --- a/elf/tst-dlmopen4.c +++ b/elf/tst-dlmopen4.c @@ -25,16 +25,10 @@ #include <support/check.h> #include <support/test-driver.h> -#ifndef ELF_MACHINE_GET_R_DEBUG -# define ELF_MACHINE_GET_R_DEBUG(d) \ - (__extension__ ({ \ - struct r_debug_extended *debug; \ - if ((d)->d_tag == DT_DEBUG) \ - debug = (struct r_debug_extended *) (d)->d_un.d_ptr; \ - else \ - debug = NULL; \ - debug; })) -#endif +#define E(x) x +#define EW(x) ElfW(x) +#define R_DEBUG_IN_PROCESS +#include <elfxx-r_debug.h> static int do_test (void) @@ -44,7 +38,7 @@ do_test (void) for (d = _DYNAMIC; d->d_tag != DT_NULL; ++d) { - debug = ELF_MACHINE_GET_R_DEBUG (d); + debug = (struct r_debug_extended *) r_debug_offset (d, 0, 0); if (debug != NULL) break; } -- 2.35.0 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 2/3] pldd: use target-specific r_debug_offset function 2022-01-28 22:04 ` [PATCH v3 0/3] mips: add target-specific r_debug offset Xi Ruoyao 2022-01-28 22:05 ` [PATCH v3 1/3] add sysdeps/{generic,mips}/elfxx-r_debug.h Xi Ruoyao @ 2022-01-28 22:07 ` Xi Ruoyao 2022-01-29 19:41 ` [PATCH] elf: Add <dl-r_debug.h> H.J. Lu 2 siblings, 0 replies; 12+ messages in thread From: Xi Ruoyao @ 2022-01-28 22:07 UTC (permalink / raw) To: Carlos O'Donell, H.J. Lu, GNU C Library Cc: syq, Joseph Myers, Jiaxun Yang It allows pldd to work on MIPS. --- elf/pldd-xx.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c index 1cdfb49c53..5560afe049 100644 --- a/elf/pldd-xx.c +++ b/elf/pldd-xx.c @@ -22,6 +22,8 @@ #define EW_(e, w, t) EW__(e, w, _##t) #define EW__(e, w, t) e##w##t +#include <elfxx-r_debug.h> + struct E(link_map) { EW(Addr) l_addr; @@ -126,21 +128,25 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, != p[i].p_filesz) error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); - /* Search for the DT_DEBUG entry. */ + /* Search for the r_debug struct. */ for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j) - if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) - { - struct E(r_debug) r; - if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) - != sizeof (r)) - error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); - - if (r.r_map != 0) - { - list = r.r_map; - break; - } - } + { + EW(Addr) d_addr = offset + p[i].p_vaddr + sizeof (EW(Dyn)) * j; + EW(Addr) off = E(r_debug_offset)(&dyn[j], memfd, d_addr); + if (off != 0) + { + struct E(r_debug) r; + if (pread (memfd, &r, sizeof (r), off) + != sizeof (r)) + error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); + + if (r.r_map != 0) + { + list = r.r_map; + break; + } + } + } free (dyn); break; -- 2.35.0 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] elf: Add <dl-r_debug.h> 2022-01-28 22:04 ` [PATCH v3 0/3] mips: add target-specific r_debug offset Xi Ruoyao 2022-01-28 22:05 ` [PATCH v3 1/3] add sysdeps/{generic,mips}/elfxx-r_debug.h Xi Ruoyao 2022-01-28 22:07 ` [PATCH v3 2/3] pldd: use target-specific " Xi Ruoyao @ 2022-01-29 19:41 ` H.J. Lu 2022-01-29 19:56 ` Xi Ruoyao 2 siblings, 1 reply; 12+ messages in thread From: H.J. Lu @ 2022-01-29 19:41 UTC (permalink / raw) To: Xi Ruoyao Cc: Carlos O'Donell, GNU C Library, syq, Joseph Myers, Jiaxun Yang On Sat, Jan 29, 2022 at 06:04:12AM +0800, Xi Ruoyao wrote: > On Fri, 2022-01-28 at 13:22 -0800, H.J. Lu wrote: > > > You should drop pldd in filename and also handle tst-dlmopen4.c > > in the same header file. > > v3: pldd and tst-dlmopen4 change revised as a new patch series. Can you try this patch instead? H.J. --- Add <dl-r_debug.h> to get the adddress of the r_debug structure after relocation and its offset before relocation from the PT_DYNAMIC segment to support DT_DEBUG, DT_MIPS_RLD_MAP_REL and DT_MIPS_RLD_MAP. Co-developed-by: Xi Ruoyao <xry111@mengyan1223.wang> --- elf/pldd-xx.c | 34 +++++++++++-------- elf/tst-dlmopen4.c | 15 +++------ sysdeps/generic/dl-r_debug.h | 36 ++++++++++++++++++++ sysdeps/mips/dl-r_debug.h | 64 ++++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 sysdeps/generic/dl-r_debug.h create mode 100644 sysdeps/mips/dl-r_debug.h diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c index 1cdfb49c53..30513b423f 100644 --- a/elf/pldd-xx.c +++ b/elf/pldd-xx.c @@ -22,6 +22,8 @@ #define EW_(e, w, t) EW__(e, w, _##t) #define EW__(e, w, t) e##w##t +#include <dl-r_debug.h> + struct E(link_map) { EW(Addr) l_addr; @@ -126,21 +128,25 @@ E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv, != p[i].p_filesz) error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section")); - /* Search for the DT_DEBUG entry. */ + /* Search for the struct r_debug. */ for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j) - if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) - { - struct E(r_debug) r; - if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) - != sizeof (r)) - error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); - - if (r.r_map != 0) - { - list = r.r_map; - break; - } - } + { + EW(Addr) off = offset + p[i].p_vaddr + sizeof (EW(Dyn)) * j; + off = E(r_debug_offset) (&dyn[j], memfd, off); + if (off != 0) + { + struct E(r_debug) r; + if (pread (memfd, &r, sizeof (r), off) + != sizeof (r)) + error (EXIT_FAILURE, 0, gettext ("cannot read r_debug")); + + if (r.r_map != 0) + { + list = r.r_map; + break; + } + } + } free (dyn); break; diff --git a/elf/tst-dlmopen4.c b/elf/tst-dlmopen4.c index d8bcf7e9d5..8456f89053 100644 --- a/elf/tst-dlmopen4.c +++ b/elf/tst-dlmopen4.c @@ -25,16 +25,9 @@ #include <support/check.h> #include <support/test-driver.h> -#ifndef ELF_MACHINE_GET_R_DEBUG -# define ELF_MACHINE_GET_R_DEBUG(d) \ - (__extension__ ({ \ - struct r_debug_extended *debug; \ - if ((d)->d_tag == DT_DEBUG) \ - debug = (struct r_debug_extended *) (d)->d_un.d_ptr; \ - else \ - debug = NULL; \ - debug; })) -#endif +#define E(x) x +#define EW(x) ElfW(x) +#include <dl-r_debug.h> static int do_test (void) @@ -44,7 +37,7 @@ do_test (void) for (d = _DYNAMIC; d->d_tag != DT_NULL; ++d) { - debug = ELF_MACHINE_GET_R_DEBUG (d); + debug = (struct r_debug_extended *) r_debug_address (d); if (debug != NULL) break; } diff --git a/sysdeps/generic/dl-r_debug.h b/sysdeps/generic/dl-r_debug.h new file mode 100644 index 0000000000..e3edeb4f06 --- /dev/null +++ b/sysdeps/generic/dl-r_debug.h @@ -0,0 +1,36 @@ +/* Function to access r_debug structure. Generic version. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +/* Return the address of the struct r_debug after relocation. */ + +static inline EW(Addr) +E(r_debug_address) (EW(Dyn) *d) +{ + if (d->d_tag == DT_DEBUG) + return (EW(Addr)) d->d_un.d_ptr; + + return 0; +} + +/* Return the offset of the struct r_debug before relocation. */ + +static inline EW(Addr) +E(r_debug_offset) (EW(Dyn) *d, int fd, EW(Addr) offset) +{ + return E(r_debug_address) (d); +} diff --git a/sysdeps/mips/dl-r_debug.h b/sysdeps/mips/dl-r_debug.h new file mode 100644 index 0000000000..edd83d46fd --- /dev/null +++ b/sysdeps/mips/dl-r_debug.h @@ -0,0 +1,64 @@ +/* Function to access r_debug structure. MIPS specific version. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifdef EW_ +/* Return the offset of the struct r_debug before relocation. */ + +static inline EW(Addr) +E(r_debug_offset) (EW(Dyn) *d, int fd, EW(Addr) offset) +{ + switch (d->d_tag) + { + case DT_MIPS_RLD_MAP_REL: + offset += d->d_un.d_val; + break; + case DT_MIPS_RLD_MAP: + offset = d->d_un.d_ptr; + break; + default: + return 0; + } + + if (pread (fd, &offset, sizeof (offset), offset) != sizeof (offset)) + return 0; + + return offset; +} +#else +/* Return the address of the struct r_debug after relocation. */ + +static inline EW(Addr) +E(r_debug_address) (EW(Dyn) *d) +{ + EW(Addr) ptr; + + switch (d->d_tag) + { + case DT_MIPS_RLD_MAP_REL: + ptr = ((EW(Addr)) d) + d->d_un.d_val; + break; + case DT_MIPS_RLD_MAP: + ptr = d->d_un.d_ptr; + break; + default: + return 0; + } + + return *(EW(Addr) *) ptr; +} +#endif -- 2.34.1 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] elf: Add <dl-r_debug.h> 2022-01-29 19:41 ` [PATCH] elf: Add <dl-r_debug.h> H.J. Lu @ 2022-01-29 19:56 ` Xi Ruoyao 0 siblings, 0 replies; 12+ messages in thread From: Xi Ruoyao @ 2022-01-29 19:56 UTC (permalink / raw) To: H.J. Lu Cc: Carlos O'Donell, GNU C Library, syq, Joseph Myers, Jiaxun Yang, xry111 On Sat, 2022-01-29 at 11:41 -0800, H.J. Lu wrote: > On Sat, Jan 29, 2022 at 06:04:12AM +0800, Xi Ruoyao wrote: > > On Fri, 2022-01-28 at 13:22 -0800, H.J. Lu wrote: > > > > > You should drop pldd in filename and also handle tst-dlmopen4.c > > > in the same header file. > > > > v3: pldd and tst-dlmopen4 change revised as a new patch series. > > Can you try this patch instead? It looks a lot better than mine :). Tested on mips64 (N64 ABI) and x86_64, result good. > H.J. > --- > Add <dl-r_debug.h> to get the adddress of the r_debug structure after > relocation and its offset before relocation from the PT_DYNAMIC > segment > to support DT_DEBUG, DT_MIPS_RLD_MAP_REL and DT_MIPS_RLD_MAP. > > Co-developed-by: Xi Ruoyao <xry111@mengyan1223.wang> > --- > elf/pldd-xx.c | 34 +++++++++++-------- > elf/tst-dlmopen4.c | 15 +++------ > sysdeps/generic/dl-r_debug.h | 36 ++++++++++++++++++++ > sysdeps/mips/dl-r_debug.h | 64 > ++++++++++++++++++++++++++++++++++++ > 4 files changed, 124 insertions(+), 25 deletions(-) > create mode 100644 sysdeps/generic/dl-r_debug.h > create mode 100644 sysdeps/mips/dl-r_debug.h > > diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c > index 1cdfb49c53..30513b423f 100644 > --- a/elf/pldd-xx.c > +++ b/elf/pldd-xx.c > @@ -22,6 +22,8 @@ > #define EW_(e, w, t) EW__(e, w, _##t) > #define EW__(e, w, t) e##w##t > > +#include <dl-r_debug.h> > + > struct E(link_map) > { > EW(Addr) l_addr; > @@ -126,21 +128,25 @@ E(find_maps) (const char *exe, int memfd, pid_t > pid, void *auxv, > != p[i].p_filesz) > error (EXIT_FAILURE, 0, gettext ("cannot read dynamic > section")); > > - /* Search for the DT_DEBUG entry. */ > + /* Search for the struct r_debug. */ > for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); > ++j) > - if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0) > - { > - struct E(r_debug) r; > - if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr) > - != sizeof (r)) > - error (EXIT_FAILURE, 0, gettext ("cannot read > r_debug")); > - > - if (r.r_map != 0) > - { > - list = r.r_map; > - break; > - } > - } > + { > + EW(Addr) off = offset + p[i].p_vaddr + sizeof (EW(Dyn)) * > j; > + off = E(r_debug_offset) (&dyn[j], memfd, off); > + if (off != 0) > + { > + struct E(r_debug) r; > + if (pread (memfd, &r, sizeof (r), off) > + != sizeof (r)) > + error (EXIT_FAILURE, 0, gettext ("cannot read > r_debug")); > + > + if (r.r_map != 0) > + { > + list = r.r_map; > + break; > + } > + } > + } > > free (dyn); > break; > diff --git a/elf/tst-dlmopen4.c b/elf/tst-dlmopen4.c > index d8bcf7e9d5..8456f89053 100644 > --- a/elf/tst-dlmopen4.c > +++ b/elf/tst-dlmopen4.c > @@ -25,16 +25,9 @@ > #include <support/check.h> > #include <support/test-driver.h> > > -#ifndef ELF_MACHINE_GET_R_DEBUG > -# define ELF_MACHINE_GET_R_DEBUG(d) \ > - (__extension__ ({ \ > - struct r_debug_extended *debug; \ > - if ((d)->d_tag == DT_DEBUG) \ > - debug = (struct r_debug_extended *) (d)->d_un.d_ptr; \ > - else \ > - debug = NULL; \ > - debug; })) > -#endif > +#define E(x) x > +#define EW(x) ElfW(x) > +#include <dl-r_debug.h> > > static int > do_test (void) > @@ -44,7 +37,7 @@ do_test (void) > > for (d = _DYNAMIC; d->d_tag != DT_NULL; ++d) > { > - debug = ELF_MACHINE_GET_R_DEBUG (d); > + debug = (struct r_debug_extended *) r_debug_address (d); > if (debug != NULL) > break; > } > diff --git a/sysdeps/generic/dl-r_debug.h b/sysdeps/generic/dl- > r_debug.h > new file mode 100644 > index 0000000000..e3edeb4f06 > --- /dev/null > +++ b/sysdeps/generic/dl-r_debug.h > @@ -0,0 +1,36 @@ > +/* Function to access r_debug structure. Generic version. > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be > useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +/* Return the address of the struct r_debug after relocation. */ > + > +static inline EW(Addr) > +E(r_debug_address) (EW(Dyn) *d) > +{ > + if (d->d_tag == DT_DEBUG) > + return (EW(Addr)) d->d_un.d_ptr; > + > + return 0; > +} > + > +/* Return the offset of the struct r_debug before relocation. */ > + > +static inline EW(Addr) > +E(r_debug_offset) (EW(Dyn) *d, int fd, EW(Addr) offset) > +{ > + return E(r_debug_address) (d); > +} > diff --git a/sysdeps/mips/dl-r_debug.h b/sysdeps/mips/dl-r_debug.h > new file mode 100644 > index 0000000000..edd83d46fd > --- /dev/null > +++ b/sysdeps/mips/dl-r_debug.h > @@ -0,0 +1,64 @@ > +/* Function to access r_debug structure. MIPS specific version. > + Copyright (C) 2022 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be > useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#ifdef EW_ > +/* Return the offset of the struct r_debug before relocation. */ > + > +static inline EW(Addr) > +E(r_debug_offset) (EW(Dyn) *d, int fd, EW(Addr) offset) > +{ > + switch (d->d_tag) > + { > + case DT_MIPS_RLD_MAP_REL: > + offset += d->d_un.d_val; > + break; > + case DT_MIPS_RLD_MAP: > + offset = d->d_un.d_ptr; > + break; > + default: > + return 0; > + } > + > + if (pread (fd, &offset, sizeof (offset), offset) != sizeof > (offset)) > + return 0; > + > + return offset; > +} > +#else > +/* Return the address of the struct r_debug after relocation. */ > + > +static inline EW(Addr) > +E(r_debug_address) (EW(Dyn) *d) > +{ > + EW(Addr) ptr; > + > + switch (d->d_tag) > + { > + case DT_MIPS_RLD_MAP_REL: > + ptr = ((EW(Addr)) d) + d->d_un.d_val; > + break; > + case DT_MIPS_RLD_MAP: > + ptr = d->d_un.d_ptr; > + break; > + default: > + return 0; > + } > + > + return *(EW(Addr) *) ptr; > +} > +#endif -- Xi Ruoyao <xry111@mengyan1223.wang> School of Aerospace Science and Technology, Xidian University ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2022-01-29 19:57 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-01-28 18:56 [PATCH] mips: pldd: support DT_MIPS_RLD_MAP and DT_MIPS_RLD_MAP_REL Xi Ruoyao 2022-01-28 20:45 ` H.J. Lu 2022-01-28 20:48 ` Adhemerval Zanella 2022-01-28 20:50 ` Carlos O'Donell 2022-01-28 21:17 ` [PATCH v2] " Xi Ruoyao 2022-01-28 21:22 ` H.J. Lu 2022-01-28 22:04 ` [PATCH v3 0/3] mips: add target-specific r_debug offset Xi Ruoyao 2022-01-28 22:05 ` [PATCH v3 1/3] add sysdeps/{generic,mips}/elfxx-r_debug.h Xi Ruoyao 2022-01-28 22:08 ` [PATCH v3 3/3] elf: tst-dlmopen4: use target specific r_debug_offset function Xi Ruoyao 2022-01-28 22:07 ` [PATCH v3 2/3] pldd: use target-specific " Xi Ruoyao 2022-01-29 19:41 ` [PATCH] elf: Add <dl-r_debug.h> H.J. Lu 2022-01-29 19:56 ` Xi Ruoyao
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).