Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37402592
en ru br
Репозитории ALT
S:2.41-alt1
5.1: 2.19.51.0.14-alt4
4.1: 2.17.50.0.6-alt4
4.0: 2.17.50.0.6-alt1
3.0: 2.15.94.0.2.2-alt3
www.altlinux.org/Changes

Другие репозитории
Upstream:2.18

Группа :: Разработка/Прочее
Пакет: binutils

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: binutils-2.17.50.0.6-rh-fixsyms.patch
Скачать


2006-10-23  Alan Modra  <amodra@bigpond.net.au>
	* linker.c (fix_syms): Choose best of previous and next
	section based on section flags and vma.
--- bfd/linker.c	17 Oct 2006 13:41:47 -0000	1.55
+++ bfd/linker.c	23 Oct 2006 02:35:38 -0000	1.56
@@ -3092,25 +3092,62 @@ fix_syms (struct bfd_link_hash_entry *h,
 	  && (s->output_section->flags & SEC_EXCLUDE) != 0
 	  && bfd_section_removed_from_list (obfd, s->output_section))
 	{
-	  asection *op;
-	  for (op = s->output_section->prev; op != NULL; op = op->prev)
+	  asection *op, *op1;
+
+	  h->u.def.value += s->output_offset + s->output_section->vma;
+
+	  /* Find preceding kept section.  */
+	  for (op1 = s->output_section->prev; op1 != NULL; op1 = op1->prev)
+	    if ((op1->flags & SEC_EXCLUDE) == 0
+		&& !bfd_section_removed_from_list (obfd, op1))
+	      break;
+
+	  /* Find following kept section.  Start at prev->next because
+	     other sections may have been added after S was removed.  */
+	  if (s->output_section->prev != NULL)
+	    op = s->output_section->prev->next;
+	  else
+	    op = s->output_section->owner->sections;
+	  for (; op != NULL; op = op->next)
 	    if ((op->flags & SEC_EXCLUDE) == 0
 		&& !bfd_section_removed_from_list (obfd, op))
 	      break;
-	  if (op == NULL)
+
+	  /* Choose better of two sections, based on flags.  The idea
+	     is to choose a section that will be in the same segment
+	     as S would have been if it was kept.  */
+	  if (op1 == NULL)
 	    {
-	      if (s->output_section->prev != NULL)
-		op = s->output_section->prev->next;
-	      else
-		op = s->output_section->owner->sections;
-	      for (; op != NULL; op = op->next)
-		if ((op->flags & SEC_EXCLUDE) == 0
-		    && !bfd_section_removed_from_list (obfd, op))
-		  break;
 	      if (op == NULL)
 		op = bfd_abs_section_ptr;
 	    }
-	  h->u.def.value += s->output_offset + s->output_section->vma;
+	  else if (op == NULL)
+	    op = op1;
+	  else if (((op1->flags ^ op->flags)
+		    & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0)
+	    {
+	      if (((op->flags ^ s->flags)
+		   & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0)
+		op = op1;
+	    }
+	  else if (((op1->flags ^ op->flags) & SEC_READONLY) != 0)
+	    {
+	      if (((op->flags ^ s->flags) & SEC_READONLY) != 0)
+		op = op1;
+	    }
+	  else if (((op1->flags ^ op->flags) & SEC_CODE) != 0)
+	    {
+	      if (((op->flags ^ s->flags) & SEC_CODE) != 0)
+		op = op1;
+	    }
+	  else
+	    {
+	      /* Flags we care about are the same.  Prefer the following
+		 section if that will result in a positive valued sym.  */
+	      if (h->u.def.value < op->vma)
+		op = op1;
+	    }
+
 	  h->u.def.value -= op->vma;
 	  h->u.def.section = op;
 	}
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin