[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