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