[PATCH] backends: add abi_cfi and register_info callbacks for RISC-V

Andreas Schwab schwab@suse.de
Tue Jul 24 14:13:00 GMT 2018


How about this, does it look reasonable?  It doesn't handle SET6/SUB6
yet, and eu-readelf -wframe doesn't agree with readelf -wf, so this is
only a RFC.

Andreas.

diff --git a/backends/riscv_symbol.c b/backends/riscv_symbol.c
index dce8e3586b..866be8f093 100644
--- a/backends/riscv_symbol.c
+++ b/backends/riscv_symbol.c
@@ -44,10 +44,27 @@ riscv_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
 {
   switch (type)
     {
+    case R_RISCV_SET8:
+      return ELF_T_BYTE;
+    case R_RISCV_SET16:
+      return ELF_T_HALF;
     case R_RISCV_32:
+    case R_RISCV_SET32:
       return ELF_T_WORD;
     case R_RISCV_64:
       return ELF_T_XWORD;
+    case R_RISCV_ADD16:
+      return ELF_T_ADD_HALF;
+    case R_RISCV_SUB16:
+      return ELF_T_SUB_HALF;
+    case R_RISCV_ADD32:
+      return ELF_T_ADD_WORD;
+    case R_RISCV_SUB32:
+      return ELF_T_SUB_WORD;
+    case R_RISCV_ADD64:
+      return ELF_T_ADD_XWORD;
+    case R_RISCV_SUB64:
+      return ELF_T_SUB_XWORD;
     default:
       return ELF_T_NUM;
     }
diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c
index 9afcdebecc..1c4a1bade2 100644
--- a/libdwfl/relocate.c
+++ b/libdwfl/relocate.c
@@ -379,9 +379,18 @@ relocate (Dwfl_Module * const mod,
     DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword);			\
     DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
     size_t size;
+    bool is_add_sub = false;
     switch (type)
       {
 #define DO_TYPE(NAME, Name)			\
+	case ELF_T_ADD_##NAME:			\
+	case ELF_T_SUB_##NAME:			\
+	  if (addend == NULL)			\
+	    /* These do not make sense with SHT_REL.  */ \
+	    return DWFL_E_BADRELTYPE;		\
+	  is_add_sub = true;			\
+	  size = sizeof (GElf_##Name);		\
+	  break;				\
 	case ELF_T_##NAME:			\
 	  size = sizeof (GElf_##Name);		\
 	break
@@ -417,9 +426,23 @@ relocate (Dwfl_Module * const mod,
       {
 	/* For the addend form, we have the value already.  */
 	value += *addend;
+	if (is_add_sub)
+	  {
+	    Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata,
+					 ehdr->e_ident[EI_DATA]);
+	    if (d == NULL)
+	      return DWFL_E_LIBELF;
+	    assert (d == &tmpdata);
+	  }
 	switch (type)
 	  {
 #define DO_TYPE(NAME, Name)			\
+	    case ELF_T_ADD_##NAME:		\
+	      tmpbuf.Name += value;		\
+	      break;				\
+	    case ELF_T_SUB_##NAME:		\
+	      tmpbuf.Name -= value;		\
+	      break;				\
 	    case ELF_T_##NAME:			\
 	      tmpbuf.Name = value;		\
 	    break
diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c
index 0c509265cb..faa6d6fd4b 100644
--- a/libelf/gelf_fsize.c
+++ b/libelf/gelf_fsize.c
@@ -52,6 +52,18 @@ const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
       [ELF_T_SWORD]	= ELFW2(LIBELFBITS, FSZ_SWORD),			      \
       [ELF_T_XWORD]	= ELFW2(LIBELFBITS, FSZ_XWORD),			      \
       [ELF_T_SXWORD]	= ELFW2(LIBELFBITS, FSZ_SXWORD),		      \
+      [ELF_T_ADD_BYTE]	= 1,						      \
+      [ELF_T_ADD_HALF]	= ELFW2(LIBELFBITS, FSZ_HALF),			      \
+      [ELF_T_ADD_WORD]	= ELFW2(LIBELFBITS, FSZ_WORD),			      \
+      [ELF_T_ADD_SWORD]	= ELFW2(LIBELFBITS, FSZ_SWORD),			      \
+      [ELF_T_ADD_XWORD]	= ELFW2(LIBELFBITS, FSZ_XWORD),			      \
+      [ELF_T_ADD_SXWORD] = ELFW2(LIBELFBITS, FSZ_SXWORD),		      \
+      [ELF_T_SUB_BYTE]	= 1,						      \
+      [ELF_T_SUB_HALF]	= ELFW2(LIBELFBITS, FSZ_HALF),			      \
+      [ELF_T_SUB_WORD]	= ELFW2(LIBELFBITS, FSZ_WORD),			      \
+      [ELF_T_SUB_SWORD]	= ELFW2(LIBELFBITS, FSZ_SWORD),			      \
+      [ELF_T_SUB_XWORD]	= ELFW2(LIBELFBITS, FSZ_XWORD),			      \
+      [ELF_T_SUB_SXWORD] = ELFW2(LIBELFBITS, FSZ_SXWORD),		      \
       [ELF_T_EHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Ehdr)),		      \
       [ELF_T_SHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Shdr)),		      \
       [ELF_T_SYM]	= sizeof (ElfW2(LIBELFBITS, Ext_Sym)),		      \
diff --git a/libelf/libelf.h b/libelf/libelf.h
index 547c0f5081..38eeea31ab 100644
--- a/libelf/libelf.h
+++ b/libelf/libelf.h
@@ -117,6 +117,18 @@ typedef enum
   ELF_T_GNUHASH,		/* GNU-style hash section.  */
   ELF_T_AUXV,			/* Elf32_auxv_t, Elf64_auxv_t, ... */
   ELF_T_CHDR,			/* Compressed, Elf32_Chdr, Elf64_Chdr, ... */
+  ELF_T_ADD_BYTE,
+  ELF_T_SUB_BYTE,
+  ELF_T_ADD_HALF,
+  ELF_T_SUB_HALF,
+  ELF_T_ADD_WORD,
+  ELF_T_SUB_WORD,
+  ELF_T_ADD_SWORD,
+  ELF_T_SUB_SWORD,
+  ELF_T_ADD_XWORD,
+  ELF_T_SUB_XWORD,
+  ELF_T_ADD_SXWORD,
+  ELF_T_SUB_SXWORD,
   /* Keep this the last entry.  */
   ELF_T_NUM
 } Elf_Type;
diff --git a/src/strip.c b/src/strip.c
index 791347c1dd..32190344ba 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -1968,6 +1968,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 		if (ebl_debugscn_p (ebl, shdr_info[sec].name))
 		  {
 		    size_t size;
+		    bool is_add_sub;
 
 #define DO_TYPE(NAME, Name) GElf_##Name Name;
 		    union { TYPES; } tmpbuf;
@@ -1976,9 +1977,16 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 		    switch (type)
 		      {
 #define DO_TYPE(NAME, Name)				\
+			case ELF_T_ADD_##NAME:		\
+			case ELF_T_SUB_##NAME:		\
+			  size = sizeof (GElf_##Name);	\
+			  tmpbuf.Name = 0;		\
+			  is_add_sub = true;		\
+			  break;			\
 			case ELF_T_##NAME:		\
 			  size = sizeof (GElf_##Name);	\
 			  tmpbuf.Name = 0;		\
+			  is_add_sub = false;		\
 			  break;
 			TYPES;
 #undef DO_TYPE
@@ -2024,6 +2032,15 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 			/* For SHT_RELA sections we just take the
 			   given addend and add it to the value.  */
 			value += addend;
+			if (is_add_sub)
+			  {
+			    Elf_Data *d = gelf_xlatetom (debugelf, &tmpdata,
+							 &rdata,
+							 ehdr->e_ident[EI_DATA]);
+			    if (d == NULL)
+			      INTERNAL_ERROR (fname);
+			    assert (d == &tmpdata);
+			  }
 		      }
 		    else
 		      {
@@ -2042,7 +2059,11 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 		      {
 #define DO_TYPE(NAME, Name)					\
 			case ELF_T_##NAME:			\
+			case ELF_T_ADD_##NAME:			\
 			  tmpbuf.Name += (GElf_##Name) value;	\
+			  break;				\
+			case ELF_T_SUB_##NAME:			\
+			  tmpbuf.Name -= (GElf_##Name) value;	\
 			  break;
 			TYPES;
 #undef DO_TYPE
-- 
2.18.0

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."



More information about the Elfutils-devel mailing list