summaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2001-04-13 00:34:36 +0000
committerJakub Jelinek <jakub@redhat.com>2001-04-13 00:34:36 +0000
commit18d0ddaee98642e2880761dc07141b1b92341a84 (patch)
treea53857d5f826a67ad9e49eb8d2555cdf88725b98 /gas
parent4127dea8928321301c45a2a776febb3332922108 (diff)
downloadbinutils-redhat-18d0ddaee98642e2880761dc07141b1b92341a84.tar.gz
bfd/
* libbfd-in.h (_bfd_merge_section): New. (_bfd_write_merged_section): New. (_bfd_merged_section_offset): New. * libbfd.h: Rebuilt. * linker.c (_bfd_generic_link_output_symbols): Handle discard_sec_merge. * aoutx.h (aout_link_write_symbols): Likewise. * pdp11.c (aout_link_write_symbols): Likewise. * elflink.h (elf_link_add_object_symbols): Call _bfd_merge_section. (elf_bfd_final_link): Adjust global symbols pointing into SEC_MERGE sections. (elf_link_sec_merge_syms): New. (elf_link_input_bfd): Call _bfd_merged_section_offset and _bfd_write_merged_section. Handle discard_sec_merge. * elf-bfd.h (struct elf_link_hash_table): Add merge_info field. (struct bfd_elf_section_data): Likewise. * elf.c (_bfd_elf_make_section_from_shdr): Set SEC_MERGE and SEC_STRINGS section flags and entsize from their ELF counterparts. (_bfd_elf_link_hash_table_init): Initialize merge_info. (elf_fake_sections): Set SHF_MERGE, SHF_STRINGS and sh_entsize from their BFD counterparts. * merge.c: New file. * Makefile.am: Add strtab.lo. * Makefile.in: Rebuilt. include/ * bfdlink.h (bfd_link_discard): Add discard_sec_merge. gas/ * config/obj-elf.c (obj_elf_change_section): Add entsize argument, handle SHF_MERGE and SHF_STRINGS. (obj_elf_parse_section_letters): Set SHF_MERGE and SHF_STRINGS. (obj_elf_section): Allow additional argument specifying entity size. * write.c (adjust_reloc_syms): Keep relocations against local symbols in SEC_MERGE sections. ld/ * ldmain.c (main): Default to discard_sec_merge. * lexsup.c (OPTION_DISCARD_NONE): Define. (ld_options): Add --discard-none. (parse_args): Handle OPTION_DISCARD_NONE. * ldlang.c (wild_doit): SEC_MERGE should be set in the output section only if SEC_MERGE and SEC_STRINGS flags and entsize of all its input sections match.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog9
-rw-r--r--gas/config/obj-elf.c46
-rw-r--r--gas/write.c7
3 files changed, 56 insertions, 6 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 901e73e928..873c16a690 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,12 @@
+2001-04-13 Jakub Jelinek <jakub@redhat.com>
+
+ * config/obj-elf.c (obj_elf_change_section): Add entsize argument,
+ handle SHF_MERGE and SHF_STRINGS.
+ (obj_elf_parse_section_letters): Set SHF_MERGE and SHF_STRINGS.
+ (obj_elf_section): Allow additional argument specifying entity size.
+ * write.c (adjust_reloc_syms): Keep relocations against local symbols
+ in SEC_MERGE sections.
+
2001-04-12 Jason Merrill <jason_merrill@redhat.com>
* dwarf2dbg.c (process_entries): Don't optimize redundant line notes.
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 162f02fa29..2510f4b474 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -620,9 +620,9 @@ static struct special_section const special_sections[] =
};
void
-obj_elf_change_section (name, type, attr, push)
+obj_elf_change_section (name, type, attr, entsize, push)
char *name;
- int type, attr, push;
+ int type, attr, entsize, push;
{
asection *old_sec;
segT sec;
@@ -690,7 +690,9 @@ obj_elf_change_section (name, type, attr, push)
| ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
| ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
| (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
- | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0));
+ | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
+ | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
+ | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0));
#ifdef md_elf_section_flags
flags = md_elf_section_flags (flags, attr, type);
#endif
@@ -704,6 +706,8 @@ obj_elf_change_section (name, type, attr, push)
seg_info (sec)->bss = 1;
bfd_set_section_flags (stdoutput, sec, flags);
+ if (flags & SEC_MERGE)
+ sec->entsize = entsize;
/* Add a symbol for this section to the symbol table. */
secsym = symbol_find (name);
@@ -719,8 +723,10 @@ obj_elf_change_section (name, type, attr, push)
saw the first time. */
if ((old_sec->flags ^ flags)
& (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
- | SEC_EXCLUDE | SEC_SORT_ENTRIES))
+ | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS))
as_warn (_("Ignoring changed section attributes for %s"), name);
+ else if ((flags & SEC_MERGE) && old_sec->entsize != entsize)
+ as_warn (_("Ignoring changed section entity size for %s"), name);
}
#ifdef md_elf_section_change_hook
@@ -748,9 +754,15 @@ obj_elf_parse_section_letters (str, len)
case 'x':
attr |= SHF_EXECINSTR;
break;
+ case 'm':
+ attr |= SHF_MERGE;
+ break;
+ case 's':
+ attr |= SHF_STRINGS;
+ break;
default:
{
- char *bad_msg = _("Unrecognized .section attribute: want a,w,x");
+ char *bad_msg = _("Unrecognized .section attribute: want a,m,s,w,x");
#ifdef md_elf_section_letter
int md_attr = md_elf_section_letter (*str, &bad_msg);
if (md_attr >= 0)
@@ -822,6 +834,7 @@ obj_elf_section (push)
{
char *name, *beg, *end;
int type, attr, dummy;
+ int entsize;
#ifndef TC_I370
if (flag_mri)
@@ -877,6 +890,7 @@ obj_elf_section (push)
type = SHT_NULL;
attr = 0;
+ entsize = 0;
if (*input_line_pointer == ',')
{
@@ -919,6 +933,20 @@ obj_elf_section (push)
type = obj_elf_section_type (beg, input_line_pointer - beg);
}
}
+
+ SKIP_WHITESPACE ();
+ if ((attr & SHF_MERGE) && *input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ entsize = get_absolute_expression ();
+ if (entsize < 0)
+ {
+ as_warn (_("Bad .section directive - invalid merge entity size"));
+ attr &= ~SHF_MERGE;
+ entsize = 0;
+ }
+ }
}
else
{
@@ -948,7 +976,13 @@ obj_elf_section (push)
demand_empty_rest_of_line ();
- obj_elf_change_section (name, type, attr, push);
+ if ((attr & SHF_MERGE) && entsize == 0)
+ {
+ as_warn (_("Entity size for SHF_MERGE not specified.\nSpecify entity size as 4th argument"));
+ attr &= SHF_MERGE;
+ }
+
+ obj_elf_change_section (name, type, attr, entsize, push);
}
/* Change to the .data section. */
diff --git a/gas/write.c b/gas/write.c
index 1a2798be24..151f1cfbe6 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -872,6 +872,13 @@ adjust_reloc_syms (abfd, sec, xxx)
symbol_mark_used_in_reloc (fixp->fx_addsy);
goto done;
}
+
+ /* Never adjust a reloc against local symbol in a merge section. */
+ if (symsec->flags & SEC_MERGE)
+ {
+ symbol_mark_used_in_reloc (fixp->fx_addsy);
+ goto done;
+ }
#endif
/* Is there some other reason we can't adjust this one? (E.g.,