Assuming we already have RELOCID in place:

There is a bool pretend_im_corev in gas/config/tc-riscv.c which sets the relocation as CORE-V. Then it gets checked and we set an ID for CORE-V (100):

if (pretend_im_corevid && fixP->fx_tcbit && fixP->fx_addsy != NULL)
{
fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
fixP->fx_next->fx_addsy = fixP->fx_next->fx_subsy = NULL;
// CUSTOM RELOC
fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_RELOCID;
fixP->fx_next->fx_size = 0;
// ID
fixP->fx_next->fx_offset = 100;
}

We then have a secondary howto table where the special_function is riscv_elf_custom_relocid, which should trigger perform_relocation. This function should handle the relocation as you can see:

static bfd_reloc_status_type
riscv_elf_custom_relocid (bfd *abfd,
       arelent *reloc_entry,
       asymbol *symbol,
       void *data,
       asection *input_section,
       bfd *output_bfd,
       char **error_message ATTRIBUTE_UNUSED)
       // do i need this?
       //bfd_vma value)
{
  reloc_howto_type *howto = reloc_entry->howto;
  bfd_vma relocation;
 
  if (output_bfd != NULL
      && (symbol->flags & BSF_SECTION_SYM) == 0
      && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
    {
      reloc_entry->address += input_section->output_offset;
            return bfd_reloc_ok;
    }
 
  if (output_bfd != NULL)
    return bfd_reloc_continue;
 
  relocation = symbol->value + symbol->section->output_section->vma
    + symbol->section->output_offset + reloc_entry->addend;
  bfd_vma old_value = bfd_get (howto->bitsize, abfd,
             data + reloc_entry->address);
 
  switch (howto->type)
    {
    case R_RISCV_CVPCREL_UI12:
      symbol->value = ENCODE_CV_HWLP_UIMM5(symbol->value >> howto->rightshift);
      break;
    }
  bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
 
  return bfd_reloc_ok;
}

Finally in bfd/elfnn-riscv.c we have:

/* Relocation handling prototype */
    case R_RISCV_RELOCID:
      switch (value) {
        case 100:
        //    ;
          return riscv_elf_custom_relocid(ELFNN_R_TYPE (rel->r_info));
        //return get_howto_from_table(&SECONDARYhowto_table, rel);
        //return bfd_reloc_ok;
        }
        break;

Which should link everything together, meaning it checks the ID in R_RISCV_RELOCID and calls the perform_relocation function, in our case riscv_elf_custom_relocid. This is the part where I am struggling :(

The error I am getting is:

nrun.o libsim.a ../../bfd/libbfd.a ../../opcodes/libopcodes.a  ../../libiberty/libiberty.a -lm -ldl -lnsl  -L../../zlib -lz   ../../gnulib/import/libgnu.a
../../bfd/libbfd.a(elf32-riscv.o): In function `perform_relocation':
/home/pietraferreira/corev/build/binutils-gdb/bfd/elfnn-riscv.c:1653: undefined reference to `riscv_elf_custom_relocid'
../../bfd/libbfd.a(elf64-riscv.o): In function `perform_relocation':
/home/pietraferreira/corev/build/binutils-gdb/bfd/elfnn-riscv.c:1653: undefined reference to `riscv_elf_custom_relocid'
collect2: error: ld returned 1 exit status