mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-12-01 07:50:49 +00:00
* write.c (resolve_reloc_expr_symbols): Convert local symbols
on relocs to section+offset. (get_frag_for_reloc): New function. (write_relocs): Merge sort fixup relocs with those from .reloc directives.
This commit is contained in:
parent
9d4b600942
commit
7230378dfd
@ -1,3 +1,11 @@
|
||||
2011-08-18 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* write.c (resolve_reloc_expr_symbols): Convert local symbols
|
||||
on relocs to section+offset.
|
||||
(get_frag_for_reloc): New function.
|
||||
(write_relocs): Merge sort fixup relocs with those from .reloc
|
||||
directives.
|
||||
|
||||
2011-08-10 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
* config/tc-mips.c (can_swap_branch_p): Update the comment on
|
||||
|
123
gas/write.c
123
gas/write.c
@ -1,7 +1,7 @@
|
||||
/* write.c - emit .o file
|
||||
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
2010 Free Software Foundation, Inc.
|
||||
2010, 2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
@ -708,7 +708,20 @@ resolve_reloc_expr_symbols (void)
|
||||
sec = NULL;
|
||||
}
|
||||
else if (sym != NULL)
|
||||
symbol_mark_used_in_reloc (sym);
|
||||
{
|
||||
if (S_IS_LOCAL (sym) && !symbol_section_p (sym))
|
||||
{
|
||||
asection *symsec = S_GET_SEGMENT (sym);
|
||||
if (!(((symsec->flags & SEC_MERGE) != 0
|
||||
&& addend != 0)
|
||||
|| (symsec->flags & SEC_THREAD_LOCAL) != 0))
|
||||
{
|
||||
addend += S_GET_VALUE (sym);
|
||||
sym = section_symbol (symsec);
|
||||
}
|
||||
}
|
||||
symbol_mark_used_in_reloc (sym);
|
||||
}
|
||||
}
|
||||
if (sym == NULL)
|
||||
{
|
||||
@ -1146,15 +1159,37 @@ install_reloc (asection *sec, arelent *reloc, fragS *fragp,
|
||||
}
|
||||
}
|
||||
|
||||
static fragS *
|
||||
get_frag_for_reloc (fragS *last_frag,
|
||||
const segment_info_type *seginfo,
|
||||
const struct reloc_list *r)
|
||||
{
|
||||
fragS *f;
|
||||
|
||||
for (f = last_frag; f != NULL; f = f->fr_next)
|
||||
if (f->fr_address <= r->u.b.r.address
|
||||
&& r->u.b.r.address < f->fr_address + f->fr_fix)
|
||||
return f;
|
||||
|
||||
for (f = seginfo->frchainP->frch_root; f != NULL; f = f->fr_next)
|
||||
if (f->fr_address <= r->u.b.r.address
|
||||
&& r->u.b.r.address < f->fr_address + f->fr_fix)
|
||||
return f;
|
||||
|
||||
as_bad_where (r->file, r->line,
|
||||
_("reloc not within (fixed part of) section"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
|
||||
{
|
||||
segment_info_type *seginfo = seg_info (sec);
|
||||
unsigned int i;
|
||||
unsigned int n;
|
||||
struct reloc_list *my_reloc_list, **rp, *r;
|
||||
arelent **relocs;
|
||||
fixS *fixp;
|
||||
fragS *last_frag;
|
||||
|
||||
/* If seginfo is NULL, we did not create this section; don't do
|
||||
anything with it. */
|
||||
@ -1188,12 +1223,19 @@ write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
|
||||
|
||||
relocs = (arelent **) xcalloc (n, sizeof (arelent *));
|
||||
|
||||
i = 0;
|
||||
n = 0;
|
||||
r = my_reloc_list;
|
||||
last_frag = NULL;
|
||||
for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
|
||||
{
|
||||
int j;
|
||||
int fx_size, slack;
|
||||
offsetT loc;
|
||||
arelent **reloc;
|
||||
#ifndef RELOC_EXPANSION_POSSIBLE
|
||||
arelent *rel;
|
||||
|
||||
reloc = &rel;
|
||||
#endif
|
||||
|
||||
if (fixp->fx_done)
|
||||
continue;
|
||||
@ -1208,28 +1250,46 @@ write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
|
||||
_("internal error: fixup not contained within frag"));
|
||||
|
||||
#ifndef RELOC_EXPANSION_POSSIBLE
|
||||
{
|
||||
arelent *reloc = tc_gen_reloc (sec, fixp);
|
||||
|
||||
if (!reloc)
|
||||
continue;
|
||||
relocs[i++] = reloc;
|
||||
j = 1;
|
||||
}
|
||||
*reloc = tc_gen_reloc (sec, fixp);
|
||||
#else
|
||||
{
|
||||
arelent **reloc = tc_gen_reloc (sec, fixp);
|
||||
|
||||
for (j = 0; reloc[j]; j++)
|
||||
relocs[i++] = reloc[j];
|
||||
}
|
||||
reloc = tc_gen_reloc (sec, fixp);
|
||||
#endif
|
||||
|
||||
for ( ; j != 0; --j)
|
||||
install_reloc (sec, relocs[i - j], fixp->fx_frag,
|
||||
fixp->fx_file, fixp->fx_line);
|
||||
while (*reloc)
|
||||
{
|
||||
while (r != NULL && r->u.b.r.address < (*reloc)->address)
|
||||
{
|
||||
fragS *f = get_frag_for_reloc (last_frag, seginfo, r);
|
||||
if (f != NULL)
|
||||
{
|
||||
last_frag = f;
|
||||
relocs[n++] = &r->u.b.r;
|
||||
install_reloc (sec, &r->u.b.r, f, r->file, r->line);
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
relocs[n++] = *reloc;
|
||||
install_reloc (sec, *reloc, fixp->fx_frag,
|
||||
fixp->fx_file, fixp->fx_line);
|
||||
#ifndef RELOC_EXPANSION_POSSIBLE
|
||||
break;
|
||||
#else
|
||||
reloc++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
while (r != NULL)
|
||||
{
|
||||
fragS *f = get_frag_for_reloc (last_frag, seginfo, r);
|
||||
if (f != NULL)
|
||||
{
|
||||
last_frag = f;
|
||||
relocs[n++] = &r->u.b.r;
|
||||
install_reloc (sec, &r->u.b.r, f, r->file, r->line);
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
n = i;
|
||||
|
||||
#ifdef DEBUG4
|
||||
{
|
||||
@ -1249,23 +1309,6 @@ write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
|
||||
}
|
||||
#endif
|
||||
|
||||
for (r = my_reloc_list; r != NULL; r = r->next)
|
||||
{
|
||||
fragS *f;
|
||||
for (f = seginfo->frchainP->frch_root; f; f = f->fr_next)
|
||||
if (f->fr_address <= r->u.b.r.address
|
||||
&& r->u.b.r.address < f->fr_address + f->fr_fix)
|
||||
break;
|
||||
if (f == NULL)
|
||||
as_bad_where (r->file, r->line,
|
||||
_("reloc not within (fixed part of) section"));
|
||||
else
|
||||
{
|
||||
relocs[n++] = &r->u.b.r;
|
||||
install_reloc (sec, &r->u.b.r, f, r->file, r->line);
|
||||
}
|
||||
}
|
||||
|
||||
if (n)
|
||||
{
|
||||
flagword flags = bfd_get_section_flags (abfd, sec);
|
||||
|
Loading…
Reference in New Issue
Block a user