Hi Dmitry, thanks for the patch. Unfortunately it breaks ARM FDPIC toolchain building: ldso/ldso/dl-startup.c: In function '_dl_start': ldso/ldso/dl-startup.c:268:9: error: aggregate value used where an integer was expected 268 | DL_RELOCATE_RELR(tpnt); | ^~~~~~~~~~~~~~~~
You could use OpenADK to produce such a toolchain. Any idea what is wrong? best regards Waldemar Dmitry Chestnykh wrote, > Nowadays modern libcs like Glibc and musl currently > support processing of RELATIVE relocations compressed > with DT_RELR format. However I have noticed that uClibc-ng > doesn't support this feature and if the source will be linked with > `-Wl,-z,pack-relative-relos` (bfd) or `-Wl,--pack-dyn-relocs=relr` > (lld) then ld.so cannot properly load the produced DSO. > This patch is intended to fix this issue and adds applying > of DT_RELR relative relocation. > > Signed-off-by: Dmitry Chestnykh <dm.chestn...@gmail.com> > --- > include/elf.h | 8 +++++- > ldso/include/dl-elf.h | 38 ++++++++++++++++++++++++++ > ldso/ldso/dl-elf.c | 3 ++ > ldso/ldso/dl-startup.c | 3 ++ > libc/misc/internals/reloc_static_pie.c | 1 + > 5 files changed, 52 insertions(+), 1 deletion(-) > > diff --git a/include/elf.h b/include/elf.h > index b7edbade2..c2efa9978 100644 > --- a/include/elf.h > +++ b/include/elf.h > @@ -60,6 +60,9 @@ typedef uint16_t Elf64_Section; > typedef Elf32_Half Elf32_Versym; > typedef Elf64_Half Elf64_Versym; > > +/* Type for relative relocations in DT_RELR format */ > +typedef Elf32_Word Elf32_Relr; > +typedef Elf64_Xword Elf64_Relr; > > /* The ELF file header. This appears at the start of every ELF file. */ > > @@ -818,7 +821,10 @@ typedef struct > #define DT_ENCODING 32 /* Start of encoded range */ > #define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ > #define DT_PREINIT_ARRAYSZ 33 /* size in bytes of > DT_PREINIT_ARRAY */ > -#define DT_NUM 34 /* Number used */ > +#define DT_RELRSZ 35 /* Size in bytes, of DT_RELR table */ > +#define DT_RELR 36 /* Address of Relr relocs */ > +#define DT_RELRENT 37 /* Size in bytes of one DT_RELR entry */ > +#define DT_NUM 38 /* Number used */ > #define DT_LOOS 0x6000000d /* Start of OS-specific */ > #define DT_HIOS 0x6ffff000 /* End of OS-specific */ > #define DT_LOPROC 0x70000000 /* Start of processor-specific */ > diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h > index 2b99958d9..10b895733 100644 > --- a/ldso/include/dl-elf.h > +++ b/ldso/include/dl-elf.h > @@ -250,5 +250,43 @@ unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, > unsigned long dynamic_info > (((X) & PF_W) ? PROT_WRITE : 0) | \ > (((X) & PF_X) ? PROT_EXEC : 0)) > > +/* Apply relocations in DT_RELR format */ > +#define DL_DO_RELOCATE_RELR(load_addr, relr_start, relr_end) \ > + do { \ > + const ElfW(Relr) *relr = 0; \ > + ElfW(Addr) *reloc_addr = 0; \ > + for (relr = relr_start; relr < relr_end; relr++) { \ > + ElfW(Relr) relr_entry = *relr; \ > + if (!(relr_entry & 1)) \ > + { \ > + reloc_addr = (ElfW(Addr) > *)DL_RELOC_ADDR(load_addr, relr_entry); \ > + *reloc_addr = > (ElfW(Addr))DL_RELOC_ADDR(load_addr, reloc_addr); \ > + reloc_addr++; \ > + } \ > + else \ > + { \ > + for (long int i = 0; (relr_entry >>= 1) > != 0; ++i) { \ > + if ((relr_entry & 1) != 0) \ > + reloc_addr[i] = > (ElfW(Addr))DL_RELOC_ADDR(load_addr, reloc_addr[i]); \ > + } \ > + reloc_addr += CHAR_BIT * > sizeof(ElfW(Relr)) - 1; \ > + } \ > + } \ > + } while (0); > + > +/* The macro to prepare data for the above DL_DO_RELOCATE_RELR */ > +#define DL_RELOCATE_RELR(dyn) \ > + do { \ > + if (dyn->dynamic_info[DT_RELRENT]) \ > + _dl_assert(dyn->dynamic_info[DT_RELRENT] == > sizeof(ElfW(Relr))); \ > + if (dyn->dynamic_info[DT_RELR] && \ > + dyn->dynamic_info[DT_RELRSZ]) { \ > + ElfW(Relr) *relr_start = (ElfW(Relr) > *)((ElfW(Addr))dyn->loadaddr + (ElfW(Addr))dyn->dynamic_info[DT_RELR]); \ > + ElfW(Relr) *relr_end = (ElfW(Relr) *)((const > char *)relr_start + dyn->dynamic_info[DT_RELRSZ]); \ > + _dl_if_debug_dprint("Relocating DT_RELR in %s: > start:%p, end:%p\n", \ > + dyn->libname, (void > *)relr_start, (void *)relr_end); \ > + DL_DO_RELOCATE_RELR(dyn->loadaddr, relr_start, > relr_end); \ > + } \ > + } while (0); > > #endif /* _DL_ELF_H */ > diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c > index 8210a012e..cc42b904f 100644 > --- a/ldso/ldso/dl-elf.c > +++ b/ldso/ldso/dl-elf.c > @@ -1027,6 +1027,9 @@ int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem > *scope, int now_flag) > return goof; > } > > + /* Process DT_RELR relative relocations */ > + DL_RELOCATE_RELR(tpnt); > + > reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE]; > /* On some machines, notably SPARC & PPC, DT_REL* includes DT_JMPREL in its > range. Note that according to the ELF spec, this is completely legal! */ > diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c > index 989711fcc..674c4b7b9 100644 > --- a/ldso/ldso/dl-startup.c > +++ b/ldso/ldso/dl-startup.c > @@ -264,6 +264,9 @@ DL_START(unsigned long args) > that once we are done, we have considerably more flexibility. */ > SEND_EARLY_STDERR_DEBUG("About to do library loader relocations\n"); > > + /* Process DT_RELR relative relocations */ > + DL_RELOCATE_RELR(tpnt); > + > { > int indx; > #if defined(ELF_MACHINE_PLTREL_OVERLAP) > diff --git a/libc/misc/internals/reloc_static_pie.c > b/libc/misc/internals/reloc_static_pie.c > index ab1923024..7ad80f97b 100644 > --- a/libc/misc/internals/reloc_static_pie.c > +++ b/libc/misc/internals/reloc_static_pie.c > @@ -53,6 +53,7 @@ reloc_static_pie(ElfW(Addr) load_addr) > PERFORM_BOOTSTRAP_GOT(tpnt); > #endif > > + DL_RELOCATE_RELR(tpnt); > > #if defined(ELF_MACHINE_PLTREL_OVERLAP) > # define INDX_MAX 1 > -- > 2.43.0 > > _______________________________________________ > devel mailing list -- devel@uclibc-ng.org > To unsubscribe send an email to devel-le...@uclibc-ng.org > _______________________________________________ devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-le...@uclibc-ng.org