static struct section_stack *section_stack;
+/* Match both section group name and the sh_info field. */
+struct section_match
+{
+ const char *group_name;
+ unsigned int info;
+};
+
static bfd_boolean
get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
{
- const char *gname = (const char *) inf;
+ struct section_match *match = (struct section_match *) inf;
+ const char *gname = match->group_name;
const char *group_name = elf_group_name (sec);
+ unsigned int info = elf_section_data (sec)->this_hdr.sh_info;
- return (group_name == gname
- || (group_name != NULL
- && gname != NULL
- && strcmp (group_name, gname) == 0));
+ return (info == match->info
+ && (group_name == gname
+ || (group_name != NULL
+ && gname != NULL
+ && strcmp (group_name, gname) == 0)));
}
/* Handle the .section pseudo-op. This code supports two different
void
obj_elf_change_section (const char *name,
unsigned int type,
+ unsigned int info,
bfd_vma attr,
int entsize,
const char *group_name,
flagword flags;
const struct elf_backend_data *bed;
const struct bfd_elf_special_section *ssect;
+ struct section_match match;
#ifdef md_flush_pending_output
md_flush_pending_output ();
previous_section = now_seg;
previous_subsection = now_subseg;
+ match.group_name = group_name;
+ match.info = info;
old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
- (void *) group_name);
+ (void *) &match);
if (old_sec)
{
sec = old_sec;
attr |= ssect->attr;
}
+ if ((attr & (SHF_ALLOC | SHF_GNU_MBIND)) == SHF_GNU_MBIND)
+ as_fatal (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
+
/* Convert ELF type and flags to BFD flags. */
flags = (SEC_RELOC
| ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
type = bfd_elf_get_default_section_type (flags);
elf_section_type (sec) = type;
elf_section_flags (sec) = attr;
+ elf_section_data (sec)->this_hdr.sh_info = info;
/* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
if (type == SHT_NOBITS)
case 'T':
attr |= SHF_TLS;
break;
+ case 'd':
+ attr |= SHF_GNU_MBIND;
+ break;
case '?':
*is_clone = TRUE;
break;
int entsize;
int linkonce;
subsegT new_subsection = -1;
+ unsigned int info = 0;
#ifndef TC_I370
if (flag_mri)
linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0;
}
}
+
+ if ((attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (ISDIGIT (* input_line_pointer))
+ {
+ char *t = input_line_pointer;
+ info = strtoul (input_line_pointer,
+ &input_line_pointer, 0);
+ if (info == (unsigned int) -1)
+ {
+ as_warn (_("unsupported mbind section info: %s"), t);
+ info = 0;
+ }
+ }
+ }
}
else
{
done:
demand_empty_rest_of_line ();
- obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push);
+ obj_elf_change_section (name, type, info, attr, entsize, group_name,
+ linkonce, push);
if (push && new_subsection != -1)
subseg_set (now_seg, new_subsection);