int block_count;
bfd_size_type num_records;
Elf_Internal_Rela *internal_relocs;
+ bfd_vma section_addr;
table_section_name =
xtensa_get_property_section_name (section, sec_name);
table_section = bfd_get_section_by_name (abfd, table_section_name);
free (table_section_name);
if (table_section != NULL)
- table_size = bfd_get_section_size_before_reloc (table_section);
+ table_size = table_section->size;
if (table_size == 0)
{
bfd_malloc (num_records * sizeof (property_table_entry));
block_count = 0;
+ section_addr = section->output_section->vma + section->output_offset;
+
/* If the file has not yet been relocated, process the relocations
and sort out the table entries that apply to the specified section. */
internal_relocs = retrieve_internal_relocs (abfd, table_section, TRUE);
- if (internal_relocs)
+ if (internal_relocs && !table_section->reloc_done)
{
unsigned i;
{
bfd_vma sym_off = get_elf_r_symndx_offset (abfd, r_symndx);
blocks[block_count].address =
- (section->vma + sym_off + rel->r_addend
+ (section_addr + sym_off + rel->r_addend
+ bfd_get_32 (abfd, table_data + rel->r_offset));
blocks[block_count].size =
bfd_get_32 (abfd, table_data + rel->r_offset + 4);
}
else
{
- /* No relocations. Presumably the file has been relocated
- and the addresses are already in the table. */
+ /* The file has already been relocated and the addresses are
+ already in the table. */
bfd_vma off;
for (off = 0; off < table_size; off += 8)
{
bfd_vma address = bfd_get_32 (abfd, table_data + off);
- if (address >= section->vma
- && address < ( section->vma + section->_raw_size))
+ if (address >= section_addr
+ && address < section_addr + section->size)
{
blocks[block_count].address = address;
blocks[block_count].size =
struct elf_link_hash_entry **sym_hashes;
const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end;
- property_table_entry *lit_table;
- int ltblsize;
if (info->relocatable)
return TRUE;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
- ltblsize = xtensa_read_table_entries (abfd, sec, &lit_table,
- XTENSA_LIT_SEC_NAME);
- if (ltblsize < 0)
- return FALSE;
-
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
{
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
{
- (*_bfd_error_handler) (_("%s: bad symbol index: %d"),
- bfd_archive_filename (abfd),
- r_symndx);
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+ abfd, r_symndx);
return FALSE;
}
if ((sec->flags & SEC_ALLOC) != 0)
{
- if ((sec->flags & SEC_READONLY) != 0
- && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
- sec->vma + rel->r_offset))
- h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
-
if (h->got.refcount <= 0)
h->got.refcount = 1;
else
if ((sec->flags & SEC_ALLOC) != 0)
{
- if ((sec->flags & SEC_READONLY) != 0
- && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
- sec->vma + rel->r_offset))
- h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
-
if (h->plt.refcount <= 0)
{
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
elf_local_got_refcounts (abfd) = local_got_refcounts;
}
local_got_refcounts[r_symndx] += 1;
-
- /* If the relocation is not inside the GOT, the DF_TEXTREL
- flag needs to be set. */
- if (info->shared
- && (sec->flags & SEC_READONLY) != 0
- && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
- sec->vma + rel->r_offset))
- info->flags |= DF_TEXTREL;
}
break;
case R_XTENSA_GNU_VTINHERIT:
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
- if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
return FALSE;
break;
case R_XTENSA_GNU_VTENTRY:
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
- if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
}
}
- free (lit_table);
return TRUE;
}
else
{
/* Don't need any dynamic relocations at all. */
- h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
h->plt.refcount = 0;
h->got.refcount = 0;
}
if (! xtensa_elf_dynamic_symbol_p (h, info))
elf_xtensa_make_sym_local (info, h);
- /* If the symbol has a relocation outside the GOT, set the
- DF_TEXTREL flag. */
- if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) != 0)
- info->flags |= DF_TEXTREL;
-
return TRUE;
}
h = (struct elf_link_hash_entry *) h->root.u.i.link;
if (h->plt.refcount > 0)
- srelplt->_raw_size += (h->plt.refcount * sizeof (Elf32_External_Rela));
+ srelplt->size += (h->plt.refcount * sizeof (Elf32_External_Rela));
return TRUE;
}
h = (struct elf_link_hash_entry *) h->root.u.i.link;
if (h->got.refcount > 0)
- srelgot->_raw_size += (h->got.refcount * sizeof (Elf32_External_Rela));
+ srelgot->size += (h->got.refcount * sizeof (Elf32_External_Rela));
return TRUE;
}
for (j = 0; j < cnt; ++j)
{
if (local_got_refcounts[j] > 0)
- srelgot->_raw_size += (local_got_refcounts[j]
- * sizeof (Elf32_External_Rela));
+ srelgot->size += (local_got_refcounts[j]
+ * sizeof (Elf32_External_Rela));
}
}
}
s = bfd_get_section_by_name (dynobj, ".interp");
if (s == NULL)
abort ();
- s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
}
s = bfd_get_section_by_name (dynobj, ".got");
if (s == NULL)
abort ();
- s->_raw_size = 4;
+ s->size = 4;
/* Adjust refcounts for symbols that we now know are not "dynamic". */
elf_link_hash_traverse (elf_hash_table (info),
if (spltlittbl == NULL)
abort ();
- plt_entries = srelplt->_raw_size / sizeof (Elf32_External_Rela);
+ plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
plt_chunks =
(plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
if (chunk_entries != 0)
{
- sgotplt->_raw_size = 4 * (chunk_entries + 2);
- splt->_raw_size = PLT_ENTRY_SIZE * chunk_entries;
- srelgot->_raw_size += 2 * sizeof (Elf32_External_Rela);
- spltlittbl->_raw_size += 8;
+ sgotplt->size = 4 * (chunk_entries + 2);
+ splt->size = PLT_ENTRY_SIZE * chunk_entries;
+ srelgot->size += 2 * sizeof (Elf32_External_Rela);
+ spltlittbl->size += 8;
}
else
{
- sgotplt->_raw_size = 0;
- splt->_raw_size = 0;
+ sgotplt->size = 0;
+ splt->size = 0;
}
}
sgotloc = bfd_get_section_by_name (dynobj, ".got.loc");
if (sgotloc == NULL)
abort ();
- sgotloc->_raw_size = spltlittbl->_raw_size;
+ sgotloc->size = spltlittbl->size;
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
{
if (abfd->flags & DYNAMIC)
if (! elf_discarded_section (s)
&& xtensa_is_littable_section (s)
&& s != spltlittbl)
- sgotloc->_raw_size += s->_raw_size;
+ sgotloc->size += s->size;
}
}
}
else if (strncmp (name, ".plt.", 5) == 0
|| strncmp (name, ".got.plt.", 9) == 0)
{
- if (s->_raw_size == 0)
+ if (s->size == 0)
{
/* If we don't need this section, strip it from the output
file. We must create the ".plt*" and ".got.plt*"
else
{
/* Allocate memory for the section contents. */
- s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
- if (s->contents == NULL && s->_raw_size != 0)
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL && s->size != 0)
return FALSE;
}
}
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (! info->shared)
{
return FALSE;
}
- if ((info->flags & DF_TEXTREL) != 0)
- {
- if (!add_dynamic_entry (DT_TEXTREL, 0))
- return FALSE;
- }
-
if (!add_dynamic_entry (DT_XTENSA_GOT_LOC_OFF, 0)
|| !add_dynamic_entry (DT_XTENSA_GOT_LOC_SZ, 0))
return FALSE;
/* Check for windowed CALL across a 1GB boundary. */
xtensa_opcode opcode =
get_expanded_call_opcode (contents + address,
- input_section->_raw_size - address);
+ input_section->size - address);
if (is_windowed_call_opcode (opcode))
{
self_address = (input_section->output_section->vma
{
/* Convert the L32R/CALLX to CALL. */
bfd_reloc_status_type retval =
- elf_xtensa_do_asm_simplify (contents, address,
- input_section->_raw_size);
+ elf_xtensa_do_asm_simplify (contents, address, input_section->size);
if (retval != bfd_reloc_ok)
return retval;
}
/* Is the address of the relocation really within the section? */
- if (reloc_entry->address > (input_section->_cooked_size
- / bfd_octets_per_byte (abfd)))
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
return bfd_reloc_outofrange;
/* Work out which section the relocation is targeted at and the
struct elf_link_hash_entry **sym_hashes;
asection *srelgot, *srelplt;
bfd *dynobj;
+ property_table_entry *lit_table = 0;
+ int ltblsize = 0;
char *error_message = NULL;
if (xtensa_default_isa == NULL)
srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
}
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ ltblsize = xtensa_read_table_entries (input_bfd, input_section,
+ &lit_table, XTENSA_LIT_SEC_NAME);
+ if (ltblsize < 0)
+ return FALSE;
+ }
+
rel = relocs;
relend = relocs + input_section->reloc_count;
for (; rel < relend; rel++)
{
/* Convert ASM_SIMPLIFY into the simpler relocation
so that they never escape a relaxing link. */
- contract_asm_expansion (contents, input_section->_raw_size, rel);
+ contract_asm_expansion (contents, input_section->size, rel);
r_type = ELF32_R_TYPE (rel->r_info);
}
}
/* Sanity check the address. */
- if (rel->r_offset >= input_section->_raw_size
+ if (rel->r_offset >= bfd_get_section_limit (input_bfd, input_section)
&& ELF32_R_TYPE (rel->r_info) != R_XTENSA_NONE)
{
bfd_set_error (bfd_error_bad_value);
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
+ /* Complain if the relocation is in a read-only section
+ and not in a literal pool. */
+ if ((input_section->flags & SEC_READONLY) != 0
+ && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
+ outrel.r_offset))
+ {
+ error_message =
+ _("dynamic relocation in read-only section");
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+
if (dynamic_symbol)
{
outrel.r_addend = rel->r_addend;
+ srel->reloc_count++ * sizeof (Elf32_External_Rela));
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
BFD_ASSERT (sizeof (Elf32_External_Rela) * srel->reloc_count
- <= srel->_cooked_size);
+ <= srel->size);
}
}
&& !((input_section->flags & SEC_DEBUGGING) != 0
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
(*_bfd_error_handler)
- (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"),
- bfd_archive_filename (input_bfd),
- bfd_get_section_name (input_bfd, input_section),
+ (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
(long) rel->r_offset,
h->root.root.string);
}
}
+ if (lit_table)
+ free (lit_table);
+
+ input_section->reloc_done = TRUE;
+
return TRUE;
}
bfd_vma offset;
int n, m, num;
- section_size = (sxtlit->_cooked_size != 0
- ? sxtlit->_cooked_size : sxtlit->_raw_size);
+ section_size = sxtlit->size;
BFD_ASSERT (section_size % 8 == 0);
num = section_size / 8;
- sgotloc_size = (sgotloc->_cooked_size != 0
- ? sgotloc->_cooked_size : sgotloc->_raw_size);
+ sgotloc_size = sgotloc->size;
if (sgotloc_size != section_size)
{
(*_bfd_error_handler)
return -1;
}
- contents = (bfd_byte *) bfd_malloc (section_size);
- table = (property_table_entry *)
- bfd_malloc (num * sizeof (property_table_entry));
- if (contents == 0 || table == 0)
+ table = bfd_malloc (num * sizeof (property_table_entry));
+ if (table == 0)
return -1;
/* The ".xt.lit.plt" section has the SEC_IN_MEMORY flag set and this
propagates to the output section, where it doesn't really apply and
- where it breaks the following call to bfd_get_section_contents. */
+ where it breaks the following call to bfd_malloc_and_get_section. */
sxtlit->flags &= ~SEC_IN_MEMORY;
- if (! bfd_get_section_contents (output_bfd, sxtlit, contents, 0,
- section_size))
- return -1;
+ if (!bfd_malloc_and_get_section (output_bfd, sxtlit, &contents))
+ {
+ if (contents != 0)
+ free (contents);
+ free (table);
+ return -1;
+ }
/* There should never be any relocations left at this point, so this
is quite a bit easier than what is done during relaxation. */
/* Clear the removed bytes. */
if ((bfd_size_type) (num * 8) < section_size)
- {
- memset (&contents[num * 8], 0, section_size - num * 8);
- sxtlit->_cooked_size = num * 8;
- }
+ memset (&contents[num * 8], 0, section_size - num * 8);
if (! bfd_set_section_contents (output_bfd, sxtlit, contents, 0,
section_size))
sgot = bfd_get_section_by_name (dynobj, ".got");
if (sgot)
{
- BFD_ASSERT (sgot->_raw_size == 4);
+ BFD_ASSERT (sgot->size == 4);
if (sdyn == NULL)
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
else
}
srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
- if (srelplt != NULL && srelplt->_raw_size != 0)
+ if (srelplt != NULL && srelplt->size != 0)
{
asection *sgotplt, *srelgot, *spltlittbl;
int chunk, plt_chunks, plt_entries;
}
BFD_ASSERT (rtld_reloc < srelgot->reloc_count);
- plt_entries = (srelplt->_raw_size / sizeof (Elf32_External_Rela));
+ plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
plt_chunks =
(plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
else
chunk_entries = plt_entries - (chunk * PLT_ENTRIES_PER_CHUNK);
- BFD_ASSERT ((unsigned) (chunk + 1) * 8 <= spltlittbl->_cooked_size);
+ BFD_ASSERT ((unsigned) (chunk + 1) * 8 <= spltlittbl->size);
bfd_put_32 (output_bfd,
sgotplt->output_section->vma + sgotplt->output_offset,
spltlittbl->contents + (chunk * 8) + 0);
/* All the dynamic relocations have been emitted at this point.
Make sure the relocation sections are the correct size. */
- if (srelgot->_cooked_size != (sizeof (Elf32_External_Rela)
- * srelgot->reloc_count)
- || srelplt->_cooked_size != (sizeof (Elf32_External_Rela)
- * srelplt->reloc_count))
+ if (srelgot->size != (sizeof (Elf32_External_Rela)
+ * srelgot->reloc_count)
+ || srelplt->size != (sizeof (Elf32_External_Rela)
+ * srelplt->reloc_count))
abort ();
/* The .xt.lit.plt section has just been modified. This must
spltlittbl->output_section,
spltlittbl->contents,
spltlittbl->output_offset,
- spltlittbl->_raw_size))
+ spltlittbl->size))
return FALSE;
/* Clear SEC_HAS_CONTENTS so the contents won't be output again. */
spltlittbl->flags &= ~SEC_HAS_CONTENTS;
return FALSE;
dyncon = (Elf32_External_Dyn *) sdyn->contents;
- dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
for (; dyncon < dynconend; dyncon++)
{
Elf_Internal_Dyn dyn;
case DT_PLTRELSZ:
s = bfd_get_section_by_name (output_bfd, ".rela.plt");
BFD_ASSERT (s);
- dyn.d_un.d_val = (s->_cooked_size ? s->_cooked_size : s->_raw_size);
+ dyn.d_un.d_val = s->size;
break;
case DT_RELASZ:
don't have to worry about changing the DT_RELA entry. */
s = bfd_get_section_by_name (output_bfd, ".rela.plt");
if (s)
- {
- dyn.d_un.d_val -=
- (s->_cooked_size ? s->_cooked_size : s->_raw_size);
- }
+ dyn.d_un.d_val -= s->size;
break;
}
if (out_mach != in_mach)
{
(*_bfd_error_handler)
- ("%s: incompatible machine type. Output is 0x%x. Input is 0x%x",
- bfd_archive_filename (ibfd), out_mach, in_mach);
+ ("%B: incompatible machine type. Output is 0x%x. Input is 0x%x",
+ ibfd, out_mach, in_mach);
bfd_set_error (bfd_error_wrong_format);
return FALSE;
}
bfd_vma offset, actual_offset;
size_t removed_bytes = 0;
- section_size = (sec->_cooked_size ? sec->_cooked_size : sec->_raw_size);
+ section_size = sec->size;
if (section_size == 0 || section_size % 8 != 0)
return FALSE;
while (cookie->rel < cookie->relend
&& cookie->rel->r_offset == offset)
{
- if (_bfd_elf32_reloc_symbol_deleted_p (offset, cookie))
+ if (bfd_elf_reloc_symbol_deleted_p (offset, cookie))
{
/* Remove the table entry. (If the reloc type is NONE, then
the entry has already been merged with another and deleted
pin_contents (sec, contents);
pin_internal_relocs (sec, cookie->rels);
- sec->_cooked_size = section_size - removed_bytes;
- /* Also shrink _raw_size. See comments in relax_property_section. */
- sec->_raw_size = sec->_cooked_size;
+ /* Shrink size. */
+ sec->size = section_size - removed_bytes;
if (xtensa_is_littable_section (sec))
{
asection *sgotloc =
bfd_get_section_by_name (dynobj, ".got.loc");
if (sgotloc)
- {
- bfd_size_type sgotloc_size =
- (sgotloc->_cooked_size ? sgotloc->_cooked_size
- : sgotloc->_raw_size);
- sgotloc->_cooked_size = sgotloc_size - removed_bytes;
- sgotloc->_raw_size = sgotloc_size - removed_bytes;
- }
+ sgotloc->size -= removed_bytes;
}
}
}
Elf_Internal_Note *note;
{
int offset;
- unsigned int raw_size;
+ unsigned int size;
/* The size for Xtensa is variable, so don't try to recognize the format
based on the size. Just assume this is GNU/Linux. */
/* pr_reg */
offset = 72;
- raw_size = note->descsz - offset - 4;
+ size = note->descsz - offset - 4;
/* Make a ".reg/999" section. */
return _bfd_elfcore_make_pseudosection (abfd, ".reg",
- raw_size, note->descpos + offset);
+ size, note->descpos + offset);
}
if (contents == NULL)
return XTENSA_UNDEFINED;
- if (sec->_raw_size <= irel->r_offset)
+ if (sec->size <= irel->r_offset)
return XTENSA_UNDEFINED;
if (ibuff == NULL)
static bfd_boolean is_same_value
- PARAMS ((const literal_value *, const literal_value *));
+ PARAMS ((const literal_value *, const literal_value *, bfd_boolean));
static value_map_hash_table *value_map_hash_table_init
PARAMS ((void));
static unsigned hash_literal_value
static unsigned hash_bfd_vma
PARAMS ((bfd_vma));
static value_map *get_cached_value
- PARAMS ((value_map_hash_table *, const literal_value *));
+ PARAMS ((value_map_hash_table *, const literal_value *, bfd_boolean));
static value_map *add_value_map
- PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *));
+ PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *,
+ bfd_boolean));
static bfd_boolean
-is_same_value (src1, src2)
+is_same_value (src1, src2, final_static_link)
const literal_value *src1;
const literal_value *src2;
+ bfd_boolean final_static_link;
{
+ struct elf_link_hash_entry *h1, *h2;
+
if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel))
return FALSE;
if (src1->value != src2->value)
return FALSE;
- /* Now check for the same section and the same elf_hash. */
- if (r_reloc_is_defined (&src1->r_rel))
+ /* Now check for the same section (if defined) or the same elf_hash
+ (if undefined or weak). */
+ h1 = r_reloc_get_hash_entry (&src1->r_rel);
+ h2 = r_reloc_get_hash_entry (&src2->r_rel);
+ if (r_reloc_is_defined (&src1->r_rel)
+ && (final_static_link
+ || ((!h1 || h1->root.type != bfd_link_hash_defweak)
+ && (!h2 || h2->root.type != bfd_link_hash_defweak))))
{
if (r_reloc_get_section (&src1->r_rel)
!= r_reloc_get_section (&src2->r_rel))
}
else
{
- if (r_reloc_get_hash_entry (&src1->r_rel)
- != r_reloc_get_hash_entry (&src2->r_rel))
- return FALSE;
-
- if (r_reloc_get_hash_entry (&src1->r_rel) == 0)
+ /* Require that the hash entries (i.e., symbols) be identical. */
+ if (h1 != h2 || h1 == 0)
return FALSE;
}
/* Check if the specified literal_value has been seen before. */
static value_map *
-get_cached_value (map, val)
+get_cached_value (map, val, final_static_link)
value_map_hash_table *map;
const literal_value *val;
+ bfd_boolean final_static_link;
{
value_map *map_e;
value_map *bucket;
bucket = map->buckets[idx];
for (map_e = bucket; map_e; map_e = map_e->next)
{
- if (is_same_value (&map_e->val, val))
+ if (is_same_value (&map_e->val, val, final_static_link))
return map_e;
}
return NULL;
already has an entry here. */
static value_map *
-add_value_map (map, val, loc)
+add_value_map (map, val, loc, final_static_link)
value_map_hash_table *map;
const literal_value *val;
const r_reloc *loc;
+ bfd_boolean final_static_link;
{
value_map **bucket_p;
unsigned idx;
value_map *val_e = (value_map *) bfd_zmalloc (sizeof (value_map));
- BFD_ASSERT (get_cached_value (map, val) == NULL);
+ BFD_ASSERT (get_cached_value (map, val, final_static_link) == NULL);
val_e->val = *val;
val_e->loc = *loc;
contents = elf_section_data (sec)->this_hdr.contents;
- if (contents == NULL && sec->_raw_size != 0)
+ if (contents == NULL && sec->size != 0)
{
- contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
- if (contents != NULL)
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
{
- if (! bfd_get_section_contents (abfd, sec, contents,
- (file_ptr) 0, sec->_raw_size))
- {
- free (contents);
- return NULL;
- }
- if (keep_memory)
- elf_section_data (sec)->this_hdr.contents = contents;
+ if (contents != NULL)
+ free (contents);
+ return NULL;
}
+ if (keep_memory)
+ elf_section_data (sec)->this_hdr.contents = contents;
}
return contents;
}
return ok;
contents = retrieve_contents (abfd, sec, link_info->keep_memory);
- if (contents == NULL && sec->_raw_size != 0)
+ if (contents == NULL && sec->size != 0)
{
ok = FALSE;
goto error_return;
return ok;
contents = retrieve_contents (abfd, sec, link_info->keep_memory);
- if (contents == NULL && sec->_raw_size != 0)
+ if (contents == NULL && sec->size != 0)
{
ok = FALSE;
goto error_return;
return FALSE;
opcode = get_expanded_call_opcode (contents + irel->r_offset,
- sec->_raw_size - irel->r_offset);
+ sec->size - irel->r_offset);
direct_call_opcode = swap_callx_for_call_opcode (opcode);
if (direct_call_opcode == XTENSA_UNDEFINED)
bfd_byte *contents;
Elf_Internal_Rela *internal_relocs;
source_reloc *src_relocs;
+ bfd_boolean final_static_link;
bfd_boolean ok = TRUE;
int i;
link_info->keep_memory);
contents = retrieve_contents (abfd, sec, link_info->keep_memory);
- if (contents == NULL && sec->_raw_size != 0)
+ if (contents == NULL && sec->size != 0)
{
ok = FALSE;
goto error_return;
}
+ final_static_link =
+ (!link_info->relocatable
+ && !elf_hash_table (link_info)->dynamic_sections_created);
+
/* Sort the source_relocs by target offset. */
src_relocs = relax_info->src_relocs;
qsort (src_relocs, relax_info->src_count,
/* Find the literal value. */
r_reloc_init (&val.r_rel, abfd, irel);
- BFD_ASSERT (rel->r_rel.target_offset < sec->_raw_size);
+ BFD_ASSERT (rel->r_rel.target_offset < sec->size);
val.value = bfd_get_32 (abfd, contents + rel->r_rel.target_offset);
/* Check if we've seen another literal with the same value. */
- val_map = get_cached_value (values, &val);
+ val_map = get_cached_value (values, &val, final_static_link);
if (val_map != NULL)
{
/* First check that THIS and all the other relocs to this
{
/* This is the first time we've seen this literal value. */
BFD_ASSERT (sec == r_reloc_get_section (&rel->r_rel));
- add_value_map (values, &val, &rel->r_rel);
+ add_value_map (values, &val, &rel->r_rel, final_static_link);
}
}
internal_relocs = retrieve_internal_relocs (abfd, sec,
link_info->keep_memory);
contents = retrieve_contents (abfd, sec, link_info->keep_memory);
- if (contents == NULL && sec->_raw_size != 0)
+ if (contents == NULL && sec->size != 0)
{
ok = FALSE;
goto error_return;
/* Walk through the contents and delete literals that are not needed
anymore. */
- unsigned long size = sec->_cooked_size;
+ unsigned long size = sec->size;
unsigned long removed = 0;
removed_literal *reloc = relax_info->removed_list.head;
for (; reloc; reloc = reloc->next)
{
- unsigned long upper = sec->_raw_size;
+ unsigned long upper = sec->size;
bfd_vma start = reloc->from.target_offset + 4;
if (reloc->next)
upper = reloc->next->from.target_offset;
}
/* Change the section size. */
- sec->_cooked_size = size;
- /* Also shrink _raw_size. (The code in relocate_section that
- checks that relocations are within the section must use
- _raw_size because of the way the stabs sections are relaxed;
- shrinking _raw_size means that these checks will not be
- unnecessarily lax.) */
- sec->_raw_size = size;
+ sec->size = size;
}
error_return:
/* Reduce size of the .rela.* section by one reloc. */
srel = bfd_get_section_by_name (dynobj, srel_name);
BFD_ASSERT (srel != NULL);
- BFD_ASSERT (srel->_cooked_size >= sizeof (Elf32_External_Rela));
- srel->_cooked_size -= sizeof (Elf32_External_Rela);
-
- /* Also shrink _raw_size. (This seems wrong but other bfd code seems
- to assume that linker-created sections will never be relaxed and
- hence _raw_size must always equal _cooked_size.) */
- srel->_raw_size = srel->_cooked_size;
+ BFD_ASSERT (srel->size >= sizeof (Elf32_External_Rela));
+ srel->size -= sizeof (Elf32_External_Rela);
if (is_plt)
{
= size - 1" since the index starts at zero, but in this
context, the size has just been decremented so there's no
need to subtract one. */
- reloc_index = srel->_cooked_size / sizeof (Elf32_External_Rela);
+ reloc_index = srel->size / sizeof (Elf32_External_Rela);
chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
splt = elf_xtensa_get_plt_section (dynobj, chunk);
srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
BFD_ASSERT (srelgot != NULL);
srelgot->reloc_count -= 2;
- srelgot->_cooked_size -= 2 * sizeof (Elf32_External_Rela);
- /* Shrink _raw_size (see comment above). */
- srelgot->_raw_size = srelgot->_cooked_size;
-
- sgotplt->_cooked_size -= 8;
+ srelgot->size -= 2 * sizeof (Elf32_External_Rela);
+ sgotplt->size -= 8;
/* There should be only one entry left (and it will be
removed below). */
- BFD_ASSERT (sgotplt->_cooked_size == 4);
- BFD_ASSERT (splt->_cooked_size == PLT_ENTRY_SIZE);
+ BFD_ASSERT (sgotplt->size == 4);
+ BFD_ASSERT (splt->size == PLT_ENTRY_SIZE);
}
- BFD_ASSERT (sgotplt->_cooked_size >= 4);
- BFD_ASSERT (splt->_cooked_size >= PLT_ENTRY_SIZE);
+ BFD_ASSERT (sgotplt->size >= 4);
+ BFD_ASSERT (splt->size >= PLT_ENTRY_SIZE);
- sgotplt->_cooked_size -= 4;
- splt->_cooked_size -= PLT_ENTRY_SIZE;
-
- /* Shrink _raw_sizes (see comment above). */
- sgotplt->_raw_size = sgotplt->_cooked_size;
- splt->_raw_size = splt->_cooked_size;
+ sgotplt->size -= 4;
+ splt->size -= PLT_ENTRY_SIZE;
}
}
}
internal_relocs = retrieve_internal_relocs (abfd, sec,
link_info->keep_memory);
contents = retrieve_contents (abfd, sec, link_info->keep_memory);
- if (contents == NULL && sec->_raw_size != 0)
+ if (contents == NULL && sec->size != 0)
{
ok = FALSE;
goto error_return;
pin_contents (sec, contents);
last_irel_offset = (bfd_vma) -1;
- section_size = (sec->_cooked_size ? sec->_cooked_size : sec->_raw_size);
+ section_size = sec->size;
BFD_ASSERT (section_size % 8 == 0);
for (offset = 0; offset < section_size; offset += 8)
/* Clear the removed bytes. */
memset (&contents[section_size - removed_bytes], 0, removed_bytes);
- sec->_cooked_size = section_size - removed_bytes;
- /* Also shrink _raw_size. (The code in relocate_section that
- checks that relocations are within the section must use
- _raw_size because of the way the stabs sections are
- relaxed; shrinking _raw_size means that these checks will
- not be unnecessarily lax.) */
- sec->_raw_size = sec->_cooked_size;
+ sec->size = section_size - removed_bytes;
if (xtensa_is_littable_section (sec))
{
asection *sgotloc =
bfd_get_section_by_name (dynobj, ".got.loc");
if (sgotloc)
- {
- bfd_size_type sgotloc_size =
- (sgotloc->_cooked_size ? sgotloc->_cooked_size
- : sgotloc->_raw_size);
- sgotloc->_cooked_size = sgotloc_size - removed_bytes;
- sgotloc->_raw_size = sgotloc_size - removed_bytes;
- }
+ sgotloc->size -= removed_bytes;
}
}
}
prop_sec_name[linkonce_len + 1] = '.';
suffix = sec->name + linkonce_len;
- while (*suffix)
- {
- suffix += 1;
- if (suffix[-1] == '.')
- break;
- }
+ /* For backward compatibility, replace "t." instead of inserting
+ the new linkonce_kind. */
+ if (strncmp (suffix, "t.", 2) == 0)
+ suffix += 2;
strcpy (prop_sec_name + linkonce_len + 2, suffix);
return prop_sec_name;
/* Assume worst-case offsets: L32R at the very end of the ".plt"
section referencing a literal at the very beginning of
".got.plt". This is very close to the real dependence, anyway. */
- (*callback) (sec, sec->_raw_size, sgotplt, 0, closure);
+ (*callback) (sec, sec->size, sgotplt, 0, closure);
}
internal_relocs = retrieve_internal_relocs (abfd, sec,
/* Cache the contents for the duration of this scan. */
contents = retrieve_contents (abfd, sec, link_info->keep_memory);
- if (contents == NULL && sec->_raw_size != 0)
+ if (contents == NULL && sec->size != 0)
{
ok = FALSE;
goto error_return;
#define elf_info_to_howto elf_xtensa_info_to_howto_rela
-#define bfd_elf32_bfd_final_link bfd_elf32_bfd_final_link
#define bfd_elf32_bfd_merge_private_bfd_data elf_xtensa_merge_private_bfd_data
#define bfd_elf32_new_section_hook elf_xtensa_new_section_hook
#define bfd_elf32_bfd_print_private_bfd_data elf_xtensa_print_private_bfd_data