Hi Alexey,
On Wed, Apr 9, 2025 at 4:59 PM Alexey Lapshin <alexey.lapshin@espressif.com>
wrote:
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index ec254915c76..b9b0001f3f9 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -960,6 +960,168 @@ static reloc_howto_type howto_table_internal[] =
> false), /* pcrel_offset */
> };
>
> +/* This howto table is used solely to provide relocation name strings. */
> +static reloc_howto_type howto_table_vendor[] = {
> + HOWTO (R_RISCV_CUSTOM0, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM0", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM1, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM1", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM2, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM2", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM3, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM3", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM4, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM4", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM5, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM5", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM6, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM6", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM7, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM7", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM8, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM8", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM9, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM9", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM10, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM10", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM11, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM11", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM12, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM12", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM13, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM13", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM14, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM14", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM15, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM15", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM16, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM16", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM17, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM17", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM18, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM18", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM19, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM19", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM20, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM20", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM21, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM21", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM22, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM22", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM23, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM23", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM24, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM24", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM25, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM25", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM26, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM26", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM27, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM27", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM28, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM28", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM29, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM29", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM30, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM30", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM31, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM31", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM32, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM32", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM33, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM33", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM34, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM34", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM35, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM35", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM36, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM36", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM37, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM37", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM38, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM38", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM39, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM39", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM40, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM40", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM41, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM41", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM42, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM42", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM43, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM43", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM44, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM44", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM45, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM45", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM46, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM46", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM47, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM47", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM48, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM48", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM49, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM49", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM50, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM50", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM51, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM51", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM52, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM52", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM53, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM53", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM54, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM54", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM55, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM55", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM56, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM56", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM57, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM57", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM58, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM58", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM59, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM59", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM60, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM60", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM61, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM61", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM62, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM62", false, 0, 0, false),
> + HOWTO (R_RISCV_CUSTOM63, 0, 0, 0, false, 0, complain_overflow_dont,
> + bfd_elf_generic_reloc, "R_RISCV_CUSTOM63", false, 0, 0, false)
> +};
>
I think the above shouldn't be necessary. We already have howto_table and
howto_table_internal for standard cases, and you will add a howto_table_esp
for esp vendor, so could we try to do everything right in the
riscv_elf_rtype_to_howto? Which means let riscv_elf_rtype_to_howto choose
the right how_to tables, including vendors', which is the howto_table_esp
for you. It is similar to the riscv_all_supported_ext, which collects all
tables of extensions, so we may have a howto_tables to collect howto_table,
howto_table_internal and howto_table_esp, .... Then define an enum similar
to riscv_prefix_ext_class, which should be passed to
riscv_elf_rtype_to_howto, and then can get the right howto table from
howto_tables with the enum. We will parse the R_RISCV_VENDOR reloc first,
and then get the vendor id, so the vendor id can be mapped to the right
enum.
if (rtype == NULL)
> printf (_("unrecognized: %-7lx"), (unsigned long) type &
> 0xffffffff);
> else
> @@ -2500,6 +2510,7 @@ dump_relocations (Filedata * filedata,
> sec_name = printable_section_name_from_index
> (filedata, psym->st_shndx, NULL);
>
> + vendor_id = strdup(sec_name);
> print_symbol_name (22, sec_name);
> }
> else if (strtab == NULL)
> @@ -2512,6 +2523,7 @@ dump_relocations (Filedata * filedata,
> }
> else
> {
> + vendor_id = strdup(strtab + psym->st_name);
> print_symbol_name (22, strtab + psym->st_name);
> if (version_string)
> printf (sym_info == symbol_public ? "@@%s" : "@%s",
>
The other targets don't have vendor id, so probably can have a better way
to let only riscv do this.
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index 8485ad441f5..a63d4bb0f2e 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -734,6 +734,54 @@ riscv_target_format (void)
> return xlen == 64 ? "elf64-littleriscv" : "elf32-littleriscv";
> }
>
> +/* Insert R_RISCV_VENDOR relocation right before the custom relocation
> + * passed in fixP. */
> +static void
> +insert_vendor_relocation (fixS *fixP, segT target_seg, const char
> *vendor_id)
> +{
> + segT saved_seg;
> + symbolS *sym;
> + const flagword vendor_sym_flags = (BSF_NO_FLAGS | BSF_LOCAL);
> +
> + /* Check if the vendor ID symbol already exists. */
> + for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
> + {
> + /* Ensure we find a local symbol in the desired segment.
> + This prevents R_RISCV_VENDOR relocation against a global symbol
> + with the same name, if it exists. */
> + if (S_GET_SEGMENT (sym) == target_seg &&
> + symbol_get_bfdsym (sym)->flags == vendor_sym_flags &&
+ strcmp (S_GET_NAME (sym), vendor_id) == 0)
>
if (S_GET_SEGMENT (sym) == target_seg
&& symbol_get_bfdsym (sym)->flags == vendor_sym_flags
&& strcmp (S_GET_NAME (sym), vendor_id) == 0)
> + {
> + break; /* Symbol found. */
> + }
> + }
> +
> + /* If symbol does not exist, create a new one. */
> + if (sym == NULL)
> + {
> + sym = symbol_new (vendor_id, target_seg, &zero_address_frag, 0);
> + symbol_get_bfdsym (sym)->flags = vendor_sym_flags;
> + }
> +
> + /* Temporarily switch segment for fix_new(). */
> + saved_seg = now_seg;
> + now_seg = target_seg; /* Ensure fix_new_internal() uses the correct
> segment. */
> +
> + /* Insert the R_RISCV_VENDOR relocation. */
> + /* Since it's not possible to access the previous element in the fixup
> list,
> + it worked around by calling fix_at_start when 'where == 0'.
> + Otherwise, place the fix at 'where - 1' to ensure correct ordering of
> + R_RISCV_VENDOR and R_RISCV_CUSTOM. */
> + if (fixP->fx_where == 0)
> + fix_at_start (fixP->fx_frag, 4, sym, 0, false,
> BFD_RELOC_RISCV_VENDOR);
> + else
> + fix_new (fixP->fx_frag, fixP->fx_where - 1, 4, sym, 0, false,
> BFD_RELOC_RISCV_VENDOR);
>
I do not really understand the problem here. Why not just refer to how the
R_RISCV_RELAX insert? Just use the xmemdup to copy the fixup, and decide
the R_RISCV_VENDOR should be inserted into the current one or the copied
next one.
> 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
> @@ -95,15 +95,113 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
> RELOC_NUMBER (R_RISCV_TLSDESC_LOAD_LO12, 63)
> RELOC_NUMBER (R_RISCV_TLSDESC_ADD_LO12, 64)
> RELOC_NUMBER (R_RISCV_TLSDESC_CALL, 65)
> + /* update R_RISCV_internal_first if add new reloc. */
> +
> + /* Vendor-specific (nonstandard) relocations are defined here only to
> provide
> + string version names (in readelf). */
> + RELOC_NUMBER (R_RISCV_VENDOR, 191)
> + RELOC_NUMBER (R_RISCV_CUSTOM0, 192)
> + RELOC_NUMBER (R_RISCV_CUSTOM1, 193)
> + RELOC_NUMBER (R_RISCV_CUSTOM2, 194)
> + RELOC_NUMBER (R_RISCV_CUSTOM3, 195)
> + RELOC_NUMBER (R_RISCV_CUSTOM4, 196)
> + RELOC_NUMBER (R_RISCV_CUSTOM5, 197)
> + RELOC_NUMBER (R_RISCV_CUSTOM6, 198)
> + RELOC_NUMBER (R_RISCV_CUSTOM7, 199)
> + RELOC_NUMBER (R_RISCV_CUSTOM8, 200)
> + RELOC_NUMBER (R_RISCV_CUSTOM9, 201)
> + RELOC_NUMBER (R_RISCV_CUSTOM10, 202)
> + RELOC_NUMBER (R_RISCV_CUSTOM11, 203)
> + RELOC_NUMBER (R_RISCV_CUSTOM12, 204)
> + RELOC_NUMBER (R_RISCV_CUSTOM13, 205)
> + RELOC_NUMBER (R_RISCV_CUSTOM14, 206)
> + RELOC_NUMBER (R_RISCV_CUSTOM15, 207)
> + RELOC_NUMBER (R_RISCV_CUSTOM16, 208)
> + RELOC_NUMBER (R_RISCV_CUSTOM17, 209)
> + RELOC_NUMBER (R_RISCV_CUSTOM18, 210)
> + RELOC_NUMBER (R_RISCV_CUSTOM19, 211)
> + RELOC_NUMBER (R_RISCV_CUSTOM20, 212)
> + RELOC_NUMBER (R_RISCV_CUSTOM21, 213)
> + RELOC_NUMBER (R_RISCV_CUSTOM22, 214)
> + RELOC_NUMBER (R_RISCV_CUSTOM23, 215)
> + RELOC_NUMBER (R_RISCV_CUSTOM24, 216)
> + RELOC_NUMBER (R_RISCV_CUSTOM25, 217)
> + RELOC_NUMBER (R_RISCV_CUSTOM26, 218)
> + RELOC_NUMBER (R_RISCV_CUSTOM27, 219)
> + RELOC_NUMBER (R_RISCV_CUSTOM28, 220)
> + RELOC_NUMBER (R_RISCV_CUSTOM29, 221)
> + RELOC_NUMBER (R_RISCV_CUSTOM30, 222)
> + RELOC_NUMBER (R_RISCV_CUSTOM31, 223)
> + RELOC_NUMBER (R_RISCV_CUSTOM32, 224)
> + RELOC_NUMBER (R_RISCV_CUSTOM33, 225)
> + RELOC_NUMBER (R_RISCV_CUSTOM34, 226)
> + RELOC_NUMBER (R_RISCV_CUSTOM35, 227)
> + RELOC_NUMBER (R_RISCV_CUSTOM36, 228)
> + RELOC_NUMBER (R_RISCV_CUSTOM37, 229)
> + RELOC_NUMBER (R_RISCV_CUSTOM38, 230)
> + RELOC_NUMBER (R_RISCV_CUSTOM39, 231)
> + RELOC_NUMBER (R_RISCV_CUSTOM40, 232)
> + RELOC_NUMBER (R_RISCV_CUSTOM41, 233)
> + RELOC_NUMBER (R_RISCV_CUSTOM42, 234)
> + RELOC_NUMBER (R_RISCV_CUSTOM43, 235)
> + RELOC_NUMBER (R_RISCV_CUSTOM44, 236)
> + RELOC_NUMBER (R_RISCV_CUSTOM45, 237)
> + RELOC_NUMBER (R_RISCV_CUSTOM46, 238)
> + RELOC_NUMBER (R_RISCV_CUSTOM47, 239)
> + RELOC_NUMBER (R_RISCV_CUSTOM48, 240)
> + RELOC_NUMBER (R_RISCV_CUSTOM49, 241)
> + RELOC_NUMBER (R_RISCV_CUSTOM50, 242)
> + RELOC_NUMBER (R_RISCV_CUSTOM51, 243)
> + RELOC_NUMBER (R_RISCV_CUSTOM52, 244)
> + RELOC_NUMBER (R_RISCV_CUSTOM53, 245)
> + RELOC_NUMBER (R_RISCV_CUSTOM54, 246)
> + RELOC_NUMBER (R_RISCV_CUSTOM55, 247)
> + RELOC_NUMBER (R_RISCV_CUSTOM56, 248)
> + RELOC_NUMBER (R_RISCV_CUSTOM57, 249)
> + RELOC_NUMBER (R_RISCV_CUSTOM58, 250)
> + RELOC_NUMBER (R_RISCV_CUSTOM59, 251)
> + RELOC_NUMBER (R_RISCV_CUSTOM60, 252)
> + RELOC_NUMBER (R_RISCV_CUSTOM61, 253)
> + RELOC_NUMBER (R_RISCV_CUSTOM62, 254)
> + RELOC_NUMBER (R_RISCV_CUSTOM63, 255)
>
Likewise, these should be unnecessary.
> END_RELOC_NUMBERS (R_RISCV_max)
>
> /* Internal relocations used exclusively by the relaxation pass. */
> -#define R_RISCV_DELETE (R_RISCV_max)
> -#define R_RISCV_RVC_LUI (R_RISCV_max + 1)
> -#define R_RISCV_GPREL_I (R_RISCV_max + 2)
> -#define R_RISCV_GPREL_S (R_RISCV_max + 3)
> -#define R_RISCV_TPREL_I (R_RISCV_max + 4)
> -#define R_RISCV_TPREL_S (R_RISCV_max + 5)
> +#define R_RISCV_internal_first (R_RISCV_TLSDESC_CALL + 1)
> +#define R_RISCV_DELETE (R_RISCV_internal_first)
> +#define R_RISCV_RVC_LUI (R_RISCV_internal_first + 1)
> +#define R_RISCV_GPREL_I (R_RISCV_internal_first + 2)
> +#define R_RISCV_GPREL_S (R_RISCV_internal_first + 3)
> +#define R_RISCV_TPREL_I (R_RISCV_internal_first + 4)
> +#define R_RISCV_TPREL_S (R_RISCV_internal_first + 5)
In case one day the internal relocations may be overlapped with the vendor
stuff, I think we only need to define the R_RISCV_internal_first to 256
directly, after the end of vendor relocations.
Thanks
Nelson
@@ -5430,6 +5430,11 @@ enum bfd_reloc_code_real
BFD_RELOC_RISCV_32_PCREL,
BFD_RELOC_RISCV_SET_ULEB128,
BFD_RELOC_RISCV_SUB_ULEB128,
+ BFD_RELOC_RISCV_VENDOR,
+
+ /* RISC-V Vendor (Espressif) relocations. */
+ BFD_RELOC_RISCV_ESP_LP_OFFSET_9,
+ BFD_RELOC_RISCV_ESP_LP_OFFSET_12,
/* Renesas RL78 Relocations. */
BFD_RELOC_RL78_NEG8,
@@ -264,7 +264,27 @@ riscv_info_to_howto_rela (bfd *abfd,
arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
- cache_ptr->howto = riscv_elf_rtype_to_howto (abfd, ELFNN_R_TYPE (dst->r_info));
+ static enum elf_riscv_vendor_id vendor_id = R_RISCV_VENDOR_ID_NONE;
+ unsigned int r_type = ELFNN_R_TYPE (dst->r_info);
+
+ if (r_type > R_RISCV_VENDOR)
+ {
+ cache_ptr->howto =
+ riscv_elf_rtype_to_vendor_howto (abfd, r_type, vendor_id);
+ vendor_id = R_RISCV_VENDOR_ID_NONE;
+ return cache_ptr->howto != NULL;
+ }
+ else
+ vendor_id = R_RISCV_VENDOR_ID_NONE;
+
+ if (r_type == R_RISCV_VENDOR)
+ {
+ const char *sym_name = bfd_asymbol_name (*cache_ptr->sym_ptr_ptr);
+ if (sym_name != NULL)
+ vendor_id = riscv_elf_vendor_id_str_to_enum (sym_name);
+ }
+
+ cache_ptr->howto = riscv_elf_rtype_to_howto (abfd, r_type);
return cache_ptr->howto != NULL;
}
@@ -1772,6 +1792,38 @@ riscv_global_pointer_value (struct bfd_link_info *info)
return h->u.def.value + sec_addr (h->u.def.section);
}
+static bfd_reloc_status_type
+calculate_vendor_relocaton (const Elf_Internal_Rela *rel, bfd_vma *value,
+ enum elf_riscv_vendor_id vendor_id)
+{
+ bfd_vma v = *value;
+
+ switch (vendor_id)
+ {
+ case R_RISCV_VENDOR_ID_ESP: /* Espressif. */
+ switch (ELFNN_R_TYPE (rel->r_info))
+ {
+ case R_RISCV_ESP_LP_OFFSET_9:
+ if (!VALID_ESPPIE_LP_OFFSET_9 (v))
+ return bfd_reloc_overflow;
+ v = ENCODE_ESPPIE_LP_OFFSET_9 (v);
+ break;
+
+ case R_RISCV_ESP_LP_OFFSET_12:
+ if (!VALID_ESPPIE_LP_OFFSET_12 (v))
+ return bfd_reloc_overflow;
+ v = ENCODE_ESPPIE_LP_OFFSET_12 (v);
+ break;
+ }
+ break;
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ *value = v;
+ return bfd_reloc_ok;
+}
+
/* Emplace a static relocation. */
static bfd_reloc_status_type
@@ -1780,7 +1832,8 @@ perform_relocation (const reloc_howto_type *howto,
bfd_vma value,
asection *input_section,
bfd *input_bfd,
- bfd_byte *contents)
+ bfd_byte *contents,
+ enum elf_riscv_vendor_id vendor_id)
{
if (howto->pc_relative)
value -= sec_addr (input_section) + rel->r_offset;
@@ -1789,6 +1842,15 @@ perform_relocation (const reloc_howto_type *howto,
if (ELFNN_R_TYPE (rel->r_info) != R_RISCV_SUB_ULEB128)
value += rel->r_addend;
+ if (vendor_id != R_RISCV_VENDOR_ID_NONE)
+ {
+ bfd_reloc_status_type status =
+ calculate_vendor_relocaton (rel, &value, vendor_id);
+ if (status != bfd_reloc_ok)
+ return status;
+ goto finish_relocation;
+ }
+
switch (ELFNN_R_TYPE (rel->r_info))
{
case R_RISCV_HI20:
@@ -1944,6 +2006,8 @@ perform_relocation (const reloc_howto_type *howto,
return bfd_reloc_notsupported;
}
+finish_relocation:
+
bfd_vma word;
if (riscv_is_insn_reloc (howto))
word = riscv_get_insn (howto->bitsize, contents + rel->r_offset);
@@ -2166,7 +2230,7 @@ riscv_resolve_pcrel_lo_relocs (riscv_pcrel_relocs *p)
}
perform_relocation (r->howto, r->reloc, entry->value, r->input_section,
- input_bfd, r->contents);
+ input_bfd, r->contents, R_RISCV_VENDOR_ID_NONE);
/* The corresponding R_RISCV_GOT_PCREL_HI20 and R_RISCV_PCREL_HI20 are
converted to R_RISCV_HI20, so try to convert R_RISCV_PCREL_LO12_I/S
@@ -2241,6 +2305,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
bfd_vma uleb128_set_vma = 0;
Elf_Internal_Rela *uleb128_set_rel = NULL;
+ Elf_Internal_Rela *vendor_rel = NULL;
bool absolute;
if (!riscv_init_pcrel_relocs (&pcrel_relocs))
@@ -2260,10 +2325,45 @@ riscv_elf_relocate_section (bfd *output_bfd,
bool unresolved_reloc, is_ie = false, is_desc = false;
bfd_vma pc = sec_addr (input_section) + rel->r_offset;
int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
- reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
+ reloc_howto_type *howto;
const char *msg = NULL;
bool resolved_to_zero;
bool via_plt = false;
+ enum elf_riscv_vendor_id vendor_id = R_RISCV_VENDOR_ID_NONE;
+
+ if (vendor_rel == NULL)
+ howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
+ else
+ {
+ if (r_type <= R_RISCV_VENDOR)
+ {
+ _bfd_error_handler
+ (_
+ ("error: %pB: expected vendor-specific relocation (r_type 192..255) after R_RISCV_VENDOR(191); Got r_type %d"),
+ input_bfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ r_symndx = ELFNN_R_SYM (vendor_rel->r_info);
+ sym =
+ bfd_sym_from_r_symndx (&htab->elf.sym_cache, input_bfd, r_symndx);
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, NULL);
+ vendor_id = riscv_elf_vendor_id_str_to_enum (name);
+ if (vendor_id == R_RISCV_VENDOR_ID_NONE)
+ {
+ _bfd_error_handler
+ (_
+ ("error: %pB: vendor-specific (%s) relocations are not supported"),
+ input_bfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ howto =
+ riscv_elf_rtype_to_vendor_howto (input_bfd, r_type, vendor_id);
+ name = NULL;
+ vendor_rel = NULL;
+ }
if (howto == NULL)
continue;
@@ -2572,6 +2672,26 @@ riscv_elf_relocate_section (bfd *output_bfd,
&& h != NULL
&& h->plt.offset != MINUS_ONE);
+ /* Expected vendor-specific relocation if previous
+ type was R_RISCV_VENDOR. */
+ switch (vendor_id)
+ {
+ case R_RISCV_VENDOR_ID_ESP:
+ switch (r_type)
+ {
+ case R_RISCV_ESP_LP_OFFSET_9:
+ case R_RISCV_ESP_LP_OFFSET_12:
+ /* These require no special handling beyond perform_relocation. */
+ break;
+ default:
+ /* Unreachable: vendor_id was was validated earlier. */
+ BFD_ASSERT (false);
+ }
+ goto do_relocation;
+ default:
+ break;
+ }
+
switch (r_type)
{
case R_RISCV_NONE:
@@ -2599,6 +2719,10 @@ riscv_elf_relocate_section (bfd *output_bfd,
/* These require no special handling beyond perform_relocation. */
break;
+ case R_RISCV_VENDOR:
+ vendor_rel = rel;
+ continue;
+
case R_RISCV_SET_ULEB128:
if (uleb128_set_rel == NULL)
{
@@ -3169,8 +3293,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
do_relocation:
if (r == bfd_reloc_ok)
r = perform_relocation (howto, rel, relocation, input_section,
- input_bfd, contents);
-
+ input_bfd, contents, vendor_id);
/* We should have already detected the error and set message before.
If the error message isn't set since the linker runs out of memory
or we don't set it before, then we should set the default message
@@ -960,6 +960,168 @@ static reloc_howto_type howto_table_internal[] =
false), /* pcrel_offset */
};
+/* This howto table is used solely to provide relocation name strings. */
+static reloc_howto_type howto_table_vendor[] = {
+ HOWTO (R_RISCV_CUSTOM0, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM0", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM1, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM1", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM2, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM2", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM3, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM3", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM4, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM4", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM5, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM5", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM6, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM6", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM7, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM7", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM8, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM8", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM9, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM9", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM10, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM10", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM11, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM11", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM12, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM12", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM13, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM13", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM14, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM14", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM15, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM15", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM16, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM16", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM17, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM17", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM18, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM18", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM19, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM19", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM20, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM20", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM21, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM21", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM22, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM22", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM23, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM23", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM24, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM24", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM25, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM25", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM26, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM26", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM27, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM27", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM28, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM28", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM29, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM29", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM30, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM30", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM31, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM31", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM32, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM32", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM33, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM33", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM34, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM34", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM35, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM35", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM36, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM36", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM37, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM37", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM38, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM38", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM39, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM39", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM40, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM40", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM41, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM41", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM42, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM42", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM43, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM43", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM44, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM44", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM45, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM45", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM46, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM46", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM47, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM47", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM48, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM48", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM49, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM49", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM50, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM50", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM51, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM51", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM52, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM52", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM53, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM53", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM54, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM54", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM55, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM55", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM56, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM56", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM57, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM57", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM58, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM58", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM59, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM59", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM60, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM60", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM61, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM61", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM62, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM62", false, 0, 0, false),
+ HOWTO (R_RISCV_CUSTOM63, 0, 0, 0, false, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_RISCV_CUSTOM63", false, 0, 0, false)
+};
+
+static reloc_howto_type howto_table_esp[] =
+{
+ HOWTO (R_RISCV_ESP_LP_OFFSET_9, /* type */
+ 0, /* rightshift */
+ 4, /* size */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_RISCV_ESP_LP_OFFSET_9", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ ENCODE_ESPPIE_LP_OFFSET_9 (-1U), /* dst_mask */
+ true), /* pcrel_offset */
+ HOWTO (R_RISCV_ESP_LP_OFFSET_12, /* type */
+ 0, /* rightshift */
+ 4, /* size */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_RISCV_ESP_LP_OFFSET_12", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ ENCODE_ESPPIE_LP_OFFSET_12 (-1U), /* dst_mask */
+ true), /* pcrel_offset */
+};
+
/* A mapping from BFD reloc types to RISC-V ELF reloc types. */
struct elf_reloc_map
{
@@ -1022,6 +1184,54 @@ static const struct elf_reloc_map riscv_reloc_map[] =
{ BFD_RELOC_RISCV_SUB_ULEB128, R_RISCV_SUB_ULEB128 },
};
+static const reloc_howto_type howto_vendor = HOWTO (R_RISCV_VENDOR, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_RISCV_VENDOR", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false);
+
+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 },
+};
+
/* Given a BFD reloc type, return a howto structure. */
reloc_howto_type *
@@ -1034,6 +1244,14 @@ riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
if (riscv_reloc_map[i].bfd_val == code)
return &howto_table[(int) riscv_reloc_map[i].elf_val];
+ if (code == BFD_RELOC_RISCV_VENDOR)
+ return &howto_vendor;
+
+ /* Vendor-specific (Espressif) relocations. */
+ for (i = 0; i < ARRAY_SIZE (riscv_esp_reloc_map); i++)
+ if (riscv_esp_reloc_map[i].bfd_val == code)
+ return &howto_table_esp[(int) riscv_esp_reloc_map[i].elf_val - R_RISCV_CUSTOM0];
+
bfd_set_error (bfd_error_bad_value);
return NULL;
}
@@ -1047,6 +1265,10 @@ riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
return &howto_table[i];
+ for (i = 0; i < ARRAY_SIZE (howto_table_esp); i++)
+ if (howto_table_esp[i].name && strcasecmp (howto_table_esp[i].name, r_name) == 0)
+ return &howto_table_esp[i];
+
return NULL;
}
@@ -1055,8 +1277,10 @@ riscv_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
{
if (r_type < ARRAY_SIZE (howto_table))
return &howto_table[r_type];
- else if (r_type < R_RISCV_max + ARRAY_SIZE (howto_table_internal))
- return &howto_table_internal[r_type - R_RISCV_max];
+ else if (r_type < R_RISCV_internal_first + ARRAY_SIZE (howto_table_internal))
+ return &howto_table_internal[r_type - R_RISCV_internal_first];
+ else if (r_type == R_RISCV_VENDOR)
+ return &howto_vendor;
else
{
(*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
@@ -1066,6 +1290,19 @@ riscv_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
}
}
+reloc_howto_type *
+riscv_elf_rtype_to_vendor_howto (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
+ enum elf_riscv_vendor_id vendor_id)
+{
+ switch (vendor_id)
+ {
+ case R_RISCV_VENDOR_ID_ESP:
+ return &howto_table_esp[r_type - R_RISCV_CUSTOM0];
+ default:
+ return &howto_table_vendor[r_type - R_RISCV_CUSTOM0];
+ }
+}
+
/* Special_function of RISCV_ADD and RISCV_SUB relocations. */
static bfd_reloc_status_type
@@ -1523,6 +1760,7 @@ static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
{"xsfvqmaccqoq", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
{"xsfvqmaccdod", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
{"xsfvfnrclipxfqf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
+ {"xesplp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
{NULL, 0, 0, 0, 0}
};
@@ -2863,6 +3101,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "xsfvqmaccdod");
case INSN_CLASS_XSFVFNRCLIPXFQF:
return riscv_subset_supports (rps, "xsfvfnrclipxfqf");
+ case INSN_CLASS_XESPLP:
+ return riscv_subset_supports (rps, "xesplp");
default:
rps->error_handler
(_("internal: unreachable INSN_CLASS_*"));
@@ -3162,6 +3402,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "xtheadzvamo";
case INSN_CLASS_XSFCEASE:
return "xsfcease";
+ case INSN_CLASS_XESPLP:
+ return "xesplp";
default:
rps->error_handler
(_("internal: unreachable INSN_CLASS_*"));
@@ -40,6 +40,9 @@ extern void riscv_elf32_set_options (struct bfd_link_info *,
extern void riscv_elf64_set_options (struct bfd_link_info *,
struct riscv_elf_params *);
+extern enum elf_riscv_vendor_id
+riscv_elf_vendor_id_str_to_enum(const char *id_str);
+
extern reloc_howto_type *
riscv_reloc_name_lookup (bfd *, const char *);
@@ -49,6 +52,9 @@ riscv_reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
extern reloc_howto_type *
riscv_elf_rtype_to_howto (bfd *, unsigned int r_type);
+extern reloc_howto_type *
+riscv_elf_rtype_to_vendor_howto (bfd *, unsigned int, enum elf_riscv_vendor_id);
+
/* The information of architecture attribute. */
struct riscv_subset_t
{
@@ -2467,6 +2467,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_RISCV_32_PCREL",
"BFD_RELOC_RISCV_SET_ULEB128",
"BFD_RELOC_RISCV_SUB_ULEB128",
+ "BFD_RELOC_RISCV_VENDOR",
+ "BFD_RELOC_RISCV_ESP_LP_OFFSET_9",
+ "BFD_RELOC_RISCV_ESP_LP_OFFSET_12",
"BFD_RELOC_RL78_NEG8",
"BFD_RELOC_RL78_NEG16",
"BFD_RELOC_RL78_NEG24",
@@ -5036,9 +5036,18 @@ ENUMX
BFD_RELOC_RISCV_SET_ULEB128
ENUMX
BFD_RELOC_RISCV_SUB_ULEB128
+ENUMX
+ BFD_RELOC_RISCV_VENDOR
ENUMDOC
RISC-V relocations.
+ENUM
+ BFD_RELOC_RISCV_ESP_LP_OFFSET_9
+ENUMX
+ BFD_RELOC_RISCV_ESP_LP_OFFSET_12
+ENUMDOC
+ RISC-V Vendor (Espressif) relocations.
+
ENUM
BFD_RELOC_RL78_NEG8
ENUMX
@@ -1967,6 +1967,7 @@ dump_relocations (Filedata * filedata,
size_t i;
Elf_Internal_Rela * rels;
bool res = true;
+ char *vendor_id = NULL;
if (rel_type == reltype_unknown)
rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
@@ -2197,7 +2198,10 @@ dump_relocations (Filedata * filedata,
break;
case EM_RISCV:
- rtype = elf_riscv_reloc_type (type);
+ if (vendor_id)
+ rtype = elf_riscv_vendor_reloc_type (vendor_id, type);
+ else
+ rtype = elf_riscv_reloc_type (type);
break;
case EM_ALPHA:
@@ -2397,6 +2401,12 @@ dump_relocations (Filedata * filedata,
break;
}
+ if (vendor_id)
+ {
+ free(vendor_id);
+ vendor_id = NULL;
+ }
+
if (rtype == NULL)
printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
else
@@ -2500,6 +2510,7 @@ dump_relocations (Filedata * filedata,
sec_name = printable_section_name_from_index
(filedata, psym->st_shndx, NULL);
+ vendor_id = strdup(sec_name);
print_symbol_name (22, sec_name);
}
else if (strtab == NULL)
@@ -2512,6 +2523,7 @@ dump_relocations (Filedata * filedata,
}
else
{
+ vendor_id = strdup(strtab + psym->st_name);
print_symbol_name (22, strtab + psym->st_name);
if (version_string)
printf (sym_info == symbol_public ? "@@%s" : "@%s",
@@ -734,6 +734,54 @@ riscv_target_format (void)
return xlen == 64 ? "elf64-littleriscv" : "elf32-littleriscv";
}
+/* Insert R_RISCV_VENDOR relocation right before the custom relocation
+ * passed in fixP. */
+static void
+insert_vendor_relocation (fixS *fixP, segT target_seg, const char *vendor_id)
+{
+ segT saved_seg;
+ symbolS *sym;
+ const flagword vendor_sym_flags = (BSF_NO_FLAGS | BSF_LOCAL);
+
+ /* Check if the vendor ID symbol already exists. */
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ {
+ /* Ensure we find a local symbol in the desired segment.
+ This prevents R_RISCV_VENDOR relocation against a global symbol
+ with the same name, if it exists. */
+ if (S_GET_SEGMENT (sym) == target_seg &&
+ symbol_get_bfdsym (sym)->flags == vendor_sym_flags &&
+ strcmp (S_GET_NAME (sym), vendor_id) == 0)
+ {
+ break; /* Symbol found. */
+ }
+ }
+
+ /* If symbol does not exist, create a new one. */
+ if (sym == NULL)
+ {
+ sym = symbol_new (vendor_id, target_seg, &zero_address_frag, 0);
+ symbol_get_bfdsym (sym)->flags = vendor_sym_flags;
+ }
+
+ /* Temporarily switch segment for fix_new(). */
+ saved_seg = now_seg;
+ now_seg = target_seg; /* Ensure fix_new_internal() uses the correct segment. */
+
+ /* Insert the R_RISCV_VENDOR relocation. */
+ /* Since it's not possible to access the previous element in the fixup list,
+ it worked around by calling fix_at_start when 'where == 0'.
+ Otherwise, place the fix at 'where - 1' to ensure correct ordering of
+ R_RISCV_VENDOR and R_RISCV_CUSTOM. */
+ if (fixP->fx_where == 0)
+ fix_at_start (fixP->fx_frag, 4, sym, 0, false, BFD_RELOC_RISCV_VENDOR);
+ else
+ fix_new (fixP->fx_frag, fixP->fx_where - 1, 4, sym, 0, false, BFD_RELOC_RISCV_VENDOR);
+
+ /* Restore the previous segment. */
+ now_seg = saved_seg;
+}
+
/* Return the length of instruction INSN. */
static inline unsigned int
@@ -1752,6 +1800,39 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
goto unknown_validate_operand;
}
break;
+ case 'e':
+ switch (*++oparg)
+ {
+ case 'l':
+ switch (*++oparg)
+ {
+ case 'c': used_bits |= ENCODE_ESPPIE_LP_COUNT (-1U); break; /* Xelc */
+ case 'i': used_bits |= ENCODE_ESPPIE_LP_ID (-1U); break; /* Xeli */
+ case 'o':
+ switch (*++oparg)
+ {
+ case '1':
+ switch (*++oparg)
+ {
+ case '2': used_bits |= ENCODE_ESPPIE_LP_OFFSET_12 (-1U); break; /* Xelo12 */
+ default: /* Xelo1[.] */
+ goto unknown_validate_operand;
+ }
+ break;
+ case '9': used_bits |= ENCODE_ESPPIE_LP_OFFSET_9 (-1U); break; /* Xelo9 */
+ default: /* Xelo[.] */
+ goto unknown_validate_operand;
+ }
+ break;
+ default: /* Xel[.] */
+ goto unknown_validate_operand;
+ }
+ break;
+ default: /* Xe[.] */
+ goto unknown_validate_operand;
+ }
+ break;
+
default:
goto unknown_validate_operand;
}
@@ -4173,6 +4254,80 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
#undef ENCODE_UIMM_BIT_FIELD
break;
+ case 'e': /* Vendor-specific (Espressif) operands. */
+ switch (*++oparg)
+ {
+ case 'l': /* Xesplp extension operands. */
+ switch (*++oparg)
+ {
+ case 'c': /* Xelc */
+ if (my_getSmallExpression
+ (imm_expr, imm_reloc, asarg, p)
+ || imm_expr->X_op != O_constant
+ || imm_expr->X_add_number > 4095
+ || imm_expr->X_add_number < 0
+ || !VALID_ESPPIE_LP_COUNT (imm_expr->
+ X_add_number))
+ {
+ as_bad (_("bad value for lp_count, "
+ "must be in range 0..4095 with step 1"));
+ break;
+ }
+ ip->insn_opcode |=
+ ENCODE_ESPPIE_LP_COUNT (imm_expr->X_add_number);
+ esp_imm_done:
+ asarg = expr_parse_end;
+ imm_expr->X_op = O_absent;
+ continue;
+ case 'i': /* Xeli */
+ if (my_getSmallExpression
+ (imm_expr, imm_reloc, asarg, p)
+ || imm_expr->X_op != O_constant
+ || imm_expr->X_add_number > 1
+ || imm_expr->X_add_number < 0
+ || !VALID_ESPPIE_LP_ID (imm_expr->X_add_number))
+ {
+ as_bad (_("bad value for lp_id, "
+ "must be in range 0..1 with step 1"));
+ break;
+ }
+ ip->insn_opcode |=
+ ENCODE_ESPPIE_LP_ID (imm_expr->X_add_number);
+ goto esp_imm_done;
+ case 'o':
+ switch (*++oparg)
+ {
+ case '1':
+ switch (*++oparg)
+ {
+ case '2': /* Xelo12 */
+ my_getExpression (imm_expr, asarg);
+ *imm_reloc =
+ BFD_RELOC_RISCV_ESP_LP_OFFSET_12;
+ asarg = expr_parse_end;
+ continue;
+ default: /* Xelo1[.] */
+ goto unknown_riscv_ip_operand;
+ }
+ break;
+ case '9': /* Xelo9 */
+ my_getExpression (imm_expr, asarg);
+ *imm_reloc = BFD_RELOC_RISCV_ESP_LP_OFFSET_9;
+ asarg = expr_parse_end;
+ continue;
+ default: /* Xelo[.] */
+ goto unknown_riscv_ip_operand;
+ }
+ break;
+ default: /* Xel[.] */
+ goto unknown_riscv_ip_operand;
+ }
+ break;
+ default: /* Xe[.] */
+ goto unknown_riscv_ip_operand;
+ }
+ break;
+
default:
goto unknown_riscv_ip_operand;
}
@@ -4855,6 +5010,43 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
case BFD_RELOC_RISCV_ALIGN:
break;
+ case BFD_RELOC_RISCV_VENDOR:
+ break;
+
+ case BFD_RELOC_RISCV_ESP_LP_OFFSET_9:
+ if (fixP->fx_addsy)
+ {
+ /* Fill in a tentative value to improve objdump readability. */
+ bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
+ bfd_vma delta = target - md_pcrel_from (fixP);
+ if (!VALID_ESPPIE_LP_OFFSET_9 (delta))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("bad value for lp_offset_9, must be in range 0..1022 with step 2"));
+ bfd_putl32 (bfd_getl32 (buf) | ENCODE_ESPPIE_LP_OFFSET_9 (delta), buf);
+ if (!riscv_opts.relax)
+ fixP->fx_done = 1;
+ }
+ if (!fixP->fx_done)
+ insert_vendor_relocation(fixP, seg, R_RISCV_ESPRESSIF_VENDOR_ID_STR);
+ break;
+
+ case BFD_RELOC_RISCV_ESP_LP_OFFSET_12:
+ if (fixP->fx_addsy)
+ {
+ /* Fill in a tentative value to improve objdump readability. */
+ bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
+ bfd_vma delta = target - md_pcrel_from (fixP);
+ if (!VALID_ESPPIE_LP_OFFSET_12 (delta))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("bad value for lp_offset_12, must be in range 0..8190 with step 2"));
+ bfd_putl32 (bfd_getl32 (buf) | ENCODE_ESPPIE_LP_OFFSET_12 (delta), buf);
+ if (!riscv_opts.relax)
+ fixP->fx_done = 1;
+ }
+ if (!fixP->fx_done)
+ insert_vendor_relocation(fixP, seg, R_RISCV_ESPRESSIF_VENDOR_ID_STR);
+ break;
+
default:
/* We ignore generic BFD relocations we don't know about. */
if (bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type) != NULL)
@@ -173,3 +173,4 @@ All available -march extensions for RISC-V:
xsfvqmaccqoq 1.0
xsfvqmaccdod 1.0
xsfvfnrclipxfqf 1.0
+ xesplp 1.0
new file mode 100644
@@ -0,0 +1,12 @@
+#as: -march=rv32ic_xesplp10
+#source: xesplp-reloc.s
+#objdump: -r
+
+.*:[ ]+file format .*
+
+RELOCATION RECORDS FOR .*
+.*
+0+0 R_RISCV_VENDOR[ ]+esp
+0+0 R_RISCV_ESP_LP_OFFSET_12.*
+0+3 R_RISCV_VENDOR[ ]+esp
+0+4 R_RISCV_ESP_LP_OFFSET_9.*
new file mode 100644
@@ -0,0 +1,7 @@
+ .global _start
+ .type _start, @function
+_start:
+ esp.lp.setup 0,t0,last_inst + 4
+ esp.lp.setupi 0,4,last_inst - 4
+last_inst:
+ nop
@@ -95,15 +95,113 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
RELOC_NUMBER (R_RISCV_TLSDESC_LOAD_LO12, 63)
RELOC_NUMBER (R_RISCV_TLSDESC_ADD_LO12, 64)
RELOC_NUMBER (R_RISCV_TLSDESC_CALL, 65)
+ /* update R_RISCV_internal_first if add new reloc. */
+
+ /* Vendor-specific (nonstandard) relocations are defined here only to provide
+ string version names (in readelf). */
+ RELOC_NUMBER (R_RISCV_VENDOR, 191)
+ RELOC_NUMBER (R_RISCV_CUSTOM0, 192)
+ RELOC_NUMBER (R_RISCV_CUSTOM1, 193)
+ RELOC_NUMBER (R_RISCV_CUSTOM2, 194)
+ RELOC_NUMBER (R_RISCV_CUSTOM3, 195)
+ RELOC_NUMBER (R_RISCV_CUSTOM4, 196)
+ RELOC_NUMBER (R_RISCV_CUSTOM5, 197)
+ RELOC_NUMBER (R_RISCV_CUSTOM6, 198)
+ RELOC_NUMBER (R_RISCV_CUSTOM7, 199)
+ RELOC_NUMBER (R_RISCV_CUSTOM8, 200)
+ RELOC_NUMBER (R_RISCV_CUSTOM9, 201)
+ RELOC_NUMBER (R_RISCV_CUSTOM10, 202)
+ RELOC_NUMBER (R_RISCV_CUSTOM11, 203)
+ RELOC_NUMBER (R_RISCV_CUSTOM12, 204)
+ RELOC_NUMBER (R_RISCV_CUSTOM13, 205)
+ RELOC_NUMBER (R_RISCV_CUSTOM14, 206)
+ RELOC_NUMBER (R_RISCV_CUSTOM15, 207)
+ RELOC_NUMBER (R_RISCV_CUSTOM16, 208)
+ RELOC_NUMBER (R_RISCV_CUSTOM17, 209)
+ RELOC_NUMBER (R_RISCV_CUSTOM18, 210)
+ RELOC_NUMBER (R_RISCV_CUSTOM19, 211)
+ RELOC_NUMBER (R_RISCV_CUSTOM20, 212)
+ RELOC_NUMBER (R_RISCV_CUSTOM21, 213)
+ RELOC_NUMBER (R_RISCV_CUSTOM22, 214)
+ RELOC_NUMBER (R_RISCV_CUSTOM23, 215)
+ RELOC_NUMBER (R_RISCV_CUSTOM24, 216)
+ RELOC_NUMBER (R_RISCV_CUSTOM25, 217)
+ RELOC_NUMBER (R_RISCV_CUSTOM26, 218)
+ RELOC_NUMBER (R_RISCV_CUSTOM27, 219)
+ RELOC_NUMBER (R_RISCV_CUSTOM28, 220)
+ RELOC_NUMBER (R_RISCV_CUSTOM29, 221)
+ RELOC_NUMBER (R_RISCV_CUSTOM30, 222)
+ RELOC_NUMBER (R_RISCV_CUSTOM31, 223)
+ RELOC_NUMBER (R_RISCV_CUSTOM32, 224)
+ RELOC_NUMBER (R_RISCV_CUSTOM33, 225)
+ RELOC_NUMBER (R_RISCV_CUSTOM34, 226)
+ RELOC_NUMBER (R_RISCV_CUSTOM35, 227)
+ RELOC_NUMBER (R_RISCV_CUSTOM36, 228)
+ RELOC_NUMBER (R_RISCV_CUSTOM37, 229)
+ RELOC_NUMBER (R_RISCV_CUSTOM38, 230)
+ RELOC_NUMBER (R_RISCV_CUSTOM39, 231)
+ RELOC_NUMBER (R_RISCV_CUSTOM40, 232)
+ RELOC_NUMBER (R_RISCV_CUSTOM41, 233)
+ RELOC_NUMBER (R_RISCV_CUSTOM42, 234)
+ RELOC_NUMBER (R_RISCV_CUSTOM43, 235)
+ RELOC_NUMBER (R_RISCV_CUSTOM44, 236)
+ RELOC_NUMBER (R_RISCV_CUSTOM45, 237)
+ RELOC_NUMBER (R_RISCV_CUSTOM46, 238)
+ RELOC_NUMBER (R_RISCV_CUSTOM47, 239)
+ RELOC_NUMBER (R_RISCV_CUSTOM48, 240)
+ RELOC_NUMBER (R_RISCV_CUSTOM49, 241)
+ RELOC_NUMBER (R_RISCV_CUSTOM50, 242)
+ RELOC_NUMBER (R_RISCV_CUSTOM51, 243)
+ RELOC_NUMBER (R_RISCV_CUSTOM52, 244)
+ RELOC_NUMBER (R_RISCV_CUSTOM53, 245)
+ RELOC_NUMBER (R_RISCV_CUSTOM54, 246)
+ RELOC_NUMBER (R_RISCV_CUSTOM55, 247)
+ RELOC_NUMBER (R_RISCV_CUSTOM56, 248)
+ RELOC_NUMBER (R_RISCV_CUSTOM57, 249)
+ RELOC_NUMBER (R_RISCV_CUSTOM58, 250)
+ RELOC_NUMBER (R_RISCV_CUSTOM59, 251)
+ RELOC_NUMBER (R_RISCV_CUSTOM60, 252)
+ RELOC_NUMBER (R_RISCV_CUSTOM61, 253)
+ RELOC_NUMBER (R_RISCV_CUSTOM62, 254)
+ RELOC_NUMBER (R_RISCV_CUSTOM63, 255)
END_RELOC_NUMBERS (R_RISCV_max)
/* Internal relocations used exclusively by the relaxation pass. */
-#define R_RISCV_DELETE (R_RISCV_max)
-#define R_RISCV_RVC_LUI (R_RISCV_max + 1)
-#define R_RISCV_GPREL_I (R_RISCV_max + 2)
-#define R_RISCV_GPREL_S (R_RISCV_max + 3)
-#define R_RISCV_TPREL_I (R_RISCV_max + 4)
-#define R_RISCV_TPREL_S (R_RISCV_max + 5)
+#define R_RISCV_internal_first (R_RISCV_TLSDESC_CALL + 1)
+#define R_RISCV_DELETE (R_RISCV_internal_first)
+#define R_RISCV_RVC_LUI (R_RISCV_internal_first + 1)
+#define R_RISCV_GPREL_I (R_RISCV_internal_first + 2)
+#define R_RISCV_GPREL_S (R_RISCV_internal_first + 3)
+#define R_RISCV_TPREL_I (R_RISCV_internal_first + 4)
+#define R_RISCV_TPREL_S (R_RISCV_internal_first + 5)
+
+/* 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)
+
+#ifdef RELOC_MACROS_GEN_FUNC
+static const char *elf_riscv_vendor_reloc_type (const char *vendor, unsigned long rtype);
+static const char *
+elf_riscv_vendor_reloc_type (const char *vendor, unsigned long rtype)
+{
+ if (strcmp(vendor, R_RISCV_ESPRESSIF_VENDOR_ID_STR) == 0)
+ {
+ return elf_riscv_esp_reloc_type(rtype);
+ }
+ return elf_riscv_reloc_type(rtype);
+}
+#endif /* RELOC_MACROS_GEN_FUNC */
/* Processor specific flags for the ELF header e_flags field. */
@@ -3804,6 +3804,19 @@
#define MASK_SFVFNRCLIPXUFQF 0xfe00707f
#define MATCH_SFVFNRCLIPXFQF 0x8e00505b
#define MASK_SFVFNRCLIPXFQF 0xfe00707f
+/* Vendor-specific (Espressif) hardware loop instructions. */
+#define MATCH_ESP_LP_COUNT 0x202b
+#define MASK_ESP_LP_COUNT 0xfff07f7f
+#define MATCH_ESP_LP_COUNTI 0x302b
+#define MASK_ESP_LP_COUNTI 0xfff7f
+#define MATCH_ESP_LP_ENDI 0x102b
+#define MASK_ESP_LP_ENDI 0xfff7f
+#define MATCH_ESP_LP_SETUP 0x402b
+#define MASK_ESP_LP_SETUP 0x7f7f
+#define MATCH_ESP_LP_SETUPI 0x502b
+#define MASK_ESP_LP_SETUPI 0x707f
+#define MATCH_ESP_LP_STARTI 0x2b
+#define MASK_ESP_LP_STARTI 0xfff7f
/* Unprivileged Counter/Timers CSR addresses. */
#define CSR_CYCLE 0xc00
#define CSR_TIME 0xc01
@@ -4934,6 +4947,13 @@ DECLARE_INSN(th_sync_s, MATCH_TH_SYNC_S, MASK_TH_SYNC_S)
/* XVentanaCondOps instructions. */
DECLARE_INSN(vt_maskc, MATCH_VT_MASKC, MASK_VT_MASKC)
DECLARE_INSN(vt_maskcn, MATCH_VT_MASKCN, MASK_VT_MASKCN)
+/* Vendor-specific (Espressif) Xesplp instructions. */
+DECLARE_INSN(esp_lp_count, MATCH_ESP_LP_COUNT, MASK_ESP_LP_COUNT)
+DECLARE_INSN(esp_lp_counti, MATCH_ESP_LP_COUNTI, MASK_ESP_LP_COUNTI)
+DECLARE_INSN(esp_lp_endi, MATCH_ESP_LP_ENDI, MASK_ESP_LP_ENDI)
+DECLARE_INSN(esp_lp_setup, MATCH_ESP_LP_SETUP, MASK_ESP_LP_SETUP)
+DECLARE_INSN(esp_lp_setupi, MATCH_ESP_LP_SETUPI, MASK_ESP_LP_SETUPI)
+DECLARE_INSN(esp_lp_starti, MATCH_ESP_LP_STARTI, MASK_ESP_LP_STARTI)
/* Zicfiss instructions. */
DECLARE_INSN(sspush, MATCH_SSPUSH, MASK_SSPUSH)
@@ -132,6 +132,15 @@ static inline unsigned int riscv_insn_length (insn_t insn)
((RV_X(x, 25, 1)) | (RV_X(x, 20, 5) << 1) | (RV_IMM_SIGN_N(x, 20, 5) << 5))
#define EXTRACT_CV_SIMD_UIMM6(x) \
((RV_X(x, 25, 1)) | (RV_X(x, 20, 5) << 1))
+/* Vendor-specific (Espressif) extract macros. */
+#define EXTRACT_ESPPIE_LP_COUNT(x) \
+ (RV_X(x, 20, 12))
+#define EXTRACT_ESPPIE_LP_ID(x) \
+ (RV_X(x, 7, 1))
+#define EXTRACT_ESPPIE_LP_OFFSET_12(x) \
+ (RV_X(x, 20, 12) << 1)
+#define EXTRACT_ESPPIE_LP_OFFSET_9(x) \
+ ((RV_X(x, 15, 5) << 1) | (RV_X(x, 8, 4) << 6))
#define ENCODE_ITYPE_IMM(x) \
(RV_X(x, 0, 12) << 20)
@@ -200,6 +209,15 @@ static inline unsigned int riscv_insn_length (insn_t insn)
((RV_X(x, 0, 1) << 25) | (RV_X(x, 1, 5) << 20))
#define ENCODE_CV_SIMD_UIMM6(x) \
((RV_X(x, 0, 1) << 25) | (RV_X(x, 1, 5) << 20))
+/* Vendor-specific (Espressif) encode macros. */
+#define ENCODE_ESPPIE_LP_COUNT(x) \
+ (RV_X(x, 0, 12) << 20)
+#define ENCODE_ESPPIE_LP_ID(x) \
+ (RV_X(x, 0, 1) << 7)
+#define ENCODE_ESPPIE_LP_OFFSET_12(x) \
+ (RV_X(x, 1, 12) << 20)
+#define ENCODE_ESPPIE_LP_OFFSET_9(x) \
+ ((RV_X(x, 1, 5) << 15) | (RV_X(x, 6, 4) << 8))
#define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x))
#define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x))
@@ -228,6 +246,11 @@ static inline unsigned int riscv_insn_length (insn_t insn)
#define VALID_ZCB_BYTE_UIMM(x) (EXTRACT_ZCB_BYTE_UIMM(ENCODE_ZCB_BYTE_UIMM(x)) == (x))
#define VALID_ZCB_HALFWORD_UIMM(x) (EXTRACT_ZCB_HALFWORD_UIMM(ENCODE_ZCB_HALFWORD_UIMM(x)) == (x))
#define VALID_ZCMP_SPIMM(x) (EXTRACT_ZCMP_SPIMM(ENCODE_ZCMP_SPIMM(x)) == (x))
+/* Vendor-specific (Espressif) validation macros. */
+#define VALID_ESPPIE_LP_COUNT(x) (EXTRACT_ESPPIE_LP_COUNT(ENCODE_ESPPIE_LP_COUNT(x)) == (x))
+#define VALID_ESPPIE_LP_ID(x) (EXTRACT_ESPPIE_LP_ID(ENCODE_ESPPIE_LP_ID(x)) == (x))
+#define VALID_ESPPIE_LP_OFFSET_12(x) (EXTRACT_ESPPIE_LP_OFFSET_12(ENCODE_ESPPIE_LP_OFFSET_12(x)) == (x))
+#define VALID_ESPPIE_LP_OFFSET_9(x) (EXTRACT_ESPPIE_LP_OFFSET_9(ENCODE_ESPPIE_LP_OFFSET_9(x)) == (x))
#define RISCV_RTYPE(insn, rd, rs1, rs2) \
((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2))
@@ -563,6 +586,7 @@ enum riscv_insn_class
INSN_CLASS_XSFVQMACCQOQ,
INSN_CLASS_XSFVQMACCDOD,
INSN_CLASS_XSFVFNRCLIPXFQF,
+ INSN_CLASS_XESPLP,
};
/* This structure holds information for a particular instruction. */
@@ -179,6 +179,8 @@ if [istarget "riscv*-*-*"] {
"-march=rv64i -mabi=lp64" {weakref64.s} \
{{objdump -d weakref64.d}} "weakref64"]]
+ run_dump_test "xesplp-reloc"
+
# The following tests require shared library support.
if ![check_shared_lib_support] {
return
new file mode 100644
@@ -0,0 +1,13 @@
+#source: xesplp-reloc.s
+#as: -march=rv32i_xesplp
+#ld:
+#objdump: -d
+
+#...
+Disassembly of section .text:
+#...
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+esp.lp.setup[ ]+.*<last_inst\+0x4>
+.*:[ ]+[0-9a-f]+[ ]+esp.lp.setupi[ ]+.*<_start\+0x4>
+0+[0-9a-f]+ <last_inst>:
+#...
new file mode 100644
@@ -0,0 +1,7 @@
+ .global _start
+ .type _start, @function
+_start:
+ esp.lp.setup 0,t0,last_inst + 4
+ esp.lp.setupi 0,4,last_inst - 4
+last_inst:
+ nop
@@ -880,6 +880,57 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
break;
}
break;
+ case 'e': /* Vendor-specific (Espressif) operands. */
+ switch (*++oparg)
+ {
+ case 'l': /* Xesplp extension operands. */
+ switch (*++oparg)
+ {
+ case 'c': /* Xelc */
+ print (info->stream, dis_style_immediate, "%d",
+ (int) EXTRACT_ESPPIE_LP_COUNT (l));
+ break; /* Xelc */
+ case 'i': /* Xeli */
+ print (info->stream, dis_style_immediate, "%d",
+ (int) EXTRACT_ESPPIE_LP_ID (l));
+ break; /* Xeli */
+ case 'o':
+ switch (*++oparg)
+ {
+ case '1':
+ switch (*++oparg)
+ {
+ case '2': /* Xelo12 */
+ maybe_print_address (pd, 0,
+ EXTRACT_ESPPIE_LP_OFFSET_12
+ (l) + pc, 0);
+ print (info->stream, dis_style_address_offset,
+ "%d",
+ (int) EXTRACT_ESPPIE_LP_OFFSET_12 (l));
+ break; /* Xelo12 */
+ default: /* Xelo1[.] */
+ goto undefined_modifier;
+ }
+ break;
+ case '9': /* Xelo9 */
+ maybe_print_address (pd, 0,
+ EXTRACT_ESPPIE_LP_OFFSET_9 (l)
+ + pc, 0);
+ print (info->stream, dis_style_address_offset, "%d",
+ (int) EXTRACT_ESPPIE_LP_OFFSET_9 (l));
+ break; /* Xelo9 */
+ default: /* Xelo[.] */
+ goto undefined_modifier;
+ }
+ break;
+ default: /* Xel[.] */
+ goto undefined_modifier;
+ }
+ break;
+ default: /* Xe[.] */
+ goto undefined_modifier;
+ }
+ break;
default:
goto undefined_modifier;
}
@@ -3522,6 +3522,14 @@ const struct riscv_opcode riscv_opcodes[] =
{"sf.vfnrclip.xu.f.qf", 0, INSN_CLASS_XSFVFNRCLIPXFQF, "Vd,Vt,S", MATCH_SFVFNRCLIPXUFQF, MASK_SFVFNRCLIPXUFQF, match_opcode, 0},
{"sf.vfnrclip.x.f.qf", 0, INSN_CLASS_XSFVFNRCLIPXFQF, "Vd,Vt,S", MATCH_SFVFNRCLIPXFQF, MASK_SFVFNRCLIPXFQF, match_opcode, 0},
+/* Vendor-specific (Espressif) hardware loop instructions (Xesplp). */
+{"esp.lp.setupi", 32, INSN_CLASS_XESPLP, "Xeli,Xelc,Xelo9", MATCH_ESP_LP_SETUPI, MASK_ESP_LP_SETUPI, match_opcode, 0 },
+{"esp.lp.setup", 32, INSN_CLASS_XESPLP, "Xeli,s,Xelo12", MATCH_ESP_LP_SETUP, MASK_ESP_LP_SETUP, match_opcode, 0 },
+{"esp.lp.starti", 32, INSN_CLASS_XESPLP, "Xeli,Xelo12", MATCH_ESP_LP_STARTI, MASK_ESP_LP_STARTI, match_opcode, 0 },
+{"esp.lp.endi", 32, INSN_CLASS_XESPLP, "Xeli,Xelo12", MATCH_ESP_LP_ENDI, MASK_ESP_LP_ENDI, match_opcode, 0 },
+{"esp.lp.counti", 32, INSN_CLASS_XESPLP, "Xeli,Xelc", MATCH_ESP_LP_COUNTI, MASK_ESP_LP_COUNTI, match_opcode, 0 },
+{"esp.lp.count", 32, INSN_CLASS_XESPLP, "Xeli,s", MATCH_ESP_LP_COUNT, MASK_ESP_LP_COUNT, match_opcode, 0 },
+
/* Terminate the list. */
{0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
};