dcavalca / rpms / rpm

Forked from rpms/rpm 2 years ago
Clone

Blame 0001-debugedit-Refactor-reading-writing-of-relocated-valu.patch

James Antill ee2eaf
From ce6e8556a8f93327d6de0446f21ac5e549861d82 Mon Sep 17 00:00:00 2001
James Antill ee2eaf
Message-Id: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
James Antill ee2eaf
From: Mark Wielaard <mark@klomp.org>
James Antill ee2eaf
Date: Mon, 17 Jun 2019 11:23:24 +0200
James Antill ee2eaf
Subject: [PATCH 1/3] debugedit: Refactor reading/writing of relocated values.
James Antill ee2eaf
James Antill ee2eaf
This refactors the reading and writing of relocated values into seperate
James Antill ee2eaf
helper functions (setup_relbuf and update_rela_data). It will be easier
James Antill ee2eaf
to reuse this code in case we want to read/write relocated values in other
James Antill ee2eaf
sections than DEBUG_INFO. The only functional change is that we explicitly
James Antill ee2eaf
track whether the relocation data is updated, and only explicitly update
James Antill ee2eaf
and write out the relocation data if so. In the case there were no strp
James Antill ee2eaf
or stmt updates, there will also not be any relocation updates, even if
James Antill ee2eaf
there is relocation data available.
James Antill ee2eaf
James Antill ee2eaf
All new debugedit testcases pass before and after this refactoring.
James Antill ee2eaf
---
James Antill ee2eaf
 tools/debugedit.c | 395 +++++++++++++++++++++++++---------------------
James Antill ee2eaf
 1 file changed, 216 insertions(+), 179 deletions(-)
James Antill ee2eaf
James Antill ee2eaf
diff --git a/tools/debugedit.c b/tools/debugedit.c
James Antill ee2eaf
index 4be85b979..cf9cc3ca9 100644
James Antill ee2eaf
--- a/tools/debugedit.c
James Antill ee2eaf
+++ b/tools/debugedit.c
James Antill ee2eaf
@@ -401,13 +401,18 @@ dwarf2_write_be32 (unsigned char *p, uint32_t v)
James Antill ee2eaf
    relend). Might just update the addend. So relocations need to be
James Antill ee2eaf
    updated at the end.  */
James Antill ee2eaf
 
James Antill ee2eaf
+static bool rel_updated;
James Antill ee2eaf
+
James Antill ee2eaf
 #define do_write_32_relocated(ptr,val) ({ \
James Antill ee2eaf
   if (relptr && relptr < relend && relptr->ptr == ptr)	\
James Antill ee2eaf
     {							\
James Antill ee2eaf
       if (reltype == SHT_REL)				\
James Antill ee2eaf
 	do_write_32 (ptr, val - relptr->addend);	\
James Antill ee2eaf
       else						\
James Antill ee2eaf
-	relptr->addend = val;				\
James Antill ee2eaf
+	{						\
James Antill ee2eaf
+	  relptr->addend = val;				\
James Antill ee2eaf
+	  rel_updated = true;				\
James Antill ee2eaf
+	}						\
James Antill ee2eaf
     }							\
James Antill ee2eaf
   else							\
James Antill ee2eaf
     do_write_32 (ptr,val);				\
James Antill ee2eaf
@@ -418,14 +423,18 @@ dwarf2_write_be32 (unsigned char *p, uint32_t v)
James Antill ee2eaf
   ptr += 4;			       \
James Antill ee2eaf
 })
James Antill ee2eaf
 
