[PATCH] Finish fixing riscv gas lns-common-1 failure, and lns-duplicate.

Palmer Dabbelt palmer@sifive.com
Wed Nov 15 02:36:00 GMT 2017


On Tue, 14 Nov 2017 17:45:30 PST (-0800), Jim Wilson wrote:
> This is the second half of the fix for the riscv gas lns-common-1 failure, and
> also fixes lns-duplicate.  Because riscv has linker relaxations that delete
> code, we can't compute label subtractions until link time, and hence have
> relocs against eh and debug info sections that readelf needs to know about.
>
> This is a fair amount of new code for just one target, but I tried to add this
> in a general way that might be usable for other targets.
>
> I will also need some code for SET6 and SUB6 relocs, but I will worry about
> that later, as I'm not seeing any testsuite failures for them, so I don't
> have convenient testcases for them.
>
> Comments?

This is a whole lot better than how I tried to do it a few weeks ago :)

Thanks!

>
> 	binutils/
> 	* readelf.c (elf/riscv.h): Alphabetize include.
> 	(is_32bit_inplace_add_reloc, is_32bit_inplace_sub_reloc)
> 	(is_64bit_inplace_add_reloc, is_64bit_inplace_sub_reloc)
> 	(is_16bit_inplace_add_reloc, is_16bit_inplace_sub_reloc)
> 	(is_8bit_inplace_add_reloc, is_8bit_inplace_sub_reloc): New.
> 	(apply_relocations): New locals reloc_inplace and reloc_subtract.
> 	Call the new functions and set the new locals.  Call byte_get if
> 	reloc_inplace.  Subtract sym->st_value if reloc_subtract.
> ---
>  binutils/readelf.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 159 insertions(+), 2 deletions(-)
>
> diff --git a/binutils/readelf.c b/binutils/readelf.c
> index 5e7cbefbef..57de9a83c0 100644
> --- a/binutils/readelf.c
> +++ b/binutils/readelf.c
> @@ -124,7 +124,6 @@
>  #include "elf/metag.h"
>  #include "elf/microblaze.h"
>  #include "elf/mips.h"
> -#include "elf/riscv.h"
>  #include "elf/mmix.h"
>  #include "elf/mn10200.h"
>  #include "elf/mn10300.h"
> @@ -138,6 +137,7 @@
>  #include "elf/ppc.h"
>  #include "elf/ppc64.h"
>  #include "elf/pru.h"
> +#include "elf/riscv.h"
>  #include "elf/rl78.h"
>  #include "elf/rx.h"
>  #include "elf/s390.h"
> @@ -12550,6 +12550,134 @@ is_16bit_abs_reloc (unsigned int reloc_type)
>      }
>  }
>
> +/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
> +   a 32-bit inplace add RELA relocation used in DWARF debug sections.  */
> +
> +static bfd_boolean
> +is_32bit_inplace_add_reloc (unsigned int reloc_type)
> +{
> +  /* Please keep this table alpha-sorted for ease of visual lookup.  */
> +  switch (elf_header.e_machine)
> +    {
> +    case EM_RISCV:
> +      return reloc_type == 35; /* R_RISCV_ADD32.  */
> +    default:
> +      return FALSE;
> +    }
> +}
> +
> +/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
> +   a 32-bit inplace sub RELA relocation used in DWARF debug sections.  */
> +
> +static bfd_boolean
> +is_32bit_inplace_sub_reloc (unsigned int reloc_type)
> +{
> +  /* Please keep this table alpha-sorted for ease of visual lookup.  */
> +  switch (elf_header.e_machine)
> +    {
> +    case EM_RISCV:
> +      return reloc_type == 39; /* R_RISCV_SUB32.  */
> +    default:
> +      return FALSE;
> +    }
> +}
> +
> +/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
> +   a 64-bit inplace add RELA relocation used in DWARF debug sections.  */
> +
> +static bfd_boolean
> +is_64bit_inplace_add_reloc (unsigned int reloc_type)
> +{
> +  /* Please keep this table alpha-sorted for ease of visual lookup.  */
> +  switch (elf_header.e_machine)
> +    {
> +    case EM_RISCV:
> +      return reloc_type == 36; /* R_RISCV_ADD64.  */
> +    default:
> +      return FALSE;
> +    }
> +}
> +
> +/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
> +   a 64-bit inplace sub RELA relocation used in DWARF debug sections.  */
> +
> +static bfd_boolean
> +is_64bit_inplace_sub_reloc (unsigned int reloc_type)
> +{
> +  /* Please keep this table alpha-sorted for ease of visual lookup.  */
> +  switch (elf_header.e_machine)
> +    {
> +    case EM_RISCV:
> +      return reloc_type == 40; /* R_RISCV_SUB64.  */
> +    default:
> +      return FALSE;
> +    }
> +}
> +
> +/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
> +   a 16-bit inplace add RELA relocation used in DWARF debug sections.  */
> +
> +static bfd_boolean
> +is_16bit_inplace_add_reloc (unsigned int reloc_type)
> +{
> +  /* Please keep this table alpha-sorted for ease of visual lookup.  */
> +  switch (elf_header.e_machine)
> +    {
> +    case EM_RISCV:
> +      return reloc_type == 34; /* R_RISCV_ADD16.  */
> +    default:
> +      return FALSE;
> +    }
> +}
> +
> +/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
> +   a 16-bit inplace sub RELA relocation used in DWARF debug sections.  */
> +
> +static bfd_boolean
> +is_16bit_inplace_sub_reloc (unsigned int reloc_type)
> +{
> +  /* Please keep this table alpha-sorted for ease of visual lookup.  */
> +  switch (elf_header.e_machine)
> +    {
> +    case EM_RISCV:
> +      return reloc_type == 38; /* R_RISCV_SUB16.  */
> +    default:
> +      return FALSE;
> +    }
> +}
> +
> +/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
> +   a 8-bit inplace add RELA relocation used in DWARF debug sections.  */
> +
> +static bfd_boolean
> +is_8bit_inplace_add_reloc (unsigned int reloc_type)
> +{
> +  /* Please keep this table alpha-sorted for ease of visual lookup.  */
> +  switch (elf_header.e_machine)
> +    {
> +    case EM_RISCV:
> +      return reloc_type == 33; /* R_RISCV_ADD8.  */
> +    default:
> +      return FALSE;
> +    }
> +}
> +
> +/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
> +   a 8-bit inplace sub RELA relocation used in DWARF debug sections.  */
> +
> +static bfd_boolean
> +is_8bit_inplace_sub_reloc (unsigned int reloc_type)
> +{
> +  /* Please keep this table alpha-sorted for ease of visual lookup.  */
> +  switch (elf_header.e_machine)
> +    {
> +    case EM_RISCV:
> +      return reloc_type == 37; /* R_RISCV_SUB8.  */
> +    default:
> +      return FALSE;
> +    }
> +}
> +
>  /* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
>     relocation entries (possibly formerly used for SHT_GROUP sections).  */
>
> @@ -12732,6 +12860,8 @@ apply_relocations (void *                     file,
>  	  bfd_vma         addend;
>  	  unsigned int    reloc_type;
>  	  unsigned int    reloc_size;
> +	  bfd_boolean     reloc_inplace = FALSE;
> +	  bfd_boolean     reloc_subtract = FALSE;
>  	  unsigned char * rloc;
>  	  unsigned long   sym_index;
>
> @@ -12751,6 +12881,30 @@ apply_relocations (void *                     file,
>  	    reloc_size = 3;
>  	  else if (is_16bit_abs_reloc (reloc_type))
>  	    reloc_size = 2;
> +	  else if ((reloc_subtract = is_32bit_inplace_sub_reloc (reloc_type))
> +		   || is_32bit_inplace_add_reloc (reloc_type))
> +	    {
> +	      reloc_size = 4;
> +	      reloc_inplace = TRUE;
> +	    }
> +	  else if ((reloc_subtract = is_64bit_inplace_sub_reloc (reloc_type))
> +		   || is_64bit_inplace_add_reloc (reloc_type))
> +	    {
> +	      reloc_size = 8;
> +	      reloc_inplace = TRUE;
> +	    }
> +	  else if ((reloc_subtract = is_16bit_inplace_sub_reloc (reloc_type))
> +		   || is_16bit_inplace_add_reloc (reloc_type))
> +	    {
> +	      reloc_size = 2;
> +	      reloc_inplace = TRUE;
> +	    }
> +	  else if ((reloc_subtract = is_8bit_inplace_sub_reloc (reloc_type))
> +		   || is_8bit_inplace_add_reloc (reloc_type))
> +	    {
> +	      reloc_size = 1;
> +	      reloc_inplace = TRUE;
> +	    }
>  	  else
>  	    {
>  	      static unsigned int prev_reloc = 0;
> @@ -12820,7 +12974,8 @@ apply_relocations (void *                     file,
>  		  && reloc_type == 1)
>  	      || ((elf_header.e_machine == EM_D30V
>  		   || elf_header.e_machine == EM_CYGNUS_D30V)
> -		  && reloc_type == 12))
> +		  && reloc_type == 12)
> +	      || reloc_inplace)
>  	    addend += byte_get (rloc, reloc_size);
>
>  	  if (is_32bit_pcrel_reloc (reloc_type)
> @@ -12832,6 +12987,8 @@ apply_relocations (void *                     file,
>  	      byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
>  		        reloc_size);
>  	    }
> +	  else if (reloc_subtract)
> +	    byte_put (rloc, addend - sym->st_value, reloc_size);
>  	  else
>  	    byte_put (rloc, addend + sym->st_value, reloc_size);
>  	}



More information about the Binutils mailing list