* elf64-ppc.c (ppc64_elf_branch_reloc): Check .opd is in a regular
object file. (struct sfpr_def_parms): Save some space. (sfpr_define): Here too. * elf64-ppc.c (compare_symbols): Put section syms first. (sym_exists_at): New function. (ppc64_elf_get_synthetic_symtab): Use relocs to find code entry points only for relocatable files. Use .opd section contents otherwise. Generally clean up the code.
This commit is contained in:
parent
4b6f5fd267
commit
699733f62e
|
@ -1,3 +1,16 @@
|
||||||
|
2004-08-28 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf64-ppc.c (ppc64_elf_branch_reloc): Check .opd is in a regular
|
||||||
|
object file.
|
||||||
|
(struct sfpr_def_parms): Save some space.
|
||||||
|
(sfpr_define): Here too.
|
||||||
|
|
||||||
|
* elf64-ppc.c (compare_symbols): Put section syms first.
|
||||||
|
(sym_exists_at): New function.
|
||||||
|
(ppc64_elf_get_synthetic_symtab): Use relocs to find code entry
|
||||||
|
points only for relocatable files. Use .opd section contents
|
||||||
|
otherwise. Generally clean up the code.
|
||||||
|
|
||||||
2004-08-27 Alan Modra <amodra@bigpond.net.au>
|
2004-08-27 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* elf64-ppc.c (STD_R0_0R1, STD_R0_0R12, LD_R0_0R1, LD_R0_0R12,
|
* elf64-ppc.c (STD_R0_0R1, STD_R0_0R12, LD_R0_0R1, LD_R0_0R12,
|
||||||
|
|
458
bfd/elf64-ppc.c
458
bfd/elf64-ppc.c
|
@ -2153,7 +2153,8 @@ ppc64_elf_branch_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
|
||||||
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
|
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
|
||||||
input_section, output_bfd, error_message);
|
input_section, output_bfd, error_message);
|
||||||
|
|
||||||
if (strcmp (symbol->section->name, ".opd") == 0)
|
if (strcmp (symbol->section->name, ".opd") == 0
|
||||||
|
&& (symbol->section->owner->flags & DYNAMIC) == 0)
|
||||||
{
|
{
|
||||||
bfd_vma dest = opd_entry_value (symbol->section,
|
bfd_vma dest = opd_entry_value (symbol->section,
|
||||||
symbol->value + reloc_entry->addend,
|
symbol->value + reloc_entry->addend,
|
||||||
|
@ -2549,7 +2550,7 @@ get_opd_info (asection * sec)
|
||||||
static asection *synthetic_opd;
|
static asection *synthetic_opd;
|
||||||
static bfd_boolean synthetic_relocatable;
|
static bfd_boolean synthetic_relocatable;
|
||||||
|
|
||||||
/* Helper routine for ppc64_elf_get_synthetic_symtab. */
|
/* qsort comparison function for ppc64_elf_get_synthetic_symtab. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compare_symbols (const void *ap, const void *bp)
|
compare_symbols (const void *ap, const void *bp)
|
||||||
|
@ -2557,16 +2558,19 @@ compare_symbols (const void *ap, const void *bp)
|
||||||
const asymbol *a = * (const asymbol **) ap;
|
const asymbol *a = * (const asymbol **) ap;
|
||||||
const asymbol *b = * (const asymbol **) bp;
|
const asymbol *b = * (const asymbol **) bp;
|
||||||
|
|
||||||
if ((a->flags & BSF_SECTION_SYM) == 0 && (b->flags & BSF_SECTION_SYM))
|
/* Section symbols first. */
|
||||||
|
if ((a->flags & BSF_SECTION_SYM) && !(b->flags & BSF_SECTION_SYM))
|
||||||
return -1;
|
return -1;
|
||||||
if ((a->flags & BSF_SECTION_SYM) && (b->flags & BSF_SECTION_SYM) == 0)
|
if (!(a->flags & BSF_SECTION_SYM) && (b->flags & BSF_SECTION_SYM))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* then .opd symbols. */
|
||||||
if (a->section == synthetic_opd && b->section != synthetic_opd)
|
if (a->section == synthetic_opd && b->section != synthetic_opd)
|
||||||
return -1;
|
return -1;
|
||||||
if (a->section != synthetic_opd && b->section == synthetic_opd)
|
if (a->section != synthetic_opd && b->section == synthetic_opd)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* then other code symbols. */
|
||||||
if ((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
|
if ((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
|
||||||
== (SEC_CODE | SEC_ALLOC)
|
== (SEC_CODE | SEC_ALLOC)
|
||||||
&& (b->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
|
&& (b->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
|
||||||
|
@ -2597,37 +2601,59 @@ compare_symbols (const void *ap, const void *bp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper routine for ppc64_elf_get_synthetic_symtab. */
|
/* Search SYMS for a symbol of the given VALUE. */
|
||||||
|
|
||||||
static int
|
static asymbol *
|
||||||
compare_relocs (const void *ap, const void *bp)
|
sym_exists_at (asymbol **syms, long lo, long hi, int id, bfd_vma value)
|
||||||
{
|
{
|
||||||
const arelent *a = * (const arelent **) ap;
|
long mid;
|
||||||
const arelent *b = * (const arelent **) bp;
|
|
||||||
|
|
||||||
if (a->address < b->address)
|
if (id == -1)
|
||||||
return -1;
|
{
|
||||||
|
while (lo < hi)
|
||||||
if (a->address > b->address)
|
{
|
||||||
return 1;
|
mid = (lo + hi) >> 1;
|
||||||
|
if (syms[mid]->value + syms[mid]->section->vma < value)
|
||||||
return 0;
|
lo = mid + 1;
|
||||||
|
else if (syms[mid]->value + syms[mid]->section->vma > value)
|
||||||
|
hi = mid;
|
||||||
|
else
|
||||||
|
return syms[mid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (lo < hi)
|
||||||
|
{
|
||||||
|
mid = (lo + hi) >> 1;
|
||||||
|
if (syms[mid]->section->id < id)
|
||||||
|
lo = mid + 1;
|
||||||
|
else if (syms[mid]->section->id > id)
|
||||||
|
hi = mid;
|
||||||
|
else if (syms[mid]->value < value)
|
||||||
|
lo = mid + 1;
|
||||||
|
else if (syms[mid]->value > value)
|
||||||
|
hi = mid;
|
||||||
|
else
|
||||||
|
return syms[mid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create synthetic symbols. */
|
/* Create synthetic symbols, effectively restoring "dot-symbol" function
|
||||||
|
entry syms. */
|
||||||
|
|
||||||
static long
|
static long
|
||||||
ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret)
|
ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret)
|
||||||
{
|
{
|
||||||
asymbol *s;
|
asymbol *s;
|
||||||
bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
|
long i;
|
||||||
arelent **relocs, **r;
|
long count;
|
||||||
long count, i;
|
|
||||||
size_t size;
|
|
||||||
char *names;
|
char *names;
|
||||||
asymbol **syms = NULL;
|
asymbol **syms = NULL;
|
||||||
long symcount = 0, opdsymcount, relcount;
|
long symcount = 0, codesecsym, codesecsymend, secsymend, opdsymend;
|
||||||
asection *relopd, *opd;
|
asection *opd;
|
||||||
bfd_boolean relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
|
bfd_boolean relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
|
||||||
|
|
||||||
*ret = NULL;
|
*ret = NULL;
|
||||||
|
@ -2691,61 +2717,50 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret)
|
||||||
synthetic_relocatable = relocatable;
|
synthetic_relocatable = relocatable;
|
||||||
qsort (syms, symcount, sizeof (asymbol *), compare_symbols);
|
qsort (syms, symcount, sizeof (asymbol *), compare_symbols);
|
||||||
|
|
||||||
opdsymcount = symcount;
|
i = 0;
|
||||||
for (i = 0; i < symcount; ++i)
|
if (syms[i]->section == opd)
|
||||||
{
|
++i;
|
||||||
if (syms[i]->flags & BSF_SECTION_SYM)
|
codesecsym = i;
|
||||||
{
|
|
||||||
if (opdsymcount == symcount)
|
|
||||||
opdsymcount = i;
|
|
||||||
symcount = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (syms[i]->section == opd)
|
for (; i < symcount; ++i)
|
||||||
continue;
|
if (((syms[i]->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
|
||||||
|
!= (SEC_CODE | SEC_ALLOC))
|
||||||
|
|| (syms[i]->flags & BSF_SECTION_SYM) == 0)
|
||||||
|
break;
|
||||||
|
codesecsymend = i;
|
||||||
|
|
||||||
if (opdsymcount == symcount)
|
for (; i < symcount; ++i)
|
||||||
opdsymcount = i;
|
if ((syms[i]->flags & BSF_SECTION_SYM) == 0)
|
||||||
|
break;
|
||||||
|
secsymend = i;
|
||||||
|
|
||||||
if ((syms[i]->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
|
for (; i < symcount; ++i)
|
||||||
!= (SEC_CODE | SEC_ALLOC))
|
if (syms[i]->section != opd)
|
||||||
{
|
break;
|
||||||
symcount = i;
|
opdsymend = i;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opdsymcount == 0)
|
for (; i < symcount; ++i)
|
||||||
|
if ((syms[i]->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
|
||||||
|
!= (SEC_CODE | SEC_ALLOC))
|
||||||
|
break;
|
||||||
|
symcount = i;
|
||||||
|
|
||||||
|
if (opdsymend == secsymend)
|
||||||
{
|
{
|
||||||
free (syms);
|
free (syms);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
|
count = 0;
|
||||||
if (! relocatable)
|
if (relocatable)
|
||||||
{
|
{
|
||||||
relopd = bfd_get_section_by_name (abfd, ".rela.opd");
|
bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
|
||||||
if (relopd == NULL)
|
arelent *r;
|
||||||
{
|
size_t size;
|
||||||
relopd = bfd_get_section_by_name (abfd, ".rela.dyn");
|
long relcount;
|
||||||
if (relopd == NULL)
|
asection *relopd;
|
||||||
{
|
|
||||||
free (syms);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
relcount = relopd->size / 24;
|
|
||||||
|
|
||||||
if (! relcount
|
slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
|
||||||
|| ! (*slurp_relocs) (abfd, relopd, relsyms, TRUE))
|
|
||||||
{
|
|
||||||
free (syms);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
relopd = opd;
|
relopd = opd;
|
||||||
relcount = (opd->flags & SEC_RELOC) ? opd->reloc_count : 0;
|
relcount = (opd->flags & SEC_RELOC) ? opd->reloc_count : 0;
|
||||||
|
|
||||||
|
@ -2755,178 +2770,173 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret)
|
||||||
free (syms);
|
free (syms);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
relocs = bfd_malloc (relcount * sizeof (arelent **));
|
size = 0;
|
||||||
if (relocs == NULL)
|
for (i = secsymend, r = relopd->relocation; i < opdsymend; ++i)
|
||||||
{
|
|
||||||
free (syms);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < relcount; ++i)
|
|
||||||
relocs[i] = &relopd->relocation[i];
|
|
||||||
|
|
||||||
qsort (relocs, relcount, sizeof (*relocs), compare_relocs);
|
|
||||||
|
|
||||||
size = 0;
|
|
||||||
count = 0;
|
|
||||||
for (i = 0, r = relocs; i < opdsymcount; ++i)
|
|
||||||
{
|
|
||||||
long lo, hi, mid;
|
|
||||||
asymbol *sym;
|
|
||||||
|
|
||||||
while (r < relocs + relcount
|
|
||||||
&& (*r)->address < syms[i]->value + opd->vma)
|
|
||||||
++r;
|
|
||||||
|
|
||||||
if (r == relocs + relcount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((*r)->address != syms[i]->value + opd->vma)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((*r)->howto->type != (relocatable
|
|
||||||
? R_PPC64_ADDR64 : R_PPC64_RELATIVE))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
lo = opdsymcount;
|
|
||||||
hi = symcount;
|
|
||||||
sym = *((*r)->sym_ptr_ptr);
|
|
||||||
if (relocatable)
|
|
||||||
while (lo < hi)
|
|
||||||
{
|
|
||||||
mid = (lo + hi) >> 1;
|
|
||||||
if (syms[mid]->section->id < sym->section->id)
|
|
||||||
lo = mid + 1;
|
|
||||||
else if (syms[mid]->section->id > sym->section->id)
|
|
||||||
hi = mid;
|
|
||||||
else if (syms[mid]->value < sym->value + (*r)->addend)
|
|
||||||
lo = mid + 1;
|
|
||||||
else if (syms[mid]->value > sym->value + (*r)->addend)
|
|
||||||
hi = mid;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
while (lo < hi)
|
|
||||||
{
|
|
||||||
mid = (lo + hi) >> 1;
|
|
||||||
if (syms[mid]->value + syms[mid]->section->vma < (*r)->addend)
|
|
||||||
lo = mid + 1;
|
|
||||||
else if (syms[mid]->value + syms[mid]->section->vma > (*r)->addend)
|
|
||||||
hi = mid;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lo >= hi)
|
|
||||||
{
|
{
|
||||||
++count;
|
asymbol *sym;
|
||||||
size += sizeof (asymbol);
|
|
||||||
size += strlen (syms[i]->name) + 1;
|
while (r < relopd->relocation + relcount
|
||||||
|
&& r->address < syms[i]->value + opd->vma)
|
||||||
|
++r;
|
||||||
|
|
||||||
|
if (r == relopd->relocation + relcount)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (r->address != syms[i]->value + opd->vma)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (r->howto->type != R_PPC64_ADDR64)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sym = *r->sym_ptr_ptr;
|
||||||
|
if (!sym_exists_at (syms, opdsymend, symcount,
|
||||||
|
sym->section->id, sym->value + r->addend))
|
||||||
|
{
|
||||||
|
++count;
|
||||||
|
size += sizeof (asymbol);
|
||||||
|
size += strlen (syms[i]->name) + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s = *ret = bfd_malloc (size);
|
||||||
|
if (s == NULL)
|
||||||
|
{
|
||||||
|
free (syms);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
names = (char *) (s + count);
|
||||||
|
|
||||||
|
for (i = secsymend, r = relopd->relocation; i < opdsymend; ++i)
|
||||||
|
{
|
||||||
|
asymbol *sym;
|
||||||
|
|
||||||
|
while (r < relopd->relocation + relcount
|
||||||
|
&& r->address < syms[i]->value + opd->vma)
|
||||||
|
++r;
|
||||||
|
|
||||||
|
if (r == relopd->relocation + relcount)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (r->address != syms[i]->value + opd->vma)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (r->howto->type != R_PPC64_ADDR64)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sym = *r->sym_ptr_ptr;
|
||||||
|
if (!sym_exists_at (syms, opdsymend, symcount,
|
||||||
|
sym->section->id, sym->value + r->addend))
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
*s = *syms[i];
|
||||||
|
s->section = sym->section;
|
||||||
|
s->value = sym->value + r->addend;
|
||||||
|
s->name = names;
|
||||||
|
*names++ = '.';
|
||||||
|
len = strlen (syms[i]->name);
|
||||||
|
memcpy (names, syms[i]->name, len + 1);
|
||||||
|
names += len + 1;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
s = *ret = bfd_malloc (size);
|
|
||||||
if (s == NULL)
|
|
||||||
{
|
{
|
||||||
free (syms);
|
bfd_byte *contents;
|
||||||
free (relocs);
|
size_t size;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
names = (char *) (s + count);
|
if (!bfd_malloc_and_get_section (abfd, opd, &contents))
|
||||||
|
|
||||||
for (i = 0, r = relocs; i < opdsymcount; ++i)
|
|
||||||
{
|
|
||||||
long lo, hi, mid;
|
|
||||||
asymbol *sym;
|
|
||||||
|
|
||||||
while (r < relocs + relcount
|
|
||||||
&& (*r)->address < syms[i]->value + opd->vma)
|
|
||||||
++r;
|
|
||||||
|
|
||||||
if (r == relocs + relcount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((*r)->address != syms[i]->value + opd->vma)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((*r)->howto->type != (relocatable
|
|
||||||
? R_PPC64_ADDR64 : R_PPC64_RELATIVE))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
lo = opdsymcount;
|
|
||||||
hi = symcount;
|
|
||||||
sym = *((*r)->sym_ptr_ptr);
|
|
||||||
if (relocatable)
|
|
||||||
while (lo < hi)
|
|
||||||
{
|
|
||||||
mid = (lo + hi) >> 1;
|
|
||||||
if (syms[mid]->section->id < sym->section->id)
|
|
||||||
lo = mid + 1;
|
|
||||||
else if (syms[mid]->section->id > sym->section->id)
|
|
||||||
hi = mid;
|
|
||||||
else if (syms[mid]->value < sym->value + (*r)->addend)
|
|
||||||
lo = mid + 1;
|
|
||||||
else if (syms[mid]->value > sym->value + (*r)->addend)
|
|
||||||
hi = mid;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
while (lo < hi)
|
|
||||||
{
|
|
||||||
mid = (lo + hi) >> 1;
|
|
||||||
if (syms[mid]->value + syms[mid]->section->vma < (*r)->addend)
|
|
||||||
lo = mid + 1;
|
|
||||||
else if (syms[mid]->value + syms[mid]->section->vma > (*r)->addend)
|
|
||||||
hi = mid;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lo >= hi)
|
|
||||||
{
|
{
|
||||||
size_t len;
|
if (contents)
|
||||||
|
free (contents);
|
||||||
|
free (syms);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
*s = *syms[i];
|
size = 0;
|
||||||
|
for (i = secsymend; i < opdsymend; ++i)
|
||||||
if (! relocatable)
|
{
|
||||||
|
bfd_vma ent;
|
||||||
|
|
||||||
|
ent = bfd_get_64 (abfd, contents + syms[i]->value);
|
||||||
|
if (!sym_exists_at (syms, opdsymend, symcount, -1, ent))
|
||||||
{
|
{
|
||||||
|
++count;
|
||||||
|
size += sizeof (asymbol);
|
||||||
|
size += strlen (syms[i]->name) + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s = *ret = bfd_malloc (size);
|
||||||
|
if (s == NULL)
|
||||||
|
{
|
||||||
|
free (contents);
|
||||||
|
free (syms);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
names = (char *) (s + count);
|
||||||
|
|
||||||
|
for (i = secsymend; i < opdsymend; ++i)
|
||||||
|
{
|
||||||
|
bfd_vma ent;
|
||||||
|
|
||||||
|
ent = bfd_get_64 (abfd, contents + syms[i]->value);
|
||||||
|
if (!sym_exists_at (syms, opdsymend, symcount, -1, ent))
|
||||||
|
{
|
||||||
|
long lo, hi, mid;
|
||||||
|
size_t len;
|
||||||
asection *sec;
|
asection *sec;
|
||||||
|
|
||||||
s->section = &bfd_abs_section;
|
*s = *syms[i];
|
||||||
for (sec = abfd->sections; sec; sec = sec->next)
|
lo = codesecsym;
|
||||||
if ((sec->flags & (SEC_ALLOC | SEC_CODE))
|
hi = codesecsymend;
|
||||||
== (SEC_ALLOC | SEC_CODE)
|
while (lo < hi)
|
||||||
&& (*r)->addend >= sec->vma
|
{
|
||||||
&& (*r)->addend < sec->vma + sec->size)
|
mid = (lo + hi) >> 1;
|
||||||
{
|
if (syms[mid]->section->vma < ent)
|
||||||
s->section = sec;
|
lo = mid + 1;
|
||||||
|
else if (syms[mid]->section->vma > ent)
|
||||||
|
hi = mid;
|
||||||
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
s->value = (*r)->addend - sec->vma;
|
|
||||||
|
if (lo < hi)
|
||||||
|
sec = syms[mid]->section;
|
||||||
|
else if (lo > codesecsym)
|
||||||
|
sec = syms[lo - 1]->section;
|
||||||
|
else
|
||||||
|
sec = abfd->sections;
|
||||||
|
|
||||||
|
for (; sec != NULL; sec = sec->next)
|
||||||
|
{
|
||||||
|
if (sec->vma > ent)
|
||||||
|
break;
|
||||||
|
if ((sec->flags & SEC_ALLOC) == 0
|
||||||
|
|| (sec->flags & SEC_LOAD) == 0)
|
||||||
|
break;
|
||||||
|
if ((sec->flags & SEC_CODE) != 0)
|
||||||
|
s->section = sec;
|
||||||
|
}
|
||||||
|
s->value = ent - s->section->vma;
|
||||||
|
s->name = names;
|
||||||
|
*names++ = '.';
|
||||||
|
len = strlen (syms[i]->name);
|
||||||
|
memcpy (names, syms[i]->name, len + 1);
|
||||||
|
names += len + 1;
|
||||||
|
s++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
s->section = sym->section;
|
|
||||||
s->value = sym->value + (*r)->addend;
|
|
||||||
}
|
|
||||||
s->name = names;
|
|
||||||
len = strlen (syms[i]->name);
|
|
||||||
memcpy (names, syms[i]->name, len + 1);
|
|
||||||
names += len + 1;
|
|
||||||
s++;
|
|
||||||
}
|
}
|
||||||
|
free (contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (syms);
|
free (syms);
|
||||||
free (relocs);
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The following functions are specific to the ELF linker, while
|
/* The following functions are specific to the ELF linker, while
|
||||||
functions above are used generally. Those named ppc64_elf_* are
|
functions above are used generally. Those named ppc64_elf_* are
|
||||||
|
@ -5050,8 +5060,8 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
|
||||||
|
|
||||||
struct sfpr_def_parms
|
struct sfpr_def_parms
|
||||||
{
|
{
|
||||||
const char *name;
|
const char name[12];
|
||||||
unsigned int lo, hi;
|
unsigned char lo, hi;
|
||||||
bfd_byte * (*write_ent) (bfd *, bfd_byte *, int);
|
bfd_byte * (*write_ent) (bfd *, bfd_byte *, int);
|
||||||
bfd_byte * (*write_tail) (bfd *, bfd_byte *, int);
|
bfd_byte * (*write_tail) (bfd *, bfd_byte *, int);
|
||||||
};
|
};
|
||||||
|
@ -5065,7 +5075,7 @@ sfpr_define (struct bfd_link_info *info, const struct sfpr_def_parms *parm)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
size_t len = strlen (parm->name);
|
size_t len = strlen (parm->name);
|
||||||
bfd_boolean writing = FALSE;
|
bfd_boolean writing = FALSE;
|
||||||
char sym[20];
|
char sym[16];
|
||||||
|
|
||||||
memcpy (sym, parm->name, len);
|
memcpy (sym, parm->name, len);
|
||||||
sym[len + 2] = 0;
|
sym[len + 2] = 0;
|
||||||
|
@ -6263,7 +6273,7 @@ ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
|
||||||
p = bfd_malloc (need_pad->size + 8);
|
p = bfd_malloc (need_pad->size + 8);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (! bfd_get_section_contents (need_pad->owner, need_pad,
|
if (! bfd_get_section_contents (need_pad->owner, need_pad,
|
||||||
p, 0, need_pad->size))
|
p, 0, need_pad->size))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in New Issue