* config/obj-elf.c: (obj_elf_change_section): Add "group" param.
Set elf_section_data group from it. Warn if group name changed. (obj_elf_parse_section_letters): Parse 'G' too. (obj_elf_section): Parse group name. (struct group_list): New. (build_group_lists): New function. (elf_frob_file): Create SEC_GROUP section(s). * config/obj-elf.c: (elf_copy_symbol_attributes): Zap trailing whitespace.
This commit is contained in:
parent
dbb410c3e2
commit
060adf0e2f
2 changed files with 160 additions and 24 deletions
|
@ -1,3 +1,16 @@
|
|||
2001-10-09 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* config/obj-elf.c: (obj_elf_change_section): Add "group" param.
|
||||
Set elf_section_data group from it. Warn if group name changed.
|
||||
(obj_elf_parse_section_letters): Parse 'G' too.
|
||||
(obj_elf_section): Parse group name.
|
||||
(struct group_list): New.
|
||||
(build_group_lists): New function.
|
||||
(elf_frob_file): Create SEC_GROUP section(s).
|
||||
|
||||
* config/obj-elf.c: (elf_copy_symbol_attributes): Zap trailing
|
||||
whitespace.
|
||||
|
||||
2001-10-08 Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
* doc/arm/c-arm.texi (ARM Options): Add arm9e documentation.
|
||||
|
|
|
@ -58,6 +58,7 @@ static void elf_s_set_align PARAMS ((symbolS *, bfd_vma));
|
|||
static void elf_s_set_other PARAMS ((symbolS *, int));
|
||||
static int elf_sec_sym_ok_for_reloc PARAMS ((asection *));
|
||||
static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR));
|
||||
static void build_group_lists PARAMS ((bfd *, asection *, PTR));
|
||||
static int elf_separate_stab_sections PARAMS ((void));
|
||||
static void elf_init_stab_section PARAMS ((segT));
|
||||
|
||||
|
@ -74,7 +75,8 @@ static void obj_elf_ident PARAMS ((int));
|
|||
static void obj_elf_weak PARAMS ((int));
|
||||
static void obj_elf_local PARAMS ((int));
|
||||
static void obj_elf_visibility PARAMS ((int));
|
||||
static void obj_elf_change_section PARAMS ((char *, int, int, int, int));
|
||||
static void obj_elf_change_section
|
||||
PARAMS ((const char *, int, int, int, const char *, int));
|
||||
static int obj_elf_parse_section_letters PARAMS ((char *, size_t));
|
||||
static int obj_elf_section_word PARAMS ((char *, size_t));
|
||||
static char *obj_elf_section_name PARAMS ((void));
|
||||
|
@ -618,9 +620,13 @@ static struct special_section const special_sections[] =
|
|||
};
|
||||
|
||||
static void
|
||||
obj_elf_change_section (name, type, attr, entsize, push)
|
||||
char *name;
|
||||
int type, attr, entsize, push;
|
||||
obj_elf_change_section (name, type, attr, entsize, group, push)
|
||||
const char *name;
|
||||
int type;
|
||||
int attr;
|
||||
int entsize;
|
||||
const char *group;
|
||||
int push;
|
||||
{
|
||||
asection *old_sec;
|
||||
segT sec;
|
||||
|
@ -706,6 +712,7 @@ obj_elf_change_section (name, type, attr, entsize, push)
|
|||
bfd_set_section_flags (stdoutput, sec, flags);
|
||||
if (flags & SEC_MERGE)
|
||||
sec->entsize = entsize;
|
||||
elf_section_data (sec)->group = group;
|
||||
|
||||
/* Add a symbol for this section to the symbol table. */
|
||||
secsym = symbol_find (name);
|
||||
|
@ -725,6 +732,9 @@ obj_elf_change_section (name, type, attr, entsize, push)
|
|||
as_warn (_("ignoring changed section attributes for %s"), name);
|
||||
else if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
|
||||
as_warn (_("ignoring changed section entity size for %s"), name);
|
||||
else if ((attr & SHF_GROUP) != 0
|
||||
&& strcmp (elf_section_data (old_sec)->group, group) != 0)
|
||||
as_warn (_("ignoring new section group for %s"), name);
|
||||
}
|
||||
|
||||
#ifdef md_elf_section_change_hook
|
||||
|
@ -758,6 +768,9 @@ obj_elf_parse_section_letters (str, len)
|
|||
case 'S':
|
||||
attr |= SHF_STRINGS;
|
||||
break;
|
||||
case 'G':
|
||||
attr |= SHF_GROUP;
|
||||
break;
|
||||
/* Compatibility. */
|
||||
case 'm':
|
||||
if (*(str - 1) == 'a')
|
||||
|
@ -772,7 +785,7 @@ obj_elf_parse_section_letters (str, len)
|
|||
}
|
||||
default:
|
||||
{
|
||||
char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S");
|
||||
char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S,G");
|
||||
#ifdef md_elf_section_letter
|
||||
int md_attr = md_elf_section_letter (*str, &bad_msg);
|
||||
if (md_attr >= 0)
|
||||
|
@ -882,7 +895,7 @@ void
|
|||
obj_elf_section (push)
|
||||
int push;
|
||||
{
|
||||
char *name, *beg;
|
||||
char *name, *group, *beg;
|
||||
int type, attr, dummy;
|
||||
int entsize;
|
||||
|
||||
|
@ -913,6 +926,7 @@ obj_elf_section (push)
|
|||
return;
|
||||
type = SHT_NULL;
|
||||
attr = 0;
|
||||
group = NULL;
|
||||
entsize = 0;
|
||||
|
||||
if (*input_line_pointer == ',')
|
||||
|
@ -935,6 +949,8 @@ obj_elf_section (push)
|
|||
if (*input_line_pointer == ',')
|
||||
{
|
||||
char c;
|
||||
char *save = input_line_pointer;
|
||||
|
||||
++input_line_pointer;
|
||||
SKIP_WHITESPACE ();
|
||||
c = *input_line_pointer;
|
||||
|
@ -955,6 +971,8 @@ obj_elf_section (push)
|
|||
*input_line_pointer = c;
|
||||
type = obj_elf_section_type (beg, input_line_pointer - beg);
|
||||
}
|
||||
else
|
||||
input_line_pointer = save;
|
||||
}
|
||||
|
||||
SKIP_WHITESPACE ();
|
||||
|
@ -976,6 +994,19 @@ obj_elf_section (push)
|
|||
as_warn (_("entity size for SHF_MERGE not specified"));
|
||||
attr &= ~SHF_MERGE;
|
||||
}
|
||||
|
||||
if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
|
||||
{
|
||||
++input_line_pointer;
|
||||
group = obj_elf_section_name ();
|
||||
if (group == NULL)
|
||||
attr &= ~SHF_GROUP;
|
||||
}
|
||||
else if ((attr & SHF_GROUP) != 0)
|
||||
{
|
||||
as_warn (_("group name for SHF_GROUP not specified"));
|
||||
attr &= ~SHF_GROUP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1005,7 +1036,7 @@ obj_elf_section (push)
|
|||
|
||||
demand_empty_rest_of_line ();
|
||||
|
||||
obj_elf_change_section (name, type, attr, entsize, push);
|
||||
obj_elf_change_section (name, type, attr, entsize, group, push);
|
||||
}
|
||||
|
||||
/* Change to the .data section. */
|
||||
|
@ -1361,23 +1392,23 @@ void
|
|||
elf_copy_symbol_attributes (dest, src)
|
||||
symbolS *dest, *src;
|
||||
{
|
||||
struct elf_obj_sy *srcelf = symbol_get_obj (src);
|
||||
struct elf_obj_sy *destelf = symbol_get_obj (dest);
|
||||
if (srcelf->size)
|
||||
{
|
||||
if (destelf->size == NULL)
|
||||
destelf->size =
|
||||
(expressionS *) xmalloc (sizeof (expressionS));
|
||||
*destelf->size = *srcelf->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (destelf->size != NULL)
|
||||
free (destelf->size);
|
||||
destelf->size = NULL;
|
||||
}
|
||||
S_SET_SIZE (dest, S_GET_SIZE (src));
|
||||
S_SET_OTHER (dest, S_GET_OTHER (src));
|
||||
struct elf_obj_sy *srcelf = symbol_get_obj (src);
|
||||
struct elf_obj_sy *destelf = symbol_get_obj (dest);
|
||||
if (srcelf->size)
|
||||
{
|
||||
if (destelf->size == NULL)
|
||||
destelf->size =
|
||||
(expressionS *) xmalloc (sizeof (expressionS));
|
||||
*destelf->size = *srcelf->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (destelf->size != NULL)
|
||||
free (destelf->size);
|
||||
destelf->size = NULL;
|
||||
}
|
||||
S_SET_SIZE (dest, S_GET_SIZE (src));
|
||||
S_SET_OTHER (dest, S_GET_OTHER (src));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1860,11 +1891,103 @@ elf_frob_symbol (symp, puntp)
|
|||
#endif
|
||||
}
|
||||
|
||||
struct group_list
|
||||
{
|
||||
asection **head; /* Section lists. */
|
||||
unsigned int *elt_count; /* Number of sections in each list. */
|
||||
unsigned int num_group; /* Number of lists. */
|
||||
};
|
||||
|
||||
/* Called via bfd_map_over_sections. If SEC is a member of a group,
|
||||
add it to a list of sections belonging to the group. INF is a
|
||||
pointer to a struct group_list, which is where we store the head of
|
||||
each list. */
|
||||
|
||||
static void
|
||||
build_group_lists (abfd, sec, inf)
|
||||
bfd *abfd ATTRIBUTE_UNUSED;
|
||||
asection *sec;
|
||||
PTR inf;
|
||||
{
|
||||
struct group_list *list = (struct group_list *) inf;
|
||||
const char *group_name = elf_section_data (sec)->group;
|
||||
unsigned int i;
|
||||
|
||||
if (group_name == NULL)
|
||||
return;
|
||||
|
||||
/* If this group already has a list, add the section to the head of
|
||||
the list. */
|
||||
for (i = 0; i < list->num_group; i++)
|
||||
{
|
||||
if (strcmp (group_name, elf_section_data (list->head[i])->group) == 0)
|
||||
{
|
||||
elf_section_data (sec)->next_in_group = list->head[i];
|
||||
list->head[i] = sec;
|
||||
list->elt_count[i] += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* New group. Make the arrays bigger in chunks to minimize calls to
|
||||
realloc. */
|
||||
i = list->num_group;
|
||||
if ((i & 127) == 0)
|
||||
{
|
||||
unsigned int newsize = i + 128;
|
||||
list->head = xrealloc (list->head, newsize * sizeof (*list->head));
|
||||
list->elt_count = xrealloc (list->elt_count,
|
||||
newsize * sizeof (*list->elt_count));
|
||||
}
|
||||
list->head[i] = sec;
|
||||
list->elt_count[i] = 1;
|
||||
list->num_group += 1;
|
||||
}
|
||||
|
||||
void
|
||||
elf_frob_file ()
|
||||
{
|
||||
struct group_list list;
|
||||
unsigned int i;
|
||||
|
||||
bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
|
||||
|
||||
/* Go find section groups. */
|
||||
list.num_group = 0;
|
||||
list.head = NULL;
|
||||
list.elt_count = NULL;
|
||||
bfd_map_over_sections (stdoutput, build_group_lists, (PTR) &list);
|
||||
|
||||
/* Make the SHT_GROUP sections that describe each section group. We
|
||||
can't set up the section contents here yet, because elf section
|
||||
indices have yet to be calculated. elf.c:set_group_contents does
|
||||
the rest of the work. */
|
||||
for (i = 0; i < list.num_group; i++)
|
||||
{
|
||||
const char *group_name = elf_section_data (list.head[i])->group;
|
||||
asection *s;
|
||||
flagword flags;
|
||||
|
||||
s = subseg_force_new (group_name, 0);
|
||||
flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
|
||||
if (s == NULL
|
||||
|| !bfd_set_section_flags (stdoutput, s, flags)
|
||||
|| !bfd_set_section_alignment (stdoutput, s, 2))
|
||||
{
|
||||
as_fatal (_("can't create group: %s"),
|
||||
bfd_errmsg (bfd_get_error ()));
|
||||
}
|
||||
|
||||
/* Pass a pointer to the first section in this group. This
|
||||
seems as good a field to use as any; It's not used otherwise
|
||||
by the ELF code. */
|
||||
s->lineno = (alent *) list.head[i];
|
||||
|
||||
s->_raw_size = 4 * (list.elt_count[i] + 1);
|
||||
s->contents = frag_more (s->_raw_size);
|
||||
frag_now->fr_fix = frag_now_fix_octets ();
|
||||
}
|
||||
|
||||
#ifdef elf_tc_final_processing
|
||||
elf_tc_final_processing ();
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue