/* You can't use -r against a dynamic object. Also, there's no
hope of using a dynamic object which does not exactly match
the format of the output file. */
- if (info->relocateable || info->hash->creator != abfd->xvec)
+ if (info->relocatable || info->hash->creator != abfd->xvec)
{
bfd_set_error (bfd_error_invalid_operation);
goto error_return;
FALSE, collect, (struct bfd_link_hash_entry **) NULL)))
goto error_return;
- if (! info->relocateable)
+ if (! info->relocatable)
{
/* Clobber the section size so that the warning does
not get copied into the output file. */
}
}
- if (! info->relocateable && ! dynamic
+ if (! info->relocatable && ! dynamic
&& is_elf_hash_table (info))
{
asection *s;
if (notesec)
{
elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec;
- if (exec && info->relocateable
+ if (exec && info->relocatable
&& notesec->output_section != bfd_abs_section_ptr)
notesec->output_section->flags |= SEC_CODE;
}
struct elf_final_link_info *finfo;
};
-/* When performing a relocateable link, the input relocations are
+/* When performing a relocatable link, the input relocations are
preserved. But, if they reference global symbols, the indices
referenced must be updated. Update all the relocations in
REL_HDR (there are COUNT of them), using the data in REL_HASH. */
dynamic = elf_hash_table (info)->dynamic_sections_created;
dynobj = elf_hash_table (info)->dynobj;
- emit_relocs = (info->relocateable
+ emit_relocs = (info->relocatable
|| info->emitrelocations
|| bed->elf_backend_emit_relocs);
if (sec->flags & SEC_MERGE)
merged = TRUE;
- if (info->relocateable || info->emitrelocations)
+ if (info->relocatable || info->emitrelocations)
reloc_count = sec->reloc_count;
else if (bed->elf_backend_count_relocs)
{
o->vma = 0;
}
- if (! info->relocateable && merged)
+ if (! info->relocatable && merged)
elf_link_hash_traverse (elf_hash_table (info),
_bfd_elf_link_sec_merge_syms, (PTR) abfd);
if (o != NULL)
o->target_index = bfd_get_symcount (abfd);
elfsym.st_shndx = i;
- if (info->relocateable || o == NULL)
+ if (info->relocatable || o == NULL)
elfsym.st_value = 0;
else
elfsym.st_value = o->vma;
Unfortunately, there is no way to know the total number of local
symbols until we have seen all of them, and the local symbol
indices precede the global symbol indices. This means that when
- we are generating relocateable output, and we see a reloc against
+ we are generating relocatable output, and we see a reloc against
a global symbol, we can not know the symbol index until we have
finished examining all the local symbols to see which ones we are
going to output. To deal with this, we keep the relocations in
memory, and don't output them until the end of the link. This is
an unfortunate waste of memory, but I don't see a good way around
- it. Fortunately, it only happens when performing a relocateable
+ it. Fortunately, it only happens when performing a relocatable
link, which is not the common case. FIXME: If keep_memory is set
we could write the relocs out and then read them again; I don't
know how bad the memory loss will be. */
}
}
- if (info->relocateable)
+ if (info->relocatable)
{
bfd_boolean failed = FALSE;
program is run. We don't have to worry about symbols that are
referenced by regular files, because we will already have issued
warnings for them. */
- if (! finfo->info->relocateable
+ if (! finfo->info->relocatable
&& (finfo->info->executable
|| ! finfo->info->allow_shlib_undefined)
&& h->root.type == bfd_link_hash_undefined
/* We should also warn if a forced local symbol is referenced from
shared libraries. */
- if (! finfo->info->relocateable
+ if (! finfo->info->relocatable
&& (! finfo->info->shared || ! finfo->info->allow_shlib_undefined)
&& (h->elf_link_hash_flags
& (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC
return FALSE;
}
- /* ELF symbols in relocateable files are section relative,
- but in nonrelocateable files they are virtual
+ /* ELF symbols in relocatable files are section relative,
+ but in nonrelocatable files they are virtual
addresses. */
sym.st_value = h->root.u.def.value + input_sec->output_offset;
- if (! finfo->info->relocateable)
+ if (! finfo->info->relocatable)
{
sym.st_value += input_sec->output_section->vma;
if (h->type == STT_TLS)
/* If a non-weak symbol with non-default visibility is not defined
locally, it is a fatal error. */
- if (! finfo->info->relocateable
+ if (! finfo->info->relocatable
&& ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT
&& ELF_ST_BIND (sym.st_info) != STB_WEAK
&& h->root.type == bfd_link_hash_undefined
if ((input_bfd->flags & DYNAMIC) != 0)
return TRUE;
- emit_relocs = (finfo->info->relocateable
+ emit_relocs = (finfo->info->relocatable
|| finfo->info->emitrelocations
|| bed->elf_backend_emit_relocs);
continue;
/* If we are discarding all local symbols, we don't want to
- output this one. If we are generating a relocateable output
+ output this one. If we are generating a relocatable output
file, then some of the local symbols may be required by
relocs; we output them below as we discover that they are
needed. */
if ((isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
&& isec != NULL
&& ((! isec->linker_mark && (isec->flags & SEC_HAS_CONTENTS) != 0)
- || (! finfo->info->relocateable
+ || (! finfo->info->relocatable
&& (isec->flags & SEC_EXCLUDE) != 0)))
continue;
&& (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
== NULL))
|| (((finfo->info->discard == discard_sec_merge
- && (isec->flags & SEC_MERGE) && ! finfo->info->relocateable)
+ && (isec->flags & SEC_MERGE) && ! finfo->info->relocatable)
|| finfo->info->discard == discard_l)
&& bfd_is_local_label_name (input_bfd, name)))
continue;
*pindex = bfd_get_symcount (output_bfd);
- /* ELF symbols in relocateable files are section relative, but
+ /* ELF symbols in relocatable files are section relative, but
in executable files they are virtual addresses. Note that
this code assumes that all ELF sections have an associated
BFD section with a reasonable value for output_offset; below
output_section. Any special sections must be set up to meet
these requirements. */
osym.st_value += isec->output_offset;
- if (! finfo->info->relocateable)
+ if (! finfo->info->relocatable)
{
osym.st_value += isec->output_section->vma;
if (ELF_ST_TYPE (osym.st_info) == STT_TLS)
/* Try to preserve debug information. */
if ((o->flags & SEC_DEBUGGING) != 0
&& sec->kept_section != NULL
- && sec->_cooked_size == sec->kept_section->_cooked_size)
+ && sec->_raw_size == sec->kept_section->_raw_size)
h->root.u.def.section
= sec->kept_section;
else
/* Try to preserve debug information. */
if ((o->flags & SEC_DEBUGGING) != 0
&& sec->kept_section != NULL
- && sec->_cooked_size == sec->kept_section->_cooked_size)
+ && sec->_raw_size == sec->kept_section->_raw_size)
finfo->sections[r_symndx]
= sec->kept_section;
else
The back end routine is responsible for adjusting the
section contents as necessary, and (if using Rela relocs
- and generating a relocateable output file) adjusting the
+ and generating a relocatable output file) adjusting the
reloc addend as necessary.
The back end routine does not have to worry about setting
internal symbols, and can access the hash table entries
for the external symbols via elf_sym_hashes (input_bfd).
- When generating relocateable output, the back end routine
+ When generating relocatable output, the back end routine
must handle STB_LOCAL/STT_SECTION symbols specially. The
output symbol is going to be a section symbol
corresponding to the output section, which will require
+ elf_section_data (o->output_section)->rel_count
+ elf_section_data (o->output_section)->rel_count2);
last_offset = o->output_offset;
- if (!finfo->info->relocateable)
+ if (!finfo->info->relocatable)
last_offset += o->output_section->vma;
for (next_erel = 0; irela < irelaend; irela++, next_erel++)
{
irela->r_offset += o->output_offset;
/* Relocs in an executable have to be virtual addresses. */
- if (!finfo->info->relocateable)
+ if (!finfo->info->relocatable)
irela->r_offset += o->output_section->vma;
last_offset = irela->r_offset;
return FALSE;
sym.st_value += sec->output_offset;
- if (! finfo->info->relocateable)
+ if (! finfo->info->relocatable)
{
sym.st_value += osec->vma;
if (ELF_ST_TYPE (sym.st_info) == STT_TLS)
/* Swap out the relocs. */
if (bed->elf_backend_emit_relocs
- && !(finfo->info->relocateable
+ && !(finfo->info->relocatable
|| finfo->info->emitrelocations))
reloc_emitter = bed->elf_backend_emit_relocs;
else
}
/* The address of a reloc is relative to the section in a
- relocateable file, and is a virtual address in an executable
+ relocatable file, and is a virtual address in an executable
file. */
offset = link_order->offset;
- if (! info->relocateable)
+ if (! info->relocatable)
offset += output_section->vma;
for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
return TRUE;
}
\f
-/* 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;
-}
-\f
-#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;
-}
-\f
/* Garbage collect unused sections. */
static bfd_boolean elf_gc_mark
struct elf_link_hash_entry *h, Elf_Internal_Sym *));
if (!get_elf_backend_data (abfd)->can_gc_sections
- || info->relocateable || info->emitrelocations
+ || info->relocatable || info->emitrelocations
|| elf_hash_table (info)->dynamic_sections_created)
return TRUE;
struct elf_backend_data *bed = get_elf_backend_data (abfd);
unsigned int log_file_align = bed->s->log_file_align;
- if (addend > h->vtable_entries_size)
+ if (addend >= h->vtable_entries_size)
{
- size_t size, bytes;
+ size_t size, bytes, file_align;
bfd_boolean *ptr = h->vtable_entries_used;
/* While the symbol is undefined, we have to be prepared to handle
a zero size. */
+ file_align = 1 << log_file_align;
if (h->root.type == bfd_link_hash_undefined)
- size = addend;
+ size = addend + file_align;
else
{
size = h->size;
- if (size < addend)
+ if (addend >= size)
{
/* Oops! We've got a reference past the defined end of
the table. This is probably a bug -- shall we warn? */
- size = addend;
+ size = addend + file_align;
}
}
+ size = (size + file_align - 1) & -file_align;
/* Allocate one extra entry for use as a "done" flag for the
- consolidation pass and another extra entry because we are
- going to write up to and including 'size' entries. */
- bytes = ((size >> log_file_align) + 2) * sizeof (bfd_boolean);
+ consolidation pass. */
+ bytes = ((size >> log_file_align) + 1) * sizeof (bfd_boolean);
if (ptr)
{
continue;
eh = bfd_get_section_by_name (abfd, ".eh_frame");
- if (info->relocateable
+ if (info->relocatable
|| (eh != NULL
&& (eh->_raw_size == 0
|| bfd_is_abs_section (eh->output_section))))
}
if (info->eh_frame_hdr
- && !info->relocateable
+ && !info->relocatable
&& _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info))
ret = TRUE;