Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(536)

Unified Diff: bfd/linker.c

Issue 11969036: Merge GDB 7.5.1 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@master
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « bfd/libbfd-in.h ('k') | bfd/lynx-core.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: bfd/linker.c
diff --git a/bfd/linker.c b/bfd/linker.c
index 7a01e114a21a268e58768859c85342e7740a0316..3caec96a8f038ac64e0df3e794484023c4370327 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1,6 +1,6 @@
/* linker.c -- BFD linker routines
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
@@ -810,6 +810,7 @@ void
_bfd_generic_link_just_syms (asection *sec,
struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
+ sec->sec_info_type = SEC_INFO_TYPE_JUST_SYMS;
sec->output_section = bfd_abs_section_ptr;
sec->output_offset = sec->vma;
}
@@ -2664,7 +2665,14 @@ default_data_link_order (bfd *abfd,
fill = link_order->u.data.contents;
fill_size = link_order->u.data.size;
- if (fill_size != 0 && fill_size < size)
+ if (fill_size == 0)
+ {
+ fill = abfd->arch_info->fill (size, bfd_big_endian (abfd),
+ (sec->flags & SEC_CODE) != 0);
+ if (fill == NULL)
+ return FALSE;
+ }
+ else if (fill_size < size)
{
bfd_byte *p;
fill = (bfd_byte *) bfd_malloc (size);
@@ -3123,6 +3131,76 @@ _bfd_generic_section_already_linked (bfd *abfd ATTRIBUTE_UNUSED,
return FALSE;
}
+/* Choose a neighbouring section to S in OBFD that will be output, or
+ the absolute section if ADDR is out of bounds of the neighbours. */
+
+asection *
+_bfd_nearby_section (bfd *obfd, asection *s, bfd_vma addr)
+{
+ asection *next, *prev, *best;
+
+ /* Find preceding kept section. */
+ for (prev = s->prev; prev != NULL; prev = prev->prev)
+ if ((prev->flags & SEC_EXCLUDE) == 0
+ && !bfd_section_removed_from_list (obfd, prev))
+ break;
+
+ /* Find following kept section. Start at prev->next because
+ other sections may have been added after S was removed. */
+ if (s->prev != NULL)
+ next = s->prev->next;
+ else
+ next = s->owner->sections;
+ for (; next != NULL; next = next->next)
+ if ((next->flags & SEC_EXCLUDE) == 0
+ && !bfd_section_removed_from_list (obfd, next))
+ break;
+
+ /* 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. */
+ best = next;
+ if (prev == NULL)
+ {
+ if (next == NULL)
+ best = bfd_abs_section_ptr;
+ }
+ else if (next == NULL)
+ best = prev;
+ else if (((prev->flags ^ next->flags)
+ & (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_LOAD)) != 0)
+ {
+ if (((next->flags ^ s->flags)
+ & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0
+ /* We prefer to choose a loaded section. Section S
+ doesn't have SEC_LOAD set (it being excluded, that
+ part of the flag processing didn't happen) so we
+ can't compare that flag to those of NEXT and PREV. */
+ || ((prev->flags & SEC_LOAD) != 0
+ && (next->flags & SEC_LOAD) == 0))
+ best = prev;
+ }
+ else if (((prev->flags ^ next->flags) & SEC_READONLY) != 0)
+ {
+ if (((next->flags ^ s->flags) & SEC_READONLY) != 0)
+ best = prev;
+ }
+ else if (((prev->flags ^ next->flags) & SEC_CODE) != 0)
+ {
+ if (((next->flags ^ s->flags) & SEC_CODE) != 0)
+ best = prev;
+ }
+ else
+ {
+ /* Flags we care about are the same. Prefer the following
+ section if that will result in a positive valued sym. */
+ if (addr < next->vma)
+ best = prev;
+ }
+
+ return best;
+}
+
/* Convert symbols in excluded output sections to use a kept section. */
static bfd_boolean
@@ -3139,68 +3217,10 @@ fix_syms (struct bfd_link_hash_entry *h, void *data)
&& (s->output_section->flags & SEC_EXCLUDE) != 0
&& bfd_section_removed_from_list (obfd, s->output_section))
{
- asection *op, *op1;
+ asection *op;
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;
-
- /* 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 (op == NULL)
- op = bfd_abs_section_ptr;
- }
- else if (op == NULL)
- op = op1;
- else if (((op1->flags ^ op->flags)
- & (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_LOAD)) != 0)
- {
- if (((op->flags ^ s->flags)
- & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0
- /* We prefer to choose a loaded section. Section S
- doesn't have SEC_LOAD set (it being excluded, that
- part of the flag processing didn't happen) so we
- can't compare that flag to those of OP and OP1. */
- || ((op1->flags & SEC_LOAD) != 0
- && (op->flags & SEC_LOAD) == 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;
- }
-
+ op = _bfd_nearby_section (obfd, s->output_section, h->u.def.value);
h->u.def.value -= op->vma;
h->u.def.section = op;
}
« no previous file with comments | « bfd/libbfd-in.h ('k') | bfd/lynx-core.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698