+2017-06-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/20022
+ PR ld/21557
+ PR ld/21562
+ PR ld/21571
+ * elf-bfd.h (elf_link_hash_entry): Add start_stop. Change the
+ vtable field to a union.
+ (_bfd_elf_is_start_stop): Removed.
+ * elf32-i386.c (elf_i386_convert_load_reloc): Also check for
+ __start_SECNAME and __stop_SECNAME symbols.
+ * elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise.
+ * elflink.c (_bfd_elf_is_start_stop): Removed.
+ (_bfd_elf_gc_mark_rsec): Check start_stop instead of calling
+ _bfd_elf_is_start_stop.
+ (elf_gc_propagate_vtable_entries_used): Skip __start_SECNAME and
+ __stop_SECNAME symbols. Updated.
+ (elf_gc_smash_unused_vtentry_relocs): Likewise.
+ (bfd_elf_gc_record_vtinherit): Likewise.
+ (bfd_elf_gc_record_vtentry): Likewise.
+
2017-06-13 Nick Clifton <nickc@redhat.com>
PR ld/21524
/* Symbol is defined by a shared library with non-default visibility
in a read/write section. */
unsigned int protected_def : 1;
+ /* Symbol is __start_SECNAME or __stop_SECNAME to mark section
+ SECNAME. */
+ unsigned int start_stop : 1;
/* String table index in .dynstr if this is a dynamic symbol. */
unsigned long dynstr_index;
struct bfd_elf_version_tree *vertree;
} verinfo;
- struct elf_link_virtual_table_entry *vtable;
+ union
+ {
+ /* For __start_SECNAME and __stop_SECNAME symbols, record the first
+ input section whose section name is SECNAME. */
+ asection *start_stop_section;
+
+ /* Vtable information. */
+ struct elf_link_virtual_table_entry *vtable;
+ } u2;
};
/* Will references to this symbol always reference the symbol
extern bfd_boolean bfd_elf_gc_common_final_link
(bfd *, struct bfd_link_info *);
-extern asection *_bfd_elf_is_start_stop
- (const struct bfd_link_info *, struct elf_link_hash_entry *);
-
extern bfd_boolean bfd_elf_reloc_symbol_deleted_p
(bfd_vma, void *);
return TRUE;
/* def_regular is set by an assignment in a linker script in
- bfd_elf_record_link_assignment. */
- if ((h->def_regular
- || h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- && SYMBOL_REFERENCES_LOCAL (link_info, h))
+ bfd_elf_record_link_assignment. start_stop is set on
+ __start_SECNAME/__stop_SECNAME which mark section SECNAME. */
+ if (h->start_stop
+ || ((h->def_regular
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && SYMBOL_REFERENCES_LOCAL (link_info, h)))
{
convert_load:
if (opcode == 0x8b)
}
/* Avoid optimizing GOTPCREL relocations againt _DYNAMIC since
ld.so may use its link-time address. */
- else if ((h->def_regular
- || h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- && h != htab->elf.hdynamic
- && SYMBOL_REFERENCES_LOCAL (link_info, h))
+ else if (h->start_stop
+ || ((h->def_regular
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h != htab->elf.hdynamic
+ && SYMBOL_REFERENCES_LOCAL (link_info, h)))
{
/* bfd_link_hash_new or bfd_link_hash_undefined is
set by an assignment in a linker script in
- bfd_elf_record_link_assignment. */
- if (h->def_regular
- && (h->root.type == bfd_link_hash_new
- || h->root.type == bfd_link_hash_undefined
- || ((h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- && h->root.u.def.section == bfd_und_section_ptr)))
+ bfd_elf_record_link_assignment. start_stop is set
+ on __start_SECNAME/__stop_SECNAME which mark section
+ SECNAME. */
+ if (h->start_stop
+ || (h->def_regular
+ && (h->root.type == bfd_link_hash_new
+ || h->root.type == bfd_link_hash_undefined
+ || ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section == bfd_und_section_ptr))))
{
/* Skip since R_X86_64_32/R_X86_64_32S may overflow. */
if (require_reloc_pc32)
return NULL;
}
-/* For undefined __start_<name> and __stop_<name> symbols, return the
- first input section matching <name>. Return NULL otherwise. */
-
-asection *
-_bfd_elf_is_start_stop (const struct bfd_link_info *info,
- struct elf_link_hash_entry *h)
-{
- asection *s;
- const char *sec_name;
-
- if (h->root.type != bfd_link_hash_undefined
- && h->root.type != bfd_link_hash_undefweak)
- return NULL;
-
- s = h->root.u.undef.section;
- if (s != NULL)
- {
- if (s == (asection *) 0 - 1)
- return NULL;
- return s;
- }
-
- sec_name = NULL;
- if (strncmp (h->root.root.string, "__start_", 8) == 0)
- sec_name = h->root.root.string + 8;
- else if (strncmp (h->root.root.string, "__stop_", 7) == 0)
- sec_name = h->root.root.string + 7;
-
- if (sec_name != NULL && *sec_name != '\0')
- {
- bfd *i;
-
- for (i = info->input_bfds; i != NULL; i = i->link.next)
- {
- s = bfd_get_section_by_name (i, sec_name);
- if (s != NULL)
- {
- h->root.u.undef.section = s;
- break;
- }
- }
- }
-
- if (s == NULL)
- h->root.u.undef.section = (asection *) 0 - 1;
-
- return s;
-}
-
/* COOKIE->rel describes a relocation against section SEC, which is
a section we've decided to keep. Return the section that contains
the relocation symbol, or NULL if no section contains it. */
or __stop_XXX symbols. The linker will later define such
symbols for orphan input sections that have a name
representable as a C identifier. */
- asection *s = _bfd_elf_is_start_stop (info, h);
-
- if (s != NULL)
+ if (h->start_stop)
{
+ asection *s = h->u2.start_stop_section;
*start_stop = !s->gc_mark;
return s;
}
elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp)
{
/* Those that are not vtables. */
- if (h->vtable == NULL || h->vtable->parent == NULL)
+ if (h->start_stop
+ || h->u2.vtable == NULL
+ || h->u2.vtable->parent == NULL)
return TRUE;
/* Those vtables that do not have parents, we cannot merge. */
- if (h->vtable->parent == (struct elf_link_hash_entry *) -1)
+ if (h->u2.vtable->parent == (struct elf_link_hash_entry *) -1)
return TRUE;
/* If we've already been done, exit. */
- if (h->vtable->used && h->vtable->used[-1])
+ if (h->u2.vtable->used && h->u2.vtable->used[-1])
return TRUE;
/* Make sure the parent's table is up to date. */
- elf_gc_propagate_vtable_entries_used (h->vtable->parent, okp);
+ elf_gc_propagate_vtable_entries_used (h->u2.vtable->parent, okp);
- if (h->vtable->used == NULL)
+ if (h->u2.vtable->used == NULL)
{
/* None of this table's entries were referenced. Re-use the
parent's table. */
- h->vtable->used = h->vtable->parent->vtable->used;
- h->vtable->size = h->vtable->parent->vtable->size;
+ h->u2.vtable->used = h->u2.vtable->parent->u2.vtable->used;
+ h->u2.vtable->size = h->u2.vtable->parent->u2.vtable->size;
}
else
{
bfd_boolean *cu, *pu;
/* Or the parent's entries into ours. */
- cu = h->vtable->used;
+ cu = h->u2.vtable->used;
cu[-1] = TRUE;
- pu = h->vtable->parent->vtable->used;
+ pu = h->u2.vtable->parent->u2.vtable->used;
if (pu != NULL)
{
const struct elf_backend_data *bed;
bed = get_elf_backend_data (h->root.u.def.section->owner);
log_file_align = bed->s->log_file_align;
- n = h->vtable->parent->vtable->size >> log_file_align;
+ n = h->u2.vtable->parent->u2.vtable->size >> log_file_align;
while (n--)
{
if (*pu)
/* Take care of both those symbols that do not describe vtables as
well as those that are not loaded. */
- if (h->vtable == NULL || h->vtable->parent == NULL)
+ if (h->start_stop
+ || h->u2.vtable == NULL
+ || h->u2.vtable->parent == NULL)
return TRUE;
BFD_ASSERT (h->root.type == bfd_link_hash_defined
if (rel->r_offset >= hstart && rel->r_offset < hend)
{
/* If the entry is in use, do nothing. */
- if (h->vtable->used
- && (rel->r_offset - hstart) < h->vtable->size)
+ if (h->u2.vtable->used
+ && (rel->r_offset - hstart) < h->u2.vtable->size)
{
bfd_vma entry = (rel->r_offset - hstart) >> log_file_align;
- if (h->vtable->used[entry])
+ if (h->u2.vtable->used[entry])
continue;
}
/* Otherwise, kill it. */
return FALSE;
win:
- if (!child->vtable)
+ if (!child->u2.vtable)
{
- child->vtable = ((struct elf_link_virtual_table_entry *)
- bfd_zalloc (abfd, sizeof (*child->vtable)));
- if (!child->vtable)
+ child->u2.vtable = ((struct elf_link_virtual_table_entry *)
+ bfd_zalloc (abfd, sizeof (*child->u2.vtable)));
+ if (!child->u2.vtable)
return FALSE;
}
if (!h)
would be bad. It isn't worth paging in the local symbols to be
sure though; that case should simply be handled by the assembler. */
- child->vtable->parent = (struct elf_link_hash_entry *) -1;
+ child->u2.vtable->parent = (struct elf_link_hash_entry *) -1;
}
else
- child->vtable->parent = h;
+ child->u2.vtable->parent = h;
return TRUE;
}
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
unsigned int log_file_align = bed->s->log_file_align;
- if (!h->vtable)
+ if (!h->u2.vtable)
{
- h->vtable = ((struct elf_link_virtual_table_entry *)
- bfd_zalloc (abfd, sizeof (*h->vtable)));
- if (!h->vtable)
+ h->u2.vtable = ((struct elf_link_virtual_table_entry *)
+ bfd_zalloc (abfd, sizeof (*h->u2.vtable)));
+ if (!h->u2.vtable)
return FALSE;
}
- if (addend >= h->vtable->size)
+ if (addend >= h->u2.vtable->size)
{
size_t size, bytes, file_align;
- bfd_boolean *ptr = h->vtable->used;
+ bfd_boolean *ptr = h->u2.vtable->used;
/* While the symbol is undefined, we have to be prepared to handle
a zero size. */
{
size_t oldbytes;
- oldbytes = (((h->vtable->size >> log_file_align) + 1)
+ oldbytes = (((h->u2.vtable->size >> log_file_align) + 1)
* sizeof (bfd_boolean));
memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes);
}
return FALSE;
/* And arrange for that done flag to be at index -1. */
- h->vtable->used = ptr + 1;
- h->vtable->size = size;
+ h->u2.vtable->used = ptr + 1;
+ h->u2.vtable->size = size;
}
- h->vtable->used[addend >> log_file_align] = TRUE;
+ h->u2.vtable->used[addend >> log_file_align] = TRUE;
return TRUE;
}
2017-06-13 H.J. Lu <hongjiu.lu@intel.com>
+ PR ld/20022
+ PR ld/21557
+ PR ld/21562
+ PR ld/21571
+ * ld.texinfo: Update __start_SECNAME/__stop_SECNAME symbols.
+ * ldlang.c (lang_insert_orphan): Move handling of __start_SECNAME
+ and __stop_SECNAME symbols to ...
+ (lang_set_startof): Here. Also define __start_SECNAME and
+ __stop_SECNAME for -Ur.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Mark
+ referenced __start_SECNAME and __stop_SECNAME symbols as hidden
+ and set start_stop for garbage collection.
+ * testsuite/ld-elf/pr21562a.d: New file.
+ * testsuite/ld-elf/pr21562a.s: Likewise.
+ * testsuite/ld-elf/pr21562a.t: Likewise.
+ * testsuite/ld-elf/pr21562b.d: Likewise.
+ * testsuite/ld-elf/pr21562b.s: Likewise.
+ * testsuite/ld-elf/pr21562b.t: Likewise.
+ * testsuite/ld-elf/pr21562c.d: Likewise.
+ * testsuite/ld-elf/pr21562c.t: Likewise.
+ * testsuite/ld-elf/pr21562d.d: Likewise.
+ * testsuite/ld-elf/pr21562d.t: Likewise.
+ * testsuite/ld-elf/pr21562e.d: Likewise.
+ * testsuite/ld-elf/pr21562f.d: Likewise.
+ * testsuite/ld-elf/pr21562g.d: Likewise.
+ * testsuite/ld-elf/pr21562h.d: Likewise.
+ * testsuite/ld-elf/pr21562i.d: Likewise.
+ * testsuite/ld-elf/pr21562j.d: Likewise.
+ * testsuite/ld-elf/pr21562k.d: Likewise.
+ * testsuite/ld-elf/pr21562l.d: Likewise.
+ * testsuite/ld-elf/pr21562m.d: Likewise.
+ * testsuite/ld-elf/pr21562n.d: Likewise.
+ * testsuite/ld-gc/pr20022.d: Likewise.
+ * testsuite/ld-gc/pr20022a.s: Likewise.
+ * testsuite/ld-gc/pr20022b.s: Likewise.
+ * testsuite/ld-gc/gc.exp: Run PR ld/20022 tests.
+ * testsuite/ld-gc/pr19161.d: Also accept local __start_SECNAME
+ symbol.
+ * testsuite/ld-gc/start.d: Likewise.
+ * testsuite/ld-x86-64/lea1a.d: Updated.
+ * testsuite/ld-x86-64/lea1b.d: Updated.
+ * testsuite/ld-x86-64/lea1d.d: Updated.
+ * testsuite/ld-x86-64/lea1e.d: Likewise.
+
+2017-06-13 H.J. Lu <hongjiu.lu@intel.com>
+
* testsuite/ld-elf/sizeof.d: New file.
* testsuite/ld-elf/sizeof.s: Likewise.
* testsuite/ld-elf/startof.d: Likewise.
{
struct bfd_link_needed_list *needed, *l;
struct elf_link_hash_table *htab;
+ asection *s;
+ bfd *abfd;
+ char leading_char;
after_open_default ();
if (emit_note_gnu_build_id != NULL)
{
- bfd *abfd;
-
/* Find an ELF input. */
for (abfd = link_info.input_bfds;
abfd != (bfd *) NULL; abfd = abfd->link.next)
return;
}
+ leading_char = bfd_get_symbol_leading_char (link_info.output_bfd);
+
+ /* Check for input sections whose names match references to
+ __start_SECNAME or __stop_SECNAME symbols. Mark the matched
+ symbols as hidden and set start_stop for garbage collection. */
+ for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
+ for (s = abfd->sections; s; s = s->next)
+ {
+ const char *name = bfd_get_section_name (abfd, s);
+ const char *ps;
+
+ for (ps = name; *ps != '\0'; ps++)
+ if (!ISALNUM ((unsigned char) *ps) && *ps != '_')
+ break;
+ if (*ps == '\0')
+ {
+ struct elf_link_hash_entry *h;
+ char *symbol = (char *) xmalloc (ps - name
+ + sizeof "__start_" + 1);
+
+ symbol[0] = leading_char;
+ sprintf (symbol + (leading_char != 0), "__start_%s", name);
+ h = elf_link_hash_lookup (elf_hash_table (&link_info),
+ symbol, FALSE, FALSE, TRUE);
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ && h->u2.start_stop_section == NULL)
+ {
+ h->start_stop = 1;
+ h->u2.start_stop_section = s;
+ _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
+ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+ h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
+ | STV_HIDDEN);
+ }
+
+ symbol[0] = leading_char;
+ sprintf (symbol + (leading_char != 0), "__stop_%s", name);
+ h = elf_link_hash_lookup (elf_hash_table (&link_info),
+ symbol, FALSE, FALSE, TRUE);
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ && h->u2.start_stop_section == NULL)
+ {
+ h->start_stop = 1;
+ h->u2.start_stop_section = s;
+ _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
+ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+ h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
+ | STV_HIDDEN);
+ }
+ }
+ }
+
if (!link_info.traditional_format)
{
- bfd *abfd, *elfbfd = NULL;
+ bfd *elfbfd = NULL;
bfd_boolean warn_eh_frame = FALSE;
- asection *s;
int seen_type = 0;
for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
@end group
@end smallexample
+If an output section's name is the same as the input section's name
+and is representable as a C identifier, then the linker will
+automatically @pxref{PROVIDE} two symbols: __start_SECNAME and
+__stop_SECNAME, where SECNAME is the name of the section. These
+indicate the start address and end address of the output section
+respectively. Note: most section names are not representable as
+C identifiers because they contain a @samp{.} character.
+
@node Output Section Data
@subsection Output Section Data
@cindex data
(@pxref{Options,,Command Line Options}) can be used to control which
output sections an orphan is placed in.
-If an orphaned section's name is representable as a C identifier then
-the linker will automatically @pxref{PROVIDE} two symbols:
-__start_SECNAME and __stop_SECNAME, where SECNAME is the name of the
-section. These indicate the start address and end address of the
-orphaned section respectively. Note: most section names are not
-representable as C identifiers because they contain a @samp{.}
-character.
-
@node Location Counter
@subsection The Location Counter
@kindex .
lang_statement_list_type *add_child)
{
lang_statement_list_type add;
- const char *ps;
- lang_assignment_statement_type *start_assign;
lang_output_section_statement_type *os;
lang_output_section_statement_type **os_tail;
os = lang_enter_output_section_statement (secname, address, normal_section,
NULL, NULL, NULL, constraint, 0);
- ps = NULL;
- start_assign = NULL;
- if (config.build_constructors && *os_tail == os)
- {
- /* If the name of the section is representable in C, then create
- symbols to mark the start and the end of the section. */
- for (ps = secname; *ps != '\0'; ps++)
- if (!ISALNUM ((unsigned char) *ps) && *ps != '_')
- break;
- if (*ps == '\0')
- {
- char *symname;
-
- symname = (char *) xmalloc (ps - secname + sizeof "__start_" + 1);
- symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
- sprintf (symname + (symname[0] != 0), "__start_%s", secname);
- start_assign
- = lang_add_assignment (exp_provide (symname,
- exp_nameop (NAME, "."),
- FALSE));
- }
- }
-
if (add_child == NULL)
add_child = &os->children;
lang_add_section (add_child, s, NULL, os);
lang_leave_output_section_statement (NULL, DEFAULT_MEMORY_REGION, NULL,
NULL);
- if (start_assign != NULL)
- {
- char *symname;
- lang_assignment_statement_type *stop_assign;
- bfd_vma dot;
-
- symname = (char *) xmalloc (ps - secname + sizeof "__stop_" + 1);
- symname[0] = bfd_get_symbol_leading_char (link_info.output_bfd);
- sprintf (symname + (symname[0] != 0), "__stop_%s", secname);
- stop_assign
- = lang_add_assignment (exp_provide (symname,
- exp_nameop (NAME, "."),
- FALSE));
- /* Evaluate the expression to define the symbol if referenced,
- before sizing dynamic sections. */
- dot = os->bfd_section->vma;
- exp_fold_tree (start_assign->exp, os->bfd_section, &dot);
- dot += TO_ADDR (s->size);
- exp_fold_tree (stop_assign->exp, os->bfd_section, &dot);
- }
-
/* Restore the global list pointer. */
if (after != NULL)
pop_stat_ptr ();
return bfd_abs_section_ptr;
}
-/* Fix any .startof. or .sizeof. symbols. When the assemblers see the
- operator .startof. (section_name), it produces an undefined symbol
- .startof.section_name. Similarly, when it sees
+/* Fix any .startof., .sizeof., __start or __stop symbols. When the
+ assemblers see the operator .startof. (section_name), it produces
+ an undefined symbol .startof.section_name. Similarly, when it sees
.sizeof. (section_name), it produces an undefined symbol
- .sizeof.section_name. For all the output sections, we look for
- such symbols, and set them to the correct value. */
+ .sizeof.section_name. Also for ELF linker, __start_XXX or __stop_XXX
+ symbols should be resolved to the start and end of section XXX. For
+ all the output sections, we look for such symbols, and set them to
+ the correct value. */
static void
lang_set_startof (void)
{
asection *s;
+ char leading_char;
+ bfd_boolean is_elf = (bfd_get_flavour (link_info.output_bfd)
+ == bfd_target_elf_flavour);
+ bfd_boolean is_elocatable = bfd_link_relocatable (&link_info);
- if (bfd_link_relocatable (&link_info))
- return;
+ leading_char = bfd_get_symbol_leading_char (link_info.output_bfd);
for (s = link_info.output_bfd->sections; s != NULL; s = s->next)
{
secname = bfd_get_section_name (link_info.output_bfd, s);
buf = (char *) xmalloc (10 + strlen (secname));
- sprintf (buf, ".startof.%s", secname);
- h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
- if (h != NULL && h->type == bfd_link_hash_undefined)
+ if (!is_elocatable)
+ {
+ sprintf (buf, ".startof.%s", secname);
+ h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE,
+ TRUE);
+ if (h != NULL && h->type == bfd_link_hash_undefined)
+ {
+ h->type = bfd_link_hash_defined;
+ h->u.def.value = 0;
+ h->u.def.section = s;
+ }
+
+ sprintf (buf, ".sizeof.%s", secname);
+ h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE,
+ TRUE);
+ if (h != NULL && h->type == bfd_link_hash_undefined)
+ {
+ h->type = bfd_link_hash_defined;
+ h->u.def.value = TO_ADDR (s->size);
+ h->u.def.section = bfd_abs_section_ptr;
+ }
+ }
+
+ buf[0] = leading_char;
+ sprintf (buf + (buf[0] != 0), "__start_%s", secname);
+ h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE,
+ TRUE);
+ if (h != NULL
+ && (h->type == bfd_link_hash_undefined
+ || h->type == bfd_link_hash_undefweak))
{
h->type = bfd_link_hash_defined;
h->u.def.value = 0;
h->u.def.section = s;
+ if (is_elf)
+ ((struct elf_link_hash_entry *) h)->def_regular = 1;
}
- sprintf (buf, ".sizeof.%s", secname);
- h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
- if (h != NULL && h->type == bfd_link_hash_undefined)
+ buf[0] = leading_char;
+ sprintf (buf + (buf[0] != 0), "__stop_%s", secname);
+ h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE,
+ TRUE);
+ if (h != NULL
+ && (h->type == bfd_link_hash_undefined
+ || h->type == bfd_link_hash_undefweak))
{
h->type = bfd_link_hash_defined;
h->u.def.value = TO_ADDR (s->size);
- h->u.def.section = bfd_abs_section_ptr;
+ h->u.def.section = s;
+ if (is_elf)
+ ((struct elf_link_hash_entry *) h)->def_regular = 1;
}
-
free (buf);
}
}
--- /dev/null
+#ld: -shared -z defs --gc-sections
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
--- /dev/null
+ .section scnfoo,"aw",%progbits
+ .zero 0x10
+
+ .globl bar
+ .data
+ .type bar, %object
+bar:
+ .dc.a __start_scnfoo
--- /dev/null
+SECTIONS {
+ scnfoo : { *(scnfoo) }
+}
--- /dev/null
+#ld: -shared -z defs --gc-sections
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
--- /dev/null
+ .section scnfoo,"aw",%progbits
+ .zero 0x10
+
+ .globl bar
+ .data
+ .type bar, %object
+bar:
+ .dc.a __stop_scnfoo
--- /dev/null
+SECTIONS {
+ PROVIDE (__start_scnfoo = .);
+ scnfoo : { *(scnfoo) }
+ PROVIDE (__stop_scnfoo = .);
+}
--- /dev/null
+#source: pr21562a.s
+#ld: -shared -z defs --gc-sections -T pr21562a.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
--- /dev/null
+SECTIONS {
+ .foo : {
+ PROVIDE (__start_scnfoo = .);
+ *(scnfoo)
+ PROVIDE (__stop_scnfoo = .);
+ }
+}
--- /dev/null
+#source: pr21562b.s
+#ld: -shared -z defs --gc-sections -T pr21562a.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
--- /dev/null
+SECTIONS {
+ PROVIDE (__start_scnfoo = .);
+ .foo : { *(scnfoo) }
+ PROVIDE (__stop_scnfoo = .);
+}
--- /dev/null
+#source: pr21562a.s
+#ld: -shared -z defs
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
--- /dev/null
+#source: pr21562b.s
+#ld: -shared -z defs
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
--- /dev/null
+#source: pr21562a.s
+#ld: -shared -z defs -T pr21562a.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
--- /dev/null
+#source: pr21562b.s
+#ld: -shared -z defs -T pr21562a.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
--- /dev/null
+#source: pr21562a.s
+#ld: -shared -z defs --gc-sections -T pr21562b.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
--- /dev/null
+#source: pr21562b.s
+#ld: -shared -z defs --gc-sections -T pr21562b.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] scnfoo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
--- /dev/null
+#source: pr21562a.s
+#ld: -shared -z defs --gc-sections -T pr21562c.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] \.foo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
--- /dev/null
+#source: pr21562b.s
+#ld: -shared -z defs --gc-sections -T pr21562c.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] \.foo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
--- /dev/null
+#source: pr21562a.s
+#ld: -shared -z defs --gc-sections -T pr21562d.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] \.foo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start_scnfoo
+#pass
--- /dev/null
+#source: pr21562b.s
+#ld: -shared -z defs --gc-sections -T pr21562d.t
+#readelf: -s -S --wide
+#target: *-*-linux* *-*-gnu*
+
+#...
+ \[[ 0-9]+\] \.foo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +0*10[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__stop_scnfoo
+#pass
run_dump_test "personality"
}
run_dump_test "pr18223"
+ if {![ld_assemble_flags $as $gasopt $srcdir/$subdir/pr20022a.s tmpdir/pr20022a.o]
+ || ![ld_link $ld tmpdir/pr20022.so "-shared --gc-sections tmpdir/pr20022a.o"] } then {
+ fail pr20022
+ } else {
+ run_dump_test "pr20022"
+ }
}
if { [is_remote host] || [which $CC] != 0 } {
#xfail: mips64vr-*-* msp430-*-* powerpc*-*-eabivle rl78-*-* rx-*-* sh*-*-*
#...
-0*[1-9a-f]+[0-9a-f]*[ ](D)[ ]_*__start_my_section
+0*[1-9a-f]+[0-9a-f]*[ ](d|D)[ ]_*__start_my_section
#...
--- /dev/null
+#source: pr20022b.s
+#ld: --gc-sections -e _start tmpdir/pr20022.so
+#readelf: -SsW
+#target: *-*-linux* *-*-gnu*
+#notarget: *-*-*aout *-*-*oldld frv-*-linux* metag-*-linux*
+
+#...
+ \[[ 0-9]+\] _foo[ \t]+PROGBITS[ \t]+[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+[ \t]+.*
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__start__foo
+#pass
--- /dev/null
+ .data
+ .globl bar
+ .type bar,%object
+bar:
+ .dc.a __start__foo
+ .section _foo,"aw",%progbits
+foo:
+ .ascii "This is bar"
--- /dev/null
+ .text
+ .globl _start
+_start:
+ .dc.a __start__foo
+ .dc.a bar
+ .section _foo,"aw",%progbits
+foo:
+ .ascii "This is foo"
#notarget: *-*-*aout *-*-*oldld frv-*-linux* metag-*-linux*
#...
-[0-9a-f]+ D +__start__foo
+[0-9a-f]+ d +__start__foo
#...
[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <foo>
[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <bar>
[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <__start_my_section>
-[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <__stop_my_section>
+[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <.*>
#pass
[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <foo>
[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <bar>
[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <__start_my_section>
-[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <__stop_my_section>
+[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <.*>
#pass
[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <foo>
[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <bar>
[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <__start_my_section>
-[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <__stop_my_section>
+[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <.*>
#pass
[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <foo>
[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <bar>
[ ]*[a-f0-9]+: 48 8d 05 ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <__start_my_section>
-[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <__stop_my_section>
+[ ]*[a-f0-9]+: 4c 8d 1d ([0-9a-f]{2} ){4} * lea 0x[a-f0-9]+\(%rip\),%r11 # [a-f0-9]+ <.*>
#pass