James Antill ee2eaf
-static struct
James Antill ee2eaf
+typedef struct debug_section
James Antill ee2eaf
   {
James Antill ee2eaf
     const char *name;
James Antill ee2eaf
     unsigned char *data;
James Antill ee2eaf
     Elf_Data *elf_data;
James Antill ee2eaf
     size_t size;
James Antill ee2eaf
     int sec, relsec;
James Antill ee2eaf
-  } debug_sections[] =
James Antill ee2eaf
+    REL *relbuf;
James Antill ee2eaf
+    REL *relend;
James Antill ee2eaf
+  } debug_section;
James Antill ee2eaf
+
James Antill ee2eaf
+static debug_section debug_sections[] =
James Antill ee2eaf
   {
James Antill ee2eaf
 #define DEBUG_INFO	0
James Antill ee2eaf
 #define DEBUG_ABBREV	1
James Antill ee2eaf
@@ -458,6 +467,201 @@ static struct
James Antill ee2eaf
     { NULL, NULL, NULL, 0, 0, 0 }
James Antill ee2eaf
   };
James Antill ee2eaf
 
James Antill ee2eaf
+static int
James Antill ee2eaf
+rel_cmp (const void *a, const void *b)
James Antill ee2eaf
+{
James Antill ee2eaf
+  REL *rela = (REL *) a, *relb = (REL *) b;
James Antill ee2eaf
+
James Antill ee2eaf
+  if (rela->ptr < relb->ptr)
James Antill ee2eaf
+    return -1;
James Antill ee2eaf
+
James Antill ee2eaf
+  if (rela->ptr > relb->ptr)
James Antill ee2eaf
+    return 1;
James Antill ee2eaf
+
James Antill ee2eaf
+  return 0;
James Antill ee2eaf
+}
James Antill ee2eaf
+
James Antill ee2eaf
+/* Returns a malloced REL array, or NULL when there are no relocations
James Antill ee2eaf
+   for this section.  When there are relocations, will setup relend,
James Antill ee2eaf
+   as the last REL, and reltype, as SHT_REL or SHT_RELA.  */
James Antill ee2eaf
+static void
James Antill ee2eaf
+setup_relbuf (DSO *dso, debug_section *sec, int *reltype)
James Antill ee2eaf
+{
James Antill ee2eaf
+  int ndx, maxndx;
James Antill ee2eaf
+  GElf_Rel rel;
James Antill ee2eaf
+  GElf_Rela rela;
James Antill ee2eaf
+  GElf_Sym sym;
James Antill ee2eaf
+  GElf_Addr base = dso->shdr[sec->sec].sh_addr;
James Antill ee2eaf
+  Elf_Data *symdata = NULL;
James Antill ee2eaf
+  int rtype;
James Antill ee2eaf
+  REL *relbuf;
James Antill ee2eaf
+  Elf_Scn *scn;
James Antill ee2eaf
+  Elf_Data *data;
James Antill ee2eaf
+  int i = sec->relsec;
James Antill ee2eaf
+
James Antill ee2eaf
+  /* No relocations, or did we do this already? */
James Antill ee2eaf
+  if (i == 0 || sec->relbuf != NULL)
James Antill ee2eaf
+    {
James Antill ee2eaf
+      relptr = sec->relbuf;
James Antill ee2eaf
+      relend = sec->relend;
James Antill ee2eaf
+      return;
James Antill ee2eaf
+    }
James Antill ee2eaf
+
James Antill ee2eaf
+  scn = dso->scn[i];
James Antill ee2eaf
+  data = elf_getdata (scn, NULL);
James Antill ee2eaf
+  assert (data != NULL && data->d_buf != NULL);
James Antill ee2eaf
+  assert (elf_getdata (scn, data) == NULL);
James Antill ee2eaf
+  assert (data->d_off == 0);
James Antill ee2eaf
+  assert (data->d_size == dso->shdr[i].sh_size);
James Antill ee2eaf
+  maxndx = dso->shdr[i].sh_size / dso->shdr[i].sh_entsize;
James Antill ee2eaf
+  relbuf = malloc (maxndx * sizeof (REL));
James Antill ee2eaf
+  *reltype = dso->shdr[i].sh_type;
James Antill ee2eaf
+  if (relbuf == NULL)
James Antill ee2eaf
+    error (1, errno, "%s: Could not allocate memory", dso->filename);
James Antill ee2eaf
+
James Antill ee2eaf
+  symdata = elf_getdata (dso->scn[dso->shdr[i].sh_link], NULL);
James Antill ee2eaf
+  assert (symdata != NULL && symdata->d_buf != NULL);
James Antill ee2eaf
+  assert (elf_getdata (dso->scn[dso->shdr[i].sh_link], symdata) == NULL);
James Antill ee2eaf
+  assert (symdata->d_off == 0);
James Antill ee2eaf
+  assert (symdata->d_size == dso->shdr[dso->shdr[i].sh_link].sh_size);
James Antill ee2eaf
+
James Antill ee2eaf
+  for (ndx = 0, relend = relbuf; ndx < maxndx; ++ndx)
James Antill ee2eaf
+    {
James Antill ee2eaf
+      if (dso->shdr[i].sh_type == SHT_REL)
James Antill ee2eaf
+	{
James Antill ee2eaf
+	  gelf_getrel (data, ndx, &rel;;
James Antill ee2eaf
+	  rela.r_offset = rel.r_offset;
James Antill ee2eaf
+	  rela.r_info = rel.r_info;
James Antill ee2eaf
+	  rela.r_addend = 0;
James Antill ee2eaf
+	}
James Antill ee2eaf
+      else
James Antill ee2eaf
+	gelf_getrela (data, ndx, &rela);
James Antill ee2eaf
+      gelf_getsym (symdata, ELF64_R_SYM (rela.r_info), &sym);
James Antill ee2eaf
+      /* Relocations against section symbols are uninteresting in REL.  */
James Antill ee2eaf
+      if (dso->shdr[i].sh_type == SHT_REL && sym.st_value == 0)
James Antill ee2eaf
+	continue;
James Antill ee2eaf
+      /* Only consider relocations against .debug_str, .debug_line
James Antill ee2eaf
+	 and .debug_abbrev.  */
James Antill ee2eaf
+      if (sym.st_shndx != debug_sections[DEBUG_STR].sec
James Antill ee2eaf
+	  && sym.st_shndx != debug_sections[DEBUG_LINE].sec
James Antill ee2eaf
+	  && sym.st_shndx != debug_sections[DEBUG_ABBREV].sec)
James Antill ee2eaf
+	continue;
James Antill ee2eaf
+      rela.r_addend += sym.st_value;
James Antill ee2eaf
+      rtype = ELF64_R_TYPE (rela.r_info);
James Antill ee2eaf
+      switch (dso->ehdr.e_machine)
James Antill ee2eaf
+	{
James Antill ee2eaf
+	case EM_SPARC:
James Antill ee2eaf
+	case EM_SPARC32PLUS:
James Antill ee2eaf
+	case EM_SPARCV9:
James Antill ee2eaf
+	  if (rtype != R_SPARC_32 && rtype != R_SPARC_UA32)
James Antill ee2eaf
+	    goto fail;
James Antill ee2eaf
+	  break;
James Antill ee2eaf
+	case EM_386:
James Antill ee2eaf
+	  if (rtype != R_386_32)
James Antill ee2eaf
+	    goto fail;
James Antill ee2eaf
+	  break;
James Antill ee2eaf
+	case EM_PPC:
James Antill ee2eaf
+	case EM_PPC64:
James Antill ee2eaf
+	  if (rtype != R_PPC_ADDR32 && rtype != R_PPC_UADDR32)
James Antill ee2eaf
+	    goto fail;
James Antill ee2eaf
+	  break;
James Antill ee2eaf
+	case EM_S390:
James Antill ee2eaf
+	  if (rtype != R_390_32)
James Antill ee2eaf
+	    goto fail;
James Antill ee2eaf
+	  break;
James Antill ee2eaf
+	case EM_IA_64:
James Antill ee2eaf
+	  if (rtype != R_IA64_SECREL32LSB)
James Antill ee2eaf
+	    goto fail;
James Antill ee2eaf
+	  break;
James Antill ee2eaf
+	case EM_X86_64:
James Antill ee2eaf
+	  if (rtype != R_X86_64_32)
James Antill ee2eaf
+	    goto fail;
James Antill ee2eaf
+	  break;
James Antill ee2eaf
+	case EM_ALPHA:
James Antill ee2eaf
+	  if (rtype != R_ALPHA_REFLONG)
James Antill ee2eaf
+	    goto fail;
James Antill ee2eaf
+	  break;
James Antill ee2eaf
+#if defined(EM_AARCH64) && defined(R_AARCH64_ABS32)
James Antill ee2eaf
+	case EM_AARCH64:
James Antill ee2eaf
+	  if (rtype != R_AARCH64_ABS32)
James Antill ee2eaf
+	    goto fail;
James Antill ee2eaf
+	  break;
James Antill ee2eaf
+#endif
James Antill ee2eaf
+	case EM_68K:
James Antill ee2eaf
+	  if (rtype != R_68K_32)
James Antill ee2eaf
+	    goto fail;
James Antill ee2eaf
+	  break;
James Antill ee2eaf
+#if defined(EM_RISCV) && defined(R_RISCV_32)
James Antill ee2eaf
+	case EM_RISCV:
James Antill ee2eaf
+	  if (rtype != R_RISCV_32)
James Antill ee2eaf
+	    goto fail;
James Antill ee2eaf
+	  break;
James Antill ee2eaf
+#endif
James Antill ee2eaf
+	default:
James Antill ee2eaf
+	fail:
James Antill ee2eaf
+	  error (1, 0, "%s: Unhandled relocation %d in %s section",
James Antill ee2eaf
+		 dso->filename, rtype, sec->name);
James Antill ee2eaf
+	}
James Antill ee2eaf
+      relend->ptr = sec->data
James Antill ee2eaf
+	+ (rela.r_offset - base);
James Antill ee2eaf
+      relend->addend = rela.r_addend;
James Antill ee2eaf
+      relend->ndx = ndx;
James Antill ee2eaf
+      ++(relend);
James Antill ee2eaf
+    }
James Antill ee2eaf
+  if (relbuf == relend)
James Antill ee2eaf
+    {
James Antill ee2eaf
+      free (relbuf);
James Antill ee2eaf
+      relbuf = NULL;
James Antill ee2eaf
+      relend = NULL;
James Antill ee2eaf
+    }
James Antill ee2eaf
+  else
James Antill ee2eaf
+    qsort (relbuf, relend - relbuf, sizeof (REL), rel_cmp);
James Antill ee2eaf
+
James Antill ee2eaf
+  sec->relbuf = relbuf;
James Antill ee2eaf
+  sec->relend = relend;
James Antill ee2eaf
+  relptr = relbuf;
James Antill ee2eaf
+}
James Antill ee2eaf
+
James Antill ee2eaf
+/* Updates SHT_RELA section associated with the given section based on
James Antill ee2eaf
+   the relbuf data. The relbuf data is freed at the end.  */
James Antill ee2eaf
+static void
James Antill ee2eaf
+update_rela_data (DSO *dso, struct debug_section *sec)
James Antill ee2eaf
+{
James Antill ee2eaf
+  Elf_Data *symdata;
James Antill ee2eaf
+  int relsec_ndx = sec->relsec;
James Antill ee2eaf
+  Elf_Data *data = elf_getdata (dso->scn[relsec_ndx], NULL);
James Antill ee2eaf
+  symdata = elf_getdata (dso->scn[dso->shdr[relsec_ndx].sh_link],
James Antill ee2eaf
+			 NULL);
James Antill ee2eaf
+
James Antill ee2eaf
+  relptr = sec->relbuf;
James Antill ee2eaf
+  relend = sec->relend;
James Antill ee2eaf
+  while (relptr < relend)
James Antill ee2eaf
+    {
James Antill ee2eaf
+      GElf_Sym sym;
James Antill ee2eaf
+      GElf_Rela rela;
James Antill ee2eaf
+      int ndx = relptr->ndx;
James Antill ee2eaf
+
James Antill ee2eaf
+      if (gelf_getrela (data, ndx, &rela) == NULL)
James Antill ee2eaf
+	error (1, 0, "Couldn't get relocation: %s",
James Antill ee2eaf
+	       elf_errmsg (-1));
James Antill ee2eaf
+
James Antill ee2eaf
+      if (gelf_getsym (symdata, GELF_R_SYM (rela.r_info),
James Antill ee2eaf
+		       &sym) == NULL)
James Antill ee2eaf
+	error (1, 0, "Couldn't get symbol: %s", elf_errmsg (-1));
James Antill ee2eaf
+
James Antill ee2eaf
+      rela.r_addend = relptr->addend - sym.st_value;
James Antill ee2eaf
+
James Antill ee2eaf
+      if (gelf_update_rela (data, ndx, &rela) == 0)
James Antill ee2eaf
+	error (1, 0, "Couldn't update relocations: %s",
James Antill ee2eaf
+	       elf_errmsg (-1));
James Antill ee2eaf
+
James Antill ee2eaf
+      ++relptr;
James Antill ee2eaf
+    }
James Antill ee2eaf
+  elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
James Antill ee2eaf
+
James Antill ee2eaf
+  free (sec->relbuf);
James Antill ee2eaf
+}
James Antill ee2eaf
+
James Antill ee2eaf
 struct abbrev_attr
James Antill ee2eaf
   {
James Antill ee2eaf
     unsigned int attr;
James Antill ee2eaf
@@ -1743,20 +1947,6 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
James Antill ee2eaf
   return ptr;
James Antill ee2eaf
 }
James Antill ee2eaf
 
James Antill ee2eaf
-static int
James Antill ee2eaf
-rel_cmp (const void *a, const void *b)
James Antill ee2eaf
-{
James Antill ee2eaf
-  REL *rela = (REL *) a, *relb = (REL *) b;
James Antill ee2eaf
-
James Antill ee2eaf
-  if (rela->ptr < relb->ptr)
James Antill ee2eaf
-    return -1;
James Antill ee2eaf
-
James Antill ee2eaf
-  if (rela->ptr > relb->ptr)
James Antill ee2eaf
-    return 1;
James Antill ee2eaf
-
James Antill ee2eaf
-  return 0;
James Antill ee2eaf
-}
James Antill ee2eaf
-
James Antill ee2eaf
 static int
James Antill ee2eaf
 line_rel_cmp (const void *a, const void *b)
James Antill ee2eaf
 {
James Antill ee2eaf
@@ -1871,132 +2061,7 @@ edit_dwarf2 (DSO *dso)
James Antill ee2eaf
       htab_t abbrev;
James Antill ee2eaf
       struct abbrev_tag tag, *t;
James Antill ee2eaf
       int phase;
James Antill ee2eaf
-      REL *relbuf = NULL;
James Antill ee2eaf
-
James Antill ee2eaf
-      if (debug_sections[DEBUG_INFO].relsec)
James Antill ee2eaf
-	{
James Antill ee2eaf
-	  int ndx, maxndx;
James Antill ee2eaf
-	  GElf_Rel rel;
James Antill ee2eaf
-	  GElf_Rela rela;
James Antill ee2eaf
-	  GElf_Sym sym;
James Antill ee2eaf
-	  GElf_Addr base = dso->shdr[debug_sections[DEBUG_INFO].sec].sh_addr;
James Antill ee2eaf
-	  Elf_Data *symdata = NULL;
James Antill ee2eaf
-	  int rtype;
James Antill ee2eaf
-
James Antill ee2eaf
-	  i = debug_sections[DEBUG_INFO].relsec;
James Antill ee2eaf
-	  scn = dso->scn[i];
James Antill ee2eaf
-	  data = elf_getdata (scn, NULL);
James Antill ee2eaf
-	  assert (data != NULL && data->d_buf != NULL);
James Antill ee2eaf
-	  assert (elf_getdata (scn, data) == NULL);
James Antill ee2eaf
-	  assert (data->d_off == 0);
James Antill ee2eaf
-	  assert (data->d_size == dso->shdr[i].sh_size);
James Antill ee2eaf
-	  maxndx = dso->shdr[i].sh_size / dso->shdr[i].sh_entsize;
James Antill ee2eaf
-	  relbuf = malloc (maxndx * sizeof (REL));
James Antill ee2eaf
-	  reltype = dso->shdr[i].sh_type;
James Antill ee2eaf
-	  if (relbuf == NULL)
James Antill ee2eaf
-	    error (1, errno, "%s: Could not allocate memory", dso->filename);
James Antill ee2eaf
-
James Antill ee2eaf
-	  symdata = elf_getdata (dso->scn[dso->shdr[i].sh_link], NULL);
James Antill ee2eaf
-	  assert (symdata != NULL && symdata->d_buf != NULL);
James Antill ee2eaf
-	  assert (elf_getdata (dso->scn[dso->shdr[i].sh_link], symdata)
James Antill ee2eaf
-		  == NULL);
James Antill ee2eaf
-	  assert (symdata->d_off == 0);
James Antill ee2eaf
-	  assert (symdata->d_size
James Antill ee2eaf
-		  == dso->shdr[dso->shdr[i].sh_link].sh_size);
James Antill ee2eaf
-
James Antill ee2eaf
-	  for (ndx = 0, relend = relbuf; ndx < maxndx; ++ndx)
James Antill ee2eaf
-	    {
James Antill ee2eaf
-	      if (dso->shdr[i].sh_type == SHT_REL)
James Antill ee2eaf
-		{
James Antill ee2eaf
-		  gelf_getrel (data, ndx, &rel;;
James Antill ee2eaf
-		  rela.r_offset = rel.r_offset;
James Antill ee2eaf
-		  rela.r_info = rel.r_info;
James Antill ee2eaf
-		  rela.r_addend = 0;
James Antill ee2eaf
-		}
James Antill ee2eaf
-	      else
James Antill ee2eaf
-		gelf_getrela (data, ndx, &rela);
James Antill ee2eaf
-	      gelf_getsym (symdata, ELF64_R_SYM (rela.r_info), &sym);
James Antill ee2eaf
-	      /* Relocations against section symbols are uninteresting
James Antill ee2eaf
-		 in REL.  */
James Antill ee2eaf
-	      if (dso->shdr[i].sh_type == SHT_REL && sym.st_value == 0)
James Antill ee2eaf
-		continue;
James Antill ee2eaf
-	      /* Only consider relocations against .debug_str, .debug_line
James Antill ee2eaf
-		 and .debug_abbrev.  */
James Antill ee2eaf
-	      if (sym.st_shndx != debug_sections[DEBUG_STR].sec
James Antill ee2eaf
-		  && sym.st_shndx != debug_sections[DEBUG_LINE].sec
James Antill ee2eaf
-		  && sym.st_shndx != debug_sections[DEBUG_ABBREV].sec)
James Antill ee2eaf
-		continue;
James Antill ee2eaf
-	      rela.r_addend += sym.st_value;
James Antill ee2eaf
-	      rtype = ELF64_R_TYPE (rela.r_info);
James Antill ee2eaf
-	      switch (dso->ehdr.e_machine)
James Antill ee2eaf
-		{
James Antill ee2eaf
-		case EM_SPARC:
James Antill ee2eaf
-		case EM_SPARC32PLUS:
James Antill ee2eaf
-		case EM_SPARCV9:
James Antill ee2eaf
-		  if (rtype != R_SPARC_32 && rtype != R_SPARC_UA32)
James Antill ee2eaf
-		    goto fail;
James Antill ee2eaf
-		  break;
James Antill ee2eaf
-		case EM_386:
James Antill ee2eaf
-		  if (rtype != R_386_32)
James Antill ee2eaf
-		    goto fail;
James Antill ee2eaf
-		  break;
James Antill ee2eaf
-		case EM_PPC:
James Antill ee2eaf
-		case EM_PPC64:
James Antill ee2eaf
-		  if (rtype != R_PPC_ADDR32 && rtype != R_PPC_UADDR32)
James Antill ee2eaf
-		    goto fail;
James Antill ee2eaf
-		  break;
James Antill ee2eaf
-		case EM_S390:
James Antill ee2eaf
-		  if (rtype != R_390_32)
James Antill ee2eaf
-		    goto fail;
James Antill ee2eaf
-		  break;
James Antill ee2eaf
-		case EM_IA_64:
James Antill ee2eaf
-		  if (rtype != R_IA64_SECREL32LSB)
James Antill ee2eaf
-		    goto fail;
James Antill ee2eaf
-		  break;
James Antill ee2eaf
-		case EM_X86_64:
James Antill ee2eaf
-		  if (rtype != R_X86_64_32)
James Antill ee2eaf
-		    goto fail;
James Antill ee2eaf
-		  break;
James Antill ee2eaf
-		case EM_ALPHA:
James Antill ee2eaf
-		  if (rtype != R_ALPHA_REFLONG)
James Antill ee2eaf
-		    goto fail;
James Antill ee2eaf
-		  break;
James Antill ee2eaf
-#if defined(EM_AARCH64) && defined(R_AARCH64_ABS32)
James Antill ee2eaf
-		case EM_AARCH64:
James Antill ee2eaf
-		  if (rtype != R_AARCH64_ABS32)
James Antill ee2eaf
-		    goto fail;
James Antill ee2eaf
-		  break;
James Antill ee2eaf
-#endif
James Antill ee2eaf
-		case EM_68K:
James Antill ee2eaf
-		  if (rtype != R_68K_32)
James Antill ee2eaf
-		    goto fail;
James Antill ee2eaf
-		  break;
James Antill ee2eaf
-#if defined(EM_RISCV) && defined(R_RISCV_32)
James Antill ee2eaf
-		case EM_RISCV:
James Antill ee2eaf
-		  if (rtype != R_RISCV_32)
James Antill ee2eaf
-		    goto fail;
James Antill ee2eaf
-		  break;
James Antill ee2eaf
-#endif
James Antill ee2eaf
-		default:
James Antill ee2eaf
-		fail:
James Antill ee2eaf
-		  error (1, 0, "%s: Unhandled relocation %d in .debug_info section",
James Antill ee2eaf
-			 dso->filename, rtype);
James Antill ee2eaf
-		}
James Antill ee2eaf
-	      relend->ptr = debug_sections[DEBUG_INFO].data
James Antill ee2eaf
-			    + (rela.r_offset - base);
James Antill ee2eaf
-	      relend->addend = rela.r_addend;
James Antill ee2eaf
-	      relend->ndx = ndx;
James Antill ee2eaf
-	      ++relend;
James Antill ee2eaf
-	    }
James Antill ee2eaf
-	  if (relbuf == relend)
James Antill ee2eaf
-	    {
James Antill ee2eaf
-	      free (relbuf);
James Antill ee2eaf
-	      relbuf = NULL;
James Antill ee2eaf
-	      relend = NULL;
James Antill ee2eaf
-	    }
James Antill ee2eaf
-	  else
James Antill ee2eaf
-	    qsort (relbuf, relend - relbuf, sizeof (REL), rel_cmp);
James Antill ee2eaf
-	}
James Antill ee2eaf
+      bool info_rel_updated = false;
James Antill ee2eaf
 
James Antill ee2eaf
       for (phase = 0; phase < 2; phase++)
James Antill ee2eaf
 	{
James Antill ee2eaf
@@ -2008,7 +2073,8 @@ edit_dwarf2 (DSO *dso)
James Antill ee2eaf
 	    break;
James Antill ee2eaf
 
James Antill ee2eaf
 	  ptr = debug_sections[DEBUG_INFO].data;
James Antill ee2eaf
-	  relptr = relbuf;
James Antill ee2eaf
+	  setup_relbuf(dso, &debug_sections[DEBUG_INFO], &reltype);
James Antill ee2eaf
+	  rel_updated = false;
James Antill ee2eaf
 	  endsec = ptr + debug_sections[DEBUG_INFO].size;
James Antill ee2eaf
 	  while (ptr < endsec)
James Antill ee2eaf
 	    {
James Antill ee2eaf
@@ -2096,6 +2162,10 @@ edit_dwarf2 (DSO *dso)
James Antill ee2eaf
 	      htab_delete (abbrev);
James Antill ee2eaf
 	    }
James Antill ee2eaf
 
James Antill ee2eaf
+	  /* Remember whether any .debug_info relocations might need
James Antill ee2eaf
+	     to be updated. */
James Antill ee2eaf
+	  info_rel_updated = rel_updated;
James Antill ee2eaf
+
James Antill ee2eaf
 	  /* We might have to recalculate/rewrite the debug_line
James Antill ee2eaf
 	     section.  We need to do that before going into phase one
James Antill ee2eaf
 	     so we have all new offsets.  We do this separately from
James Antill ee2eaf
@@ -2240,41 +2310,8 @@ edit_dwarf2 (DSO *dso)
James Antill ee2eaf
 	dirty_section (DEBUG_INFO);
James Antill ee2eaf
 
James Antill ee2eaf
       /* Update any debug_info relocations addends we might have touched. */
James Antill ee2eaf
-      if (relbuf != NULL && reltype == SHT_RELA)
James Antill ee2eaf
-	{
James Antill ee2eaf
-	  Elf_Data *symdata;
James Antill ee2eaf
-          int relsec_ndx = debug_sections[DEBUG_INFO].relsec;
James Antill ee2eaf
-          data = elf_getdata (dso->scn[relsec_ndx], NULL);
James Antill ee2eaf
-	  symdata = elf_getdata (dso->scn[dso->shdr[relsec_ndx].sh_link],
James Antill ee2eaf
-				 NULL);
James Antill ee2eaf
-
James Antill ee2eaf
-	  relptr = relbuf;
James Antill ee2eaf
-	  while (relptr < relend)
James Antill ee2eaf
-	    {
James Antill ee2eaf
-	      GElf_Sym sym;
James Antill ee2eaf
-	      GElf_Rela rela;
James Antill ee2eaf
-	      int ndx = relptr->ndx;
James Antill ee2eaf
-
James Antill ee2eaf
-	      if (gelf_getrela (data, ndx, &rela) == NULL)
James Antill ee2eaf
-		error (1, 0, "Couldn't get relocation: %s",
James Antill ee2eaf
-		       elf_errmsg (-1));
James Antill ee2eaf
-
James Antill ee2eaf
-	      if (gelf_getsym (symdata, GELF_R_SYM (rela.r_info),
James Antill ee2eaf
-			       &sym) == NULL)
James Antill ee2eaf
-		error (1, 0, "Couldn't get symbol: %s", elf_errmsg (-1));
James Antill ee2eaf
-
James Antill ee2eaf
-	      rela.r_addend = relptr->addend - sym.st_value;
James Antill ee2eaf
-
James Antill ee2eaf
-	      if (gelf_update_rela (data, ndx, &rela) == 0)
James Antill ee2eaf
-		error (1, 0, "Couldn't update relocations: %s",
James Antill ee2eaf
-		       elf_errmsg (-1));
James Antill ee2eaf
-
James Antill ee2eaf
-	      ++relptr;
James Antill ee2eaf
-	    }
James Antill ee2eaf
-	  elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
James Antill ee2eaf
-	}
James Antill ee2eaf
-
James Antill ee2eaf
-      free (relbuf);
James Antill ee2eaf
+      if (info_rel_updated)
James Antill ee2eaf
+	update_rela_data (dso, &debug_sections[DEBUG_INFO]);
James Antill ee2eaf
     }
James Antill ee2eaf
 
James Antill ee2eaf
   return 0;
James Antill ee2eaf
-- 
James Antill ee2eaf
2.23.0
James Antill ee2eaf