[PATCH] RISC-V: Add support for vendor-specific relocations
Alexey Lapshin
alexey.lapshin@espressif.com
Thu Apr 10 05:12:26 GMT 2025
Nelson, thank you for the suggestions! They are really helpful and will improve the code
The only thing should be reconsidered is:
> define the R_RISCV_internal_first to 256 directly, after the end of vendor relocations.
It seems having relocations with r_type greater than 255 is bad idea,
because it will be corrupted when passed to macro (masked by 0xff):
#define ELF32_R_INFO(s,t) (((unsigned) (s) << 8) + ((t) & 0xff))
I don't know why these 'internal' relocations were moved from elf_riscv_reloc_type
to another ID (and still have duplicate in elf_riscv_reloc_type),
but it looks like it's a 'postponed' issue to be resolved when most
relocation IDs are reserved.
Regards,
Alexey
On Thu, 2025-04-10 at 03:54 +0800, Nelson Chu wrote:
>
>
> You don't often get email from nelson@rivosinc.com.
> Learn why this is important
>
>
>
> [External: This email originated outside Espressif]
>
>
>
>
>
>
>
>
> On Wed, Apr 9, 2025 at 4:59 PM Alexey Lapshin <alexey.lapshin@espressif.com> wrote:
> > +struct elf_vendor_map
> > +{
> > + enum elf_riscv_vendor_id id;
> > + const char *id_str;
> > +};
> > +
> > +static const struct elf_vendor_map elf_riscv_vendor_map[] =
> > +{
> > + { R_RISCV_VENDOR_ID_ESP, R_RISCV_ESPRESSIF_VENDOR_ID_STR },
> > +};
> > +
> > +enum elf_riscv_vendor_id
> > +riscv_elf_vendor_id_str_to_enum(const char *id_str)
> > +{
> > + unsigned int i;
> > + for (i = 0; i < ARRAY_SIZE (elf_riscv_vendor_map); i++)
> > + if (strcmp(elf_riscv_vendor_map[i].id_str, id_str) == 0)
> > + return elf_riscv_vendor_map[i].id;
> > +
> > + return R_RISCV_VENDOR_ID_NONE;
> > +}
> > +
> > +struct elf_reloc_map_esp
> > +{
> > + bfd_reloc_code_real_type bfd_val;
> > + enum elf_riscv_esp_reloc_type elf_val;
> > +};
> > +
> > +static const struct elf_reloc_map_esp riscv_esp_reloc_map[] =
> > +{
> > + { BFD_RELOC_RISCV_ESP_LP_OFFSET_9, R_RISCV_ESP_LP_OFFSET_9 },
> > + { BFD_RELOC_RISCV_ESP_LP_OFFSET_12, R_RISCV_ESP_LP_OFFSET_12 },
> > +};
> >
>
>
> I forgot to mention this - could we just define these vendor mappings into elf_riscv_map, so...
>
> > diff --git a/include/elf/riscv.h b/include/elf/riscv.h
> > index 2ea1ae82eb6..0f3a5c4ded6 100644
> > --- a/include/elf/riscv.h
> > +++ b/include/elf/riscv.h
> > +
> > +/* Vendor specific relocations macro and structures. */
> > +#define R_RISCV_ESPRESSIF_VENDOR_ID_STR "esp"
> > +
> > +/* VENDOR IDs for internal usage. */
> > +enum elf_riscv_vendor_id {
> > + R_RISCV_VENDOR_ID_NONE = -1,
> > + R_RISCV_VENDOR_ID_ESP,
> > +};
> > +
> > +/* Vendor (Espressif) relocations. */
> > +START_RELOC_NUMBERS (elf_riscv_esp_reloc_type)
> > + RELOC_NUMBER (R_RISCV_ESP_LP_OFFSET_9, 192)
> > + RELOC_NUMBER (R_RISCV_ESP_LP_OFFSET_12, 193)
> > +END_RELOC_NUMBERS (R_RISCV_ESP_max)
> >
>
>
> ... We probably don't need to define so many elf_riscv_xxx_reloc_type for every vendor. I see MIPS and ARM had defined FAKE_RELOC for duplicate cases, not sure if that also works for risc-v vendor relocations. That is - could we define FAKE_RELOC (R_RISCV_vendor_begin) and FAKE_RELOC (R_RISCV_vendor_end), then define all vendor stuff between them?
>
> Thanks
> Nelson
More information about the Binutils
mailing list