mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
* elf-bfd.h (_bfd_elf_create_linker_section) Don't declare.
(_bfd_elf_find_pointer_linker_section): Likewise. (bfd_elf32_create_pointer_linker_section): Likewise. (bfd_elf32_finish_pointer_linker_section): Likewise. (bfd_elf64_create_pointer_linker_section): Likewise. (bfd_elf64_finish_pointer_linker_section): Likewise. (_bfd_elf_make_linker_section_rela): Likewise. * elfcode.h (elf_create_pointer_linker_section): Don't define. (elf_finish_pointer_linker_section): Likewise. * elflink.c (_bfd_elf_make_linker_section_rela): Delete. (_bfd_elf_create_linker_section): Move this function.. (_bfd_elf_find_pointer_linker_section): ..and this.. * elflink.h (elf_create_pointer_linker_section): ..and this.. (elf_finish_pointer_linker_section): ..and this.. * elf32-ppc.c: ..to here, renaming to the following, and adjusting calls. (elf_create_linker_section): Convert to C90, tidy. (elf_find_pointer_linker_section): Likewise. (elf_create_pointer_linker_section): Likewise. (elf_finish_pointer_linker_section): Likewise. * elf32-i370.c: Delete #if 0 code.
This commit is contained in:
parent
100f2e98f8
commit
3dab13f62b
@ -1,3 +1,27 @@
|
||||
2003-07-03 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf-bfd.h (_bfd_elf_create_linker_section) Don't declare.
|
||||
(_bfd_elf_find_pointer_linker_section): Likewise.
|
||||
(bfd_elf32_create_pointer_linker_section): Likewise.
|
||||
(bfd_elf32_finish_pointer_linker_section): Likewise.
|
||||
(bfd_elf64_create_pointer_linker_section): Likewise.
|
||||
(bfd_elf64_finish_pointer_linker_section): Likewise.
|
||||
(_bfd_elf_make_linker_section_rela): Likewise.
|
||||
* elfcode.h (elf_create_pointer_linker_section): Don't define.
|
||||
(elf_finish_pointer_linker_section): Likewise.
|
||||
* elflink.c (_bfd_elf_make_linker_section_rela): Delete.
|
||||
(_bfd_elf_create_linker_section): Move this function..
|
||||
(_bfd_elf_find_pointer_linker_section): ..and this..
|
||||
* elflink.h (elf_create_pointer_linker_section): ..and this..
|
||||
(elf_finish_pointer_linker_section): ..and this..
|
||||
* elf32-ppc.c: ..to here, renaming to the following, and adjusting
|
||||
calls.
|
||||
(elf_create_linker_section): Convert to C90, tidy.
|
||||
(elf_find_pointer_linker_section): Likewise.
|
||||
(elf_create_pointer_linker_section): Likewise.
|
||||
(elf_finish_pointer_linker_section): Likewise.
|
||||
* elf32-i370.c: Delete #if 0 code.
|
||||
|
||||
2003-07-02 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf64-ppc.c (ppc64_elf_func_desc_adjust): Don't allow _savef* and
|
||||
@ -3565,8 +3589,8 @@
|
||||
(aout_link_write_symbols): Cast enums in comparisons, int values to
|
||||
boolean, enums in assignments to int.
|
||||
(aout_link_input_section_std): Cast rel->r_index to unsigned int.
|
||||
(aout_link_input_section_ext): Likewise. Cast enums used in comparisons
|
||||
with unsigned ints.
|
||||
(aout_link_input_section_ext): Likewise. Cast enums used in
|
||||
comparisons with unsigned ints.
|
||||
(aout_link_reloc_link_order): Cast enum to int in assignment.
|
||||
* archive.c (_bfd_generic_read_ar_hdr_mag): Cast result of memchr
|
||||
calls to char *.
|
||||
@ -3597,8 +3621,8 @@
|
||||
(merge_strings): Add casts to const unsigned char *.
|
||||
* reloc.c (bfd_get_reloc_code_name): Cast enums in comparison to int.
|
||||
(bfd_generic_get_relocated_section_content): Cast enum to unsigned int.
|
||||
* section.c (bfd_section_hash_newfunc): Cast bfd_hash_allocate result to
|
||||
struct bfd_hash_entry *.
|
||||
* section.c (bfd_section_hash_newfunc): Cast bfd_hash_allocate result
|
||||
to struct bfd_hash_entry *.
|
||||
(bfd_set_section_content): Add cast to PTR in comparison.
|
||||
* simple.c (simple_dummy_warning, simple_dummy_undefined_symbol,
|
||||
simple_dummy_reloc_overflow, simple_dummy_reloc_dangerous,
|
||||
|
@ -1554,35 +1554,6 @@ extern bfd_boolean _bfd_elfcore_make_pseudosection
|
||||
extern char *_bfd_elfcore_strndup
|
||||
PARAMS ((bfd *, char *, size_t));
|
||||
|
||||
extern elf_linker_section_t *_bfd_elf_create_linker_section
|
||||
PARAMS ((bfd *, struct bfd_link_info *, enum elf_linker_section_enum,
|
||||
elf_linker_section_t *));
|
||||
|
||||
extern elf_linker_section_pointers_t *_bfd_elf_find_pointer_linker_section
|
||||
PARAMS ((elf_linker_section_pointers_t *, bfd_vma,
|
||||
elf_linker_section_enum_t));
|
||||
|
||||
extern bfd_boolean bfd_elf32_create_pointer_linker_section
|
||||
PARAMS ((bfd *, struct bfd_link_info *, elf_linker_section_t *,
|
||||
struct elf_link_hash_entry *, const Elf_Internal_Rela *));
|
||||
|
||||
extern bfd_vma bfd_elf32_finish_pointer_linker_section
|
||||
PARAMS ((bfd *, bfd *, struct bfd_link_info *, elf_linker_section_t *,
|
||||
struct elf_link_hash_entry *, bfd_vma,
|
||||
const Elf_Internal_Rela *, int));
|
||||
|
||||
extern bfd_boolean bfd_elf64_create_pointer_linker_section
|
||||
PARAMS ((bfd *, struct bfd_link_info *, elf_linker_section_t *,
|
||||
struct elf_link_hash_entry *, const Elf_Internal_Rela *));
|
||||
|
||||
extern bfd_vma bfd_elf64_finish_pointer_linker_section
|
||||
PARAMS ((bfd *, bfd *, struct bfd_link_info *, elf_linker_section_t *,
|
||||
struct elf_link_hash_entry *, bfd_vma,
|
||||
const Elf_Internal_Rela *, int));
|
||||
|
||||
extern bfd_boolean _bfd_elf_make_linker_section_rela
|
||||
PARAMS ((bfd *, elf_linker_section_t *, int));
|
||||
|
||||
extern Elf_Internal_Rela *_bfd_elf_link_read_relocs
|
||||
PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, bfd_boolean));
|
||||
|
||||
|
@ -290,11 +290,6 @@ static bfd_boolean i370_elf_section_from_shdr
|
||||
PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
|
||||
static bfd_boolean i370_elf_fake_sections
|
||||
PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
|
||||
#if 0
|
||||
static elf_linker_section_t *i370_elf_create_linker_section
|
||||
PARAMS ((bfd *abfd, struct bfd_link_info *info,
|
||||
enum elf_linker_section_enum));
|
||||
#endif
|
||||
static bfd_boolean i370_elf_check_relocs
|
||||
PARAMS ((bfd *, struct bfd_link_info *, asection *,
|
||||
const Elf_Internal_Rela *));
|
||||
@ -434,84 +429,6 @@ i370_elf_fake_sections (abfd, shdr, asect)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Create a special linker section */
|
||||
/* XXX hack alert bogus This routine is mostly all junk and almost
|
||||
* certainly does the wrong thing. Its here simply because it does
|
||||
* just enough to allow glibc-2.1 ld.so to compile & link.
|
||||
*/
|
||||
|
||||
static elf_linker_section_t *
|
||||
i370_elf_create_linker_section (abfd, info, which)
|
||||
bfd *abfd;
|
||||
struct bfd_link_info *info;
|
||||
enum elf_linker_section_enum which;
|
||||
{
|
||||
bfd *dynobj = elf_hash_table (info)->dynobj;
|
||||
elf_linker_section_t *lsect;
|
||||
|
||||
/* Record the first bfd section that needs the special section */
|
||||
if (!dynobj)
|
||||
dynobj = elf_hash_table (info)->dynobj = abfd;
|
||||
|
||||
/* If this is the first time, create the section */
|
||||
lsect = elf_linker_section (dynobj, which);
|
||||
if (!lsect)
|
||||
{
|
||||
elf_linker_section_t defaults;
|
||||
static elf_linker_section_t zero_section;
|
||||
|
||||
defaults = zero_section;
|
||||
defaults.which = which;
|
||||
defaults.hole_written_p = FALSE;
|
||||
defaults.alignment = 2;
|
||||
|
||||
/* Both of these sections are (technically) created by the user
|
||||
putting data in them, so they shouldn't be marked
|
||||
SEC_LINKER_CREATED.
|
||||
|
||||
The linker creates them so it has somewhere to attach their
|
||||
respective symbols. In fact, if they were empty it would
|
||||
be OK to leave the symbol set to 0 (or any random number), because
|
||||
the appropriate register should never be used. */
|
||||
defaults.flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
|
||||
| SEC_IN_MEMORY);
|
||||
|
||||
switch (which)
|
||||
{
|
||||
default:
|
||||
(*_bfd_error_handler) ("%s: Unknown special linker type %d",
|
||||
bfd_archive_filename (abfd),
|
||||
(int) which);
|
||||
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return (elf_linker_section_t *)0;
|
||||
|
||||
case LINKER_SECTION_SDATA: /* .sdata/.sbss section */
|
||||
defaults.name = ".sdata";
|
||||
defaults.rel_name = ".rela.sdata";
|
||||
defaults.bss_name = ".sbss";
|
||||
defaults.sym_name = "_SDA_BASE_";
|
||||
defaults.sym_offset = 32768;
|
||||
break;
|
||||
|
||||
case LINKER_SECTION_SDATA2: /* .sdata2/.sbss2 section */
|
||||
defaults.name = ".sdata2";
|
||||
defaults.rel_name = ".rela.sdata2";
|
||||
defaults.bss_name = ".sbss2";
|
||||
defaults.sym_name = "_SDA2_BASE_";
|
||||
defaults.sym_offset = 32768;
|
||||
defaults.flags |= SEC_READONLY;
|
||||
break;
|
||||
}
|
||||
|
||||
lsect = _bfd_elf_create_linker_section (abfd, info, which, &defaults);
|
||||
}
|
||||
|
||||
return lsect;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We have to create .dynsbss and .rela.sbss here so that they get mapped
|
||||
to output sections (just like _bfd_elf_create_dynamic_sections has
|
||||
to create .dynbss and .rela.bss). */
|
||||
|
384
bfd/elf32-ppc.c
384
bfd/elf32-ppc.c
@ -2169,6 +2169,360 @@ ppc_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Create a special linker section, or return a pointer to a linker
|
||||
section already created */
|
||||
|
||||
static elf_linker_section_t *
|
||||
elf_create_linker_section (bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
enum elf_linker_section_enum which,
|
||||
elf_linker_section_t *defaults)
|
||||
{
|
||||
bfd *dynobj = elf_hash_table (info)->dynobj;
|
||||
elf_linker_section_t *lsect;
|
||||
|
||||
/* Record the first bfd section that needs the special section */
|
||||
if (!dynobj)
|
||||
dynobj = elf_hash_table (info)->dynobj = abfd;
|
||||
|
||||
/* If this is the first time, create the section */
|
||||
lsect = elf_linker_section (dynobj, which);
|
||||
if (!lsect)
|
||||
{
|
||||
asection *s;
|
||||
bfd_size_type amt = sizeof (elf_linker_section_t);
|
||||
|
||||
lsect = bfd_alloc (dynobj, amt);
|
||||
|
||||
*lsect = *defaults;
|
||||
elf_linker_section (dynobj, which) = lsect;
|
||||
lsect->which = which;
|
||||
lsect->hole_written_p = FALSE;
|
||||
|
||||
/* See if the sections already exist */
|
||||
lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name);
|
||||
if (!s || (s->flags & defaults->flags) != defaults->flags)
|
||||
{
|
||||
lsect->section = s = bfd_make_section_anyway (dynobj, lsect->name);
|
||||
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
bfd_set_section_flags (dynobj, s, defaults->flags);
|
||||
bfd_set_section_alignment (dynobj, s, lsect->alignment);
|
||||
}
|
||||
else if (bfd_get_section_alignment (dynobj, s) < lsect->alignment)
|
||||
bfd_set_section_alignment (dynobj, s, lsect->alignment);
|
||||
|
||||
s->_raw_size = align_power (s->_raw_size, lsect->alignment);
|
||||
|
||||
/* Is there a hole we have to provide? If so check whether the
|
||||
segment is too big already */
|
||||
if (lsect->hole_size)
|
||||
{
|
||||
lsect->hole_offset = s->_raw_size;
|
||||
s->_raw_size += lsect->hole_size;
|
||||
if (lsect->hole_offset > lsect->max_hole_offset)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: Section %s is too large to add hole of %ld bytes"),
|
||||
bfd_get_filename (abfd),
|
||||
lsect->name,
|
||||
(long) lsect->hole_size);
|
||||
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Creating section %s, current size = %ld\n",
|
||||
lsect->name, (long) s->_raw_size);
|
||||
#endif
|
||||
|
||||
if (lsect->sym_name)
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
struct bfd_link_hash_entry *bh;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Adding %s to section %s\n",
|
||||
lsect->sym_name,
|
||||
lsect->name);
|
||||
#endif
|
||||
bh = bfd_link_hash_lookup (info->hash, lsect->sym_name,
|
||||
FALSE, FALSE, FALSE);
|
||||
|
||||
if ((bh == NULL || bh->type == bfd_link_hash_undefined)
|
||||
&& !(_bfd_generic_link_add_one_symbol
|
||||
(info, abfd, lsect->sym_name, BSF_GLOBAL, s,
|
||||
(lsect->hole_size
|
||||
? s->_raw_size - lsect->hole_size + lsect->sym_offset
|
||||
: lsect->sym_offset),
|
||||
NULL, FALSE,
|
||||
get_elf_backend_data (abfd)->collect, &bh)))
|
||||
return NULL;
|
||||
h = (struct elf_link_hash_entry *) bh;
|
||||
|
||||
if ((defaults->which != LINKER_SECTION_SDATA)
|
||||
&& (defaults->which != LINKER_SECTION_SDATA2))
|
||||
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC;
|
||||
|
||||
h->type = STT_OBJECT;
|
||||
lsect->sym_hash = h;
|
||||
|
||||
if (info->shared
|
||||
&& ! _bfd_elf_link_record_dynamic_symbol (info, h))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return lsect;
|
||||
}
|
||||
|
||||
/* Find a linker generated pointer with a given addend and type. */
|
||||
|
||||
static elf_linker_section_pointers_t *
|
||||
elf_find_pointer_linker_section
|
||||
(elf_linker_section_pointers_t *linker_pointers,
|
||||
bfd_vma addend,
|
||||
elf_linker_section_enum_t which)
|
||||
{
|
||||
for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)
|
||||
if (which == linker_pointers->which && addend == linker_pointers->addend)
|
||||
return linker_pointers;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate a pointer to live in a linker created section. */
|
||||
|
||||
static bfd_boolean
|
||||
elf_create_pointer_linker_section (bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
elf_linker_section_t *lsect,
|
||||
struct elf_link_hash_entry *h,
|
||||
const Elf_Internal_Rela *rel)
|
||||
{
|
||||
elf_linker_section_pointers_t **ptr_linker_section_ptr = NULL;
|
||||
elf_linker_section_pointers_t *linker_section_ptr;
|
||||
unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
bfd_size_type amt;
|
||||
|
||||
BFD_ASSERT (lsect != NULL);
|
||||
|
||||
/* Is this a global symbol? */
|
||||
if (h != NULL)
|
||||
{
|
||||
/* Has this symbol already been allocated? If so, our work is done. */
|
||||
if (elf_find_pointer_linker_section (h->linker_section_pointer,
|
||||
rel->r_addend,
|
||||
lsect->which))
|
||||
return TRUE;
|
||||
|
||||
ptr_linker_section_ptr = &h->linker_section_pointer;
|
||||
/* Make sure this symbol is output as a dynamic symbol. */
|
||||
if (h->dynindx == -1)
|
||||
{
|
||||
if (! _bfd_elf_link_record_dynamic_symbol (info, h))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lsect->rel_section)
|
||||
lsect->rel_section->_raw_size += sizeof (Elf32_External_Rela);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocation of a pointer to a local symbol. */
|
||||
elf_linker_section_pointers_t **ptr = elf_local_ptr_offsets (abfd);
|
||||
|
||||
/* Allocate a table to hold the local symbols if first time. */
|
||||
if (!ptr)
|
||||
{
|
||||
unsigned int num_symbols = elf_tdata (abfd)->symtab_hdr.sh_info;
|
||||
register unsigned int i;
|
||||
|
||||
amt = num_symbols;
|
||||
amt *= sizeof (elf_linker_section_pointers_t *);
|
||||
ptr = bfd_alloc (abfd, amt);
|
||||
|
||||
if (!ptr)
|
||||
return FALSE;
|
||||
|
||||
elf_local_ptr_offsets (abfd) = ptr;
|
||||
for (i = 0; i < num_symbols; i++)
|
||||
ptr[i] = NULL;
|
||||
}
|
||||
|
||||
/* Has this symbol already been allocated? If so, our work is done. */
|
||||
if (elf_find_pointer_linker_section (ptr[r_symndx],
|
||||
rel->r_addend,
|
||||
lsect->which))
|
||||
return TRUE;
|
||||
|
||||
ptr_linker_section_ptr = &ptr[r_symndx];
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
/* If we are generating a shared object, we need to
|
||||
output a R_<xxx>_RELATIVE reloc so that the
|
||||
dynamic linker can adjust this GOT entry. */
|
||||
BFD_ASSERT (lsect->rel_section != NULL);
|
||||
lsect->rel_section->_raw_size += sizeof (Elf32_External_Rela);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate space for a pointer in the linker section, and allocate
|
||||
a new pointer record from internal memory. */
|
||||
BFD_ASSERT (ptr_linker_section_ptr != NULL);
|
||||
amt = sizeof (elf_linker_section_pointers_t);
|
||||
linker_section_ptr = bfd_alloc (abfd, amt);
|
||||
|
||||
if (!linker_section_ptr)
|
||||
return FALSE;
|
||||
|
||||
linker_section_ptr->next = *ptr_linker_section_ptr;
|
||||
linker_section_ptr->addend = rel->r_addend;
|
||||
linker_section_ptr->which = lsect->which;
|
||||
linker_section_ptr->written_address_p = FALSE;
|
||||
*ptr_linker_section_ptr = linker_section_ptr;
|
||||
|
||||
linker_section_ptr->offset = lsect->section->_raw_size;
|
||||
lsect->section->_raw_size += 4;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr,
|
||||
"Create pointer in linker section %s, offset = %ld, section size = %ld\n",
|
||||
lsect->name, (long) linker_section_ptr->offset,
|
||||
(long) lsect->section->_raw_size);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define bfd_put_ptr(BFD, VAL, ADDR) bfd_put_32 (BFD, VAL, ADDR)
|
||||
|
||||
/* Fill in the address for a pointer generated in a linker section. */
|
||||
|
||||
static bfd_vma
|
||||
elf_finish_pointer_linker_section (bfd *output_bfd,
|
||||
bfd *input_bfd,
|
||||
struct bfd_link_info *info,
|
||||
elf_linker_section_t *lsect,
|
||||
struct elf_link_hash_entry *h,
|
||||
bfd_vma relocation,
|
||||
const Elf_Internal_Rela *rel,
|
||||
int relative_reloc)
|
||||
{
|
||||
elf_linker_section_pointers_t *linker_section_ptr;
|
||||
|
||||
BFD_ASSERT (lsect != NULL);
|
||||
|
||||
if (h != NULL)
|
||||
{
|
||||
/* Handle global symbol. */
|
||||
linker_section_ptr
|
||||
= elf_find_pointer_linker_section (h->linker_section_pointer,
|
||||
rel->r_addend,
|
||||
lsect->which);
|
||||
|
||||
BFD_ASSERT (linker_section_ptr != NULL);
|
||||
|
||||
if (! elf_hash_table (info)->dynamic_sections_created
|
||||
|| (info->shared
|
||||
&& info->symbolic
|
||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
|
||||
{
|
||||
/* This is actually a static link, or it is a
|
||||
-Bsymbolic link and the symbol is defined
|
||||
locally. We must initialize this entry in the
|
||||
global section.
|
||||
|
||||
When doing a dynamic link, we create a .rela.<xxx>
|
||||
relocation entry to initialize the value. This
|
||||
is done in the finish_dynamic_symbol routine. */
|
||||
if (!linker_section_ptr->written_address_p)
|
||||
{
|
||||
linker_section_ptr->written_address_p = TRUE;
|
||||
bfd_put_ptr (output_bfd,
|
||||
relocation + linker_section_ptr->addend,
|
||||
(lsect->section->contents
|
||||
+ linker_section_ptr->offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle local symbol. */
|
||||
unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
BFD_ASSERT (elf_local_ptr_offsets (input_bfd) != NULL);
|
||||
BFD_ASSERT (elf_local_ptr_offsets (input_bfd)[r_symndx] != NULL);
|
||||
linker_section_ptr = (elf_find_pointer_linker_section
|
||||
(elf_local_ptr_offsets (input_bfd)[r_symndx],
|
||||
rel->r_addend,
|
||||
lsect->which));
|
||||
|
||||
BFD_ASSERT (linker_section_ptr != NULL);
|
||||
|
||||
/* Write out pointer if it hasn't been rewritten out before. */
|
||||
if (!linker_section_ptr->written_address_p)
|
||||
{
|
||||
linker_section_ptr->written_address_p = TRUE;
|
||||
bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend,
|
||||
lsect->section->contents + linker_section_ptr->offset);
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
asection *srel = lsect->rel_section;
|
||||
Elf_Internal_Rela outrel[MAX_INT_RELS_PER_EXT_REL];
|
||||
bfd_byte *erel;
|
||||
struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
|
||||
unsigned int i;
|
||||
|
||||
/* We need to generate a relative reloc for the dynamic
|
||||
linker. */
|
||||
if (!srel)
|
||||
{
|
||||
srel = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
|
||||
lsect->rel_name);
|
||||
lsect->rel_section = srel;
|
||||
}
|
||||
|
||||
BFD_ASSERT (srel != NULL);
|
||||
|
||||
for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
|
||||
{
|
||||
outrel[i].r_offset = (lsect->section->output_section->vma
|
||||
+ lsect->section->output_offset
|
||||
+ linker_section_ptr->offset);
|
||||
outrel[i].r_info = 0;
|
||||
outrel[i].r_addend = 0;
|
||||
}
|
||||
outrel[0].r_info = ELF32_R_INFO (0, relative_reloc);
|
||||
erel = lsect->section->contents;
|
||||
erel += (elf_section_data (lsect->section)->rel_count++
|
||||
* sizeof (Elf32_External_Rela));
|
||||
bfd_elf32_swap_reloca_out (output_bfd, outrel, erel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
relocation = (lsect->section->output_offset
|
||||
+ linker_section_ptr->offset
|
||||
- lsect->hole_offset
|
||||
- lsect->sym_offset);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr,
|
||||
"Finish pointer in linker section %s, offset = %ld (0x%lx)\n",
|
||||
lsect->name, (long) relocation, (long) relocation);
|
||||
#endif
|
||||
|
||||
/* Subtract out the addend, because it will get added back in by the normal
|
||||
processing. */
|
||||
return relocation - linker_section_ptr->addend;
|
||||
}
|
||||
|
||||
/* Create a special linker section */
|
||||
static elf_linker_section_t *
|
||||
ppc_elf_create_linker_section (bfd *abfd,
|
||||
@ -2233,7 +2587,7 @@ ppc_elf_create_linker_section (bfd *abfd,
|
||||
break;
|
||||
}
|
||||
|
||||
lsect = _bfd_elf_create_linker_section (abfd, info, which, &defaults);
|
||||
lsect = elf_create_linker_section (abfd, info, which, &defaults);
|
||||
}
|
||||
|
||||
return lsect;
|
||||
@ -2318,7 +2672,10 @@ ppc_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
|
||||
asection *s;
|
||||
flagword flags;
|
||||
|
||||
if (!ppc_elf_create_got (abfd, info))
|
||||
htab = ppc_elf_hash_table (info);
|
||||
|
||||
if (htab->got == NULL
|
||||
&& !ppc_elf_create_got (abfd, info))
|
||||
return FALSE;
|
||||
|
||||
if (!_bfd_elf_create_dynamic_sections (abfd, info))
|
||||
@ -2327,7 +2684,6 @@ ppc_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
|
||||
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
|
||||
| SEC_LINKER_CREATED);
|
||||
|
||||
htab = ppc_elf_hash_table (info);
|
||||
htab->dynbss = bfd_get_section_by_name (abfd, ".dynbss");
|
||||
htab->dynsbss = s = bfd_make_section (abfd, ".dynsbss");
|
||||
if (s == NULL
|
||||
@ -3220,8 +3576,8 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
bad_shared_reloc (abfd, r_type);
|
||||
return FALSE;
|
||||
}
|
||||
if (!bfd_elf32_create_pointer_linker_section (abfd, info,
|
||||
htab->sdata, h, rel))
|
||||
if (!elf_create_pointer_linker_section (abfd, info,
|
||||
htab->sdata, h, rel))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
@ -3232,8 +3588,8 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
bad_shared_reloc (abfd, r_type);
|
||||
return FALSE;
|
||||
}
|
||||
if (!bfd_elf32_create_pointer_linker_section (abfd, info,
|
||||
htab->sdata2, h, rel))
|
||||
if (!elf_create_pointer_linker_section (abfd, info,
|
||||
htab->sdata2, h, rel))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
@ -5008,20 +5364,18 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_EMB_SDAI16:
|
||||
BFD_ASSERT (htab->sdata != NULL);
|
||||
relocation
|
||||
= bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd,
|
||||
info, htab->sdata, h,
|
||||
relocation, rel,
|
||||
R_PPC_RELATIVE);
|
||||
= elf_finish_pointer_linker_section (output_bfd, input_bfd, info,
|
||||
htab->sdata, h, relocation,
|
||||
rel, R_PPC_RELATIVE);
|
||||
break;
|
||||
|
||||
/* Indirect .sdata2 relocation. */
|
||||
case R_PPC_EMB_SDA2I16:
|
||||
BFD_ASSERT (htab->sdata2 != NULL);
|
||||
relocation
|
||||
= bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd,
|
||||
info, htab->sdata2, h,
|
||||
relocation, rel,
|
||||
R_PPC_RELATIVE);
|
||||
= elf_finish_pointer_linker_section (output_bfd, input_bfd, info,
|
||||
htab->sdata2, h, relocation,
|
||||
rel, R_PPC_RELATIVE);
|
||||
break;
|
||||
|
||||
/* Handle the TOC16 reloc. We want to use the offset within the .got
|
||||
|
@ -125,8 +125,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#define elf_reloc_symbol_deleted_p NAME(_bfd_elf,reloc_symbol_deleted_p)
|
||||
#define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
|
||||
#define elf_bfd_final_link NAME(bfd_elf,bfd_final_link)
|
||||
#define elf_create_pointer_linker_section NAME(bfd_elf,create_pointer_linker_section)
|
||||
#define elf_finish_pointer_linker_section NAME(bfd_elf,finish_pointer_linker_section)
|
||||
#define elf_gc_sections NAME(_bfd_elf,gc_sections)
|
||||
#define elf_gc_common_finalize_got_offsets \
|
||||
NAME(_bfd_elf,gc_common_finalize_got_offsets)
|
||||
|
173
bfd/elflink.c
173
bfd/elflink.c
@ -1896,179 +1896,6 @@ _bfd_elf_link_assign_sym_version (h, data)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Create a special linker section, or return a pointer to a linker
|
||||
section already created */
|
||||
|
||||
elf_linker_section_t *
|
||||
_bfd_elf_create_linker_section (abfd, info, which, defaults)
|
||||
bfd *abfd;
|
||||
struct bfd_link_info *info;
|
||||
enum elf_linker_section_enum which;
|
||||
elf_linker_section_t *defaults;
|
||||
{
|
||||
bfd *dynobj = elf_hash_table (info)->dynobj;
|
||||
elf_linker_section_t *lsect;
|
||||
|
||||
/* Record the first bfd section that needs the special section */
|
||||
if (!dynobj)
|
||||
dynobj = elf_hash_table (info)->dynobj = abfd;
|
||||
|
||||
/* If this is the first time, create the section */
|
||||
lsect = elf_linker_section (dynobj, which);
|
||||
if (!lsect)
|
||||
{
|
||||
asection *s;
|
||||
bfd_size_type amt = sizeof (elf_linker_section_t);
|
||||
|
||||
lsect = (elf_linker_section_t *) bfd_alloc (dynobj, amt);
|
||||
|
||||
*lsect = *defaults;
|
||||
elf_linker_section (dynobj, which) = lsect;
|
||||
lsect->which = which;
|
||||
lsect->hole_written_p = FALSE;
|
||||
|
||||
/* See if the sections already exist */
|
||||
lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name);
|
||||
if (!s || (s->flags & defaults->flags) != defaults->flags)
|
||||
{
|
||||
lsect->section = s = bfd_make_section_anyway (dynobj, lsect->name);
|
||||
|
||||
if (s == NULL)
|
||||
return (elf_linker_section_t *)0;
|
||||
|
||||
bfd_set_section_flags (dynobj, s, defaults->flags);
|
||||
bfd_set_section_alignment (dynobj, s, lsect->alignment);
|
||||
}
|
||||
else if (bfd_get_section_alignment (dynobj, s) < lsect->alignment)
|
||||
bfd_set_section_alignment (dynobj, s, lsect->alignment);
|
||||
|
||||
s->_raw_size = align_power (s->_raw_size, lsect->alignment);
|
||||
|
||||
/* Is there a hole we have to provide? If so check whether the
|
||||
segment is too big already */
|
||||
if (lsect->hole_size)
|
||||
{
|
||||
lsect->hole_offset = s->_raw_size;
|
||||
s->_raw_size += lsect->hole_size;
|
||||
if (lsect->hole_offset > lsect->max_hole_offset)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: Section %s is too large to add hole of %ld bytes"),
|
||||
bfd_get_filename (abfd),
|
||||
lsect->name,
|
||||
(long) lsect->hole_size);
|
||||
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return (elf_linker_section_t *)0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Creating section %s, current size = %ld\n",
|
||||
lsect->name, (long)s->_raw_size);
|
||||
#endif
|
||||
|
||||
if (lsect->sym_name)
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
struct bfd_link_hash_entry *bh;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Adding %s to section %s\n",
|
||||
lsect->sym_name,
|
||||
lsect->name);
|
||||
#endif
|
||||
bh = bfd_link_hash_lookup (info->hash, lsect->sym_name,
|
||||
FALSE, FALSE, FALSE);
|
||||
|
||||
if ((bh == NULL || bh->type == bfd_link_hash_undefined)
|
||||
&& !(_bfd_generic_link_add_one_symbol
|
||||
(info, abfd, lsect->sym_name, BSF_GLOBAL, s,
|
||||
(lsect->hole_size
|
||||
? s->_raw_size - lsect->hole_size + lsect->sym_offset
|
||||
: lsect->sym_offset),
|
||||
(const char *) NULL, FALSE,
|
||||
get_elf_backend_data (abfd)->collect, &bh)))
|
||||
return (elf_linker_section_t *) 0;
|
||||
h = (struct elf_link_hash_entry *) bh;
|
||||
|
||||
if ((defaults->which != LINKER_SECTION_SDATA)
|
||||
&& (defaults->which != LINKER_SECTION_SDATA2))
|
||||
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC;
|
||||
|
||||
h->type = STT_OBJECT;
|
||||
lsect->sym_hash = h;
|
||||
|
||||
if (info->shared
|
||||
&& ! _bfd_elf_link_record_dynamic_symbol (info, h))
|
||||
return (elf_linker_section_t *) 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This does not make sense. The sections which may exist in the
|
||||
object file have nothing to do with the sections we want to
|
||||
create. */
|
||||
|
||||
/* Find the related sections if they have been created */
|
||||
if (lsect->bss_name && !lsect->bss_section)
|
||||
lsect->bss_section = bfd_get_section_by_name (dynobj, lsect->bss_name);
|
||||
|
||||
if (lsect->rel_name && !lsect->rel_section)
|
||||
lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);
|
||||
#endif
|
||||
|
||||
return lsect;
|
||||
}
|
||||
|
||||
/* Find a linker generated pointer with a given addend and type. */
|
||||
|
||||
elf_linker_section_pointers_t *
|
||||
_bfd_elf_find_pointer_linker_section (linker_pointers, addend, which)
|
||||
elf_linker_section_pointers_t *linker_pointers;
|
||||
bfd_vma addend;
|
||||
elf_linker_section_enum_t which;
|
||||
{
|
||||
for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)
|
||||
{
|
||||
if (which == linker_pointers->which && addend == linker_pointers->addend)
|
||||
return linker_pointers;
|
||||
}
|
||||
|
||||
return (elf_linker_section_pointers_t *)0;
|
||||
}
|
||||
|
||||
/* Make the .rela section corresponding to the generated linker section. */
|
||||
|
||||
bfd_boolean
|
||||
_bfd_elf_make_linker_section_rela (dynobj, lsect, alignment)
|
||||
bfd *dynobj;
|
||||
elf_linker_section_t *lsect;
|
||||
int alignment;
|
||||
{
|
||||
if (lsect->rel_section)
|
||||
return TRUE;
|
||||
|
||||
lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);
|
||||
if (lsect->rel_section == NULL)
|
||||
{
|
||||
lsect->rel_section = bfd_make_section (dynobj, lsect->rel_name);
|
||||
if (lsect->rel_section == NULL
|
||||
|| ! bfd_set_section_flags (dynobj,
|
||||
lsect->rel_section,
|
||||
(SEC_ALLOC
|
||||
| SEC_LOAD
|
||||
| SEC_HAS_CONTENTS
|
||||
| SEC_IN_MEMORY
|
||||
| SEC_LINKER_CREATED
|
||||
| SEC_READONLY))
|
||||
|| ! bfd_set_section_alignment (dynobj, lsect->rel_section, alignment))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Read and swap the relocs from the section indicated by SHDR. This
|
||||
may be either a REL or a RELA section. The relocations are
|
||||
translated into RELA relocations and stored in INTERNAL_RELOCS,
|
||||
|
258
bfd/elflink.h
258
bfd/elflink.h
@ -5557,264 +5557,6 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Allocate a pointer to live in a linker created section. */
|
||||
|
||||
bfd_boolean
|
||||
elf_create_pointer_linker_section (abfd, info, lsect, h, rel)
|
||||
bfd *abfd;
|
||||
struct bfd_link_info *info;
|
||||
elf_linker_section_t *lsect;
|
||||
struct elf_link_hash_entry *h;
|
||||
const Elf_Internal_Rela *rel;
|
||||
{
|
||||
elf_linker_section_pointers_t **ptr_linker_section_ptr = NULL;
|
||||
elf_linker_section_pointers_t *linker_section_ptr;
|
||||
unsigned long r_symndx = ELF_R_SYM (rel->r_info);
|
||||
bfd_size_type amt;
|
||||
|
||||
BFD_ASSERT (lsect != NULL);
|
||||
|
||||
/* Is this a global symbol? */
|
||||
if (h != NULL)
|
||||
{
|
||||
/* Has this symbol already been allocated? If so, our work is done. */
|
||||
if (_bfd_elf_find_pointer_linker_section (h->linker_section_pointer,
|
||||
rel->r_addend,
|
||||
lsect->which))
|
||||
return TRUE;
|
||||
|
||||
ptr_linker_section_ptr = &h->linker_section_pointer;
|
||||
/* Make sure this symbol is output as a dynamic symbol. */
|
||||
if (h->dynindx == -1)
|
||||
{
|
||||
if (! elf_link_record_dynamic_symbol (info, h))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lsect->rel_section)
|
||||
lsect->rel_section->_raw_size += sizeof (Elf_External_Rela);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocation of a pointer to a local symbol. */
|
||||
elf_linker_section_pointers_t **ptr = elf_local_ptr_offsets (abfd);
|
||||
|
||||
/* Allocate a table to hold the local symbols if first time. */
|
||||
if (!ptr)
|
||||
{
|
||||
unsigned int num_symbols = elf_tdata (abfd)->symtab_hdr.sh_info;
|
||||
register unsigned int i;
|
||||
|
||||
amt = num_symbols;
|
||||
amt *= sizeof (elf_linker_section_pointers_t *);
|
||||
ptr = (elf_linker_section_pointers_t **) bfd_alloc (abfd, amt);
|
||||
|
||||
if (!ptr)
|
||||
return FALSE;
|
||||
|
||||
elf_local_ptr_offsets (abfd) = ptr;
|
||||
for (i = 0; i < num_symbols; i++)
|
||||
ptr[i] = (elf_linker_section_pointers_t *) 0;
|
||||
}
|
||||
|
||||
/* Has this symbol already been allocated? If so, our work is done. */
|
||||
if (_bfd_elf_find_pointer_linker_section (ptr[r_symndx],
|
||||
rel->r_addend,
|
||||
lsect->which))
|
||||
return TRUE;
|
||||
|
||||
ptr_linker_section_ptr = &ptr[r_symndx];
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
/* If we are generating a shared object, we need to
|
||||
output a R_<xxx>_RELATIVE reloc so that the
|
||||
dynamic linker can adjust this GOT entry. */
|
||||
BFD_ASSERT (lsect->rel_section != NULL);
|
||||
lsect->rel_section->_raw_size += sizeof (Elf_External_Rela);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate space for a pointer in the linker section, and allocate
|
||||
a new pointer record from internal memory. */
|
||||
BFD_ASSERT (ptr_linker_section_ptr != NULL);
|
||||
amt = sizeof (elf_linker_section_pointers_t);
|
||||
linker_section_ptr = (elf_linker_section_pointers_t *) bfd_alloc (abfd, amt);
|
||||
|
||||
if (!linker_section_ptr)
|
||||
return FALSE;
|
||||
|
||||
linker_section_ptr->next = *ptr_linker_section_ptr;
|
||||
linker_section_ptr->addend = rel->r_addend;
|
||||
linker_section_ptr->which = lsect->which;
|
||||
linker_section_ptr->written_address_p = FALSE;
|
||||
*ptr_linker_section_ptr = linker_section_ptr;
|
||||
|
||||
#if 0
|
||||
if (lsect->hole_size && lsect->hole_offset < lsect->max_hole_offset)
|
||||
{
|
||||
linker_section_ptr->offset = (lsect->section->_raw_size
|
||||
- lsect->hole_size + (ARCH_SIZE / 8));
|
||||
lsect->hole_offset += ARCH_SIZE / 8;
|
||||
lsect->sym_offset += ARCH_SIZE / 8;
|
||||
if (lsect->sym_hash)
|
||||
{
|
||||
/* Bump up symbol value if needed. */
|
||||
lsect->sym_hash->root.u.def.value += ARCH_SIZE / 8;
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Bump up %s by %ld, current value = %ld\n",
|
||||
lsect->sym_hash->root.root.string,
|
||||
(long) ARCH_SIZE / 8,
|
||||
(long) lsect->sym_hash->root.u.def.value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
linker_section_ptr->offset = lsect->section->_raw_size;
|
||||
|
||||
lsect->section->_raw_size += ARCH_SIZE / 8;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr,
|
||||
"Create pointer in linker section %s, offset = %ld, section size = %ld\n",
|
||||
lsect->name, (long) linker_section_ptr->offset,
|
||||
(long) lsect->section->_raw_size);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if ARCH_SIZE==64
|
||||
#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_64 (BFD, VAL, ADDR)
|
||||
#endif
|
||||
#if ARCH_SIZE==32
|
||||
#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_32 (BFD, VAL, ADDR)
|
||||
#endif
|
||||
|
||||
/* Fill in the address for a pointer generated in a linker section. */
|
||||
|
||||
bfd_vma
|
||||
elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h,
|
||||
relocation, rel, relative_reloc)
|
||||
bfd *output_bfd;
|
||||
bfd *input_bfd;
|
||||
struct bfd_link_info *info;
|
||||
elf_linker_section_t *lsect;
|
||||
struct elf_link_hash_entry *h;
|
||||
bfd_vma relocation;
|
||||
const Elf_Internal_Rela *rel;
|
||||
int relative_reloc;
|
||||
{
|
||||
elf_linker_section_pointers_t *linker_section_ptr;
|
||||
|
||||
BFD_ASSERT (lsect != NULL);
|
||||
|
||||
if (h != NULL)
|
||||
{
|
||||
/* Handle global symbol. */
|
||||
linker_section_ptr = (_bfd_elf_find_pointer_linker_section
|
||||
(h->linker_section_pointer,
|
||||
rel->r_addend,
|
||||
lsect->which));
|
||||
|
||||
BFD_ASSERT (linker_section_ptr != NULL);
|
||||
|
||||
if (! elf_hash_table (info)->dynamic_sections_created
|
||||
|| (info->shared
|
||||
&& info->symbolic
|
||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
|
||||
{
|
||||
/* This is actually a static link, or it is a
|
||||
-Bsymbolic link and the symbol is defined
|
||||
locally. We must initialize this entry in the
|
||||
global section.
|
||||
|
||||
When doing a dynamic link, we create a .rela.<xxx>
|
||||
relocation entry to initialize the value. This
|
||||
is done in the finish_dynamic_symbol routine. */
|
||||
if (!linker_section_ptr->written_address_p)
|
||||
{
|
||||
linker_section_ptr->written_address_p = TRUE;
|
||||
bfd_put_ptr (output_bfd,
|
||||
relocation + linker_section_ptr->addend,
|
||||
(lsect->section->contents
|
||||
+ linker_section_ptr->offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle local symbol. */
|
||||
unsigned long r_symndx = ELF_R_SYM (rel->r_info);
|
||||
BFD_ASSERT (elf_local_ptr_offsets (input_bfd) != NULL);
|
||||
BFD_ASSERT (elf_local_ptr_offsets (input_bfd)[r_symndx] != NULL);
|
||||
linker_section_ptr = (_bfd_elf_find_pointer_linker_section
|
||||
(elf_local_ptr_offsets (input_bfd)[r_symndx],
|
||||
rel->r_addend,
|
||||
lsect->which));
|
||||
|
||||
BFD_ASSERT (linker_section_ptr != NULL);
|
||||
|
||||
/* Write out pointer if it hasn't been rewritten out before. */
|
||||
if (!linker_section_ptr->written_address_p)
|
||||
{
|
||||
linker_section_ptr->written_address_p = TRUE;
|
||||
bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend,
|
||||
lsect->section->contents + linker_section_ptr->offset);
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
asection *srel = lsect->rel_section;
|
||||
Elf_Internal_Rela outrel[MAX_INT_RELS_PER_EXT_REL];
|
||||
bfd_byte *erel;
|
||||
struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
|
||||
unsigned int i;
|
||||
|
||||
/* We need to generate a relative reloc for the dynamic
|
||||
linker. */
|
||||
if (!srel)
|
||||
{
|
||||
srel = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
|
||||
lsect->rel_name);
|
||||
lsect->rel_section = srel;
|
||||
}
|
||||
|
||||
BFD_ASSERT (srel != NULL);
|
||||
|
||||
for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
|
||||
{
|
||||
outrel[i].r_offset = (lsect->section->output_section->vma
|
||||
+ lsect->section->output_offset
|
||||
+ linker_section_ptr->offset);
|
||||
outrel[i].r_info = 0;
|
||||
outrel[i].r_addend = 0;
|
||||
}
|
||||
outrel[0].r_info = ELF_R_INFO (0, relative_reloc);
|
||||
erel = lsect->section->contents;
|
||||
erel += (elf_section_data (lsect->section)->rel_count++
|
||||
* sizeof (Elf_External_Rela));
|
||||
elf_swap_reloca_out (output_bfd, outrel, erel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
relocation = (lsect->section->output_offset
|
||||
+ linker_section_ptr->offset
|
||||
- lsect->hole_offset
|
||||
- lsect->sym_offset);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr,
|
||||
"Finish pointer in linker section %s, offset = %ld (0x%lx)\n",
|
||||
lsect->name, (long) relocation, (long) relocation);
|
||||
#endif
|
||||
|
||||
/* Subtract out the addend, because it will get added back in by the normal
|
||||
processing. */
|
||||
return relocation - linker_section_ptr->addend;
|
||||
}
|
||||
|
||||
/* Garbage collect unused sections. */
|
||||
|
||||
static bfd_boolean elf_gc_mark
|
||||
|
Loading…
Reference in New Issue
Block a user