mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-10 14:59:31 +08:00
* ld.h (split_by_reloc, split_by_file): New flags.
* ldwrite.c (clone_section, split_sections): New functions. * lexsup.c (parse_args): Understand new split options.
This commit is contained in:
15
ld/ChangeLog
15
ld/ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
Mon Dec 19 14:02:13 1994 Steve Chamberlain (sac@jonny.cygnus.com)
|
||||||
|
|
||||||
|
* ld.h (split_by_reloc, split_by_file): New flags.
|
||||||
|
* ldwrite.c (clone_section, split_sections): New functions.
|
||||||
|
* lexsup.c (parse_args): Understand new split options.
|
||||||
|
|
||||||
|
start-sanitize-arc
|
||||||
|
Tue Dec 13 16:45:18 1994 Doug Evans <dje@canuck.cygnus.com>
|
||||||
|
|
||||||
|
* configure.in (arc-elf): New target.
|
||||||
|
* Makefile.in (earcelf.c): New target.
|
||||||
|
* config/arc-elf.mt: New file.
|
||||||
|
* emulparms/arcelf.sh: New file.
|
||||||
|
end-sanitize-arc
|
||||||
|
|
||||||
Fri Dec 9 17:22:55 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
|
Fri Dec 9 17:22:55 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
|
||||||
|
|
||||||
* scripttempl/elf.sc: Move .ctors and .dtors from .text segment to
|
* scripttempl/elf.sc: Move .ctors and .dtors from .text segment to
|
||||||
|
253
ld/ldwrite.c
253
ld/ldwrite.c
@ -44,42 +44,46 @@ build_link_order (statement)
|
|||||||
switch (statement->header.type)
|
switch (statement->header.type)
|
||||||
{
|
{
|
||||||
case lang_data_statement_enum:
|
case lang_data_statement_enum:
|
||||||
/* FIXME: This should probably build a link_order, but instead
|
|
||||||
it just does the output directly. */
|
|
||||||
{
|
{
|
||||||
bfd_vma value = statement->data_statement.value;
|
asection *output_section;
|
||||||
bfd_byte play_area[QUAD_SIZE];
|
struct bfd_link_order *link_order;
|
||||||
unsigned int size = 0;
|
bfd_vma value;
|
||||||
asection *output_section = statement->data_statement.output_section;
|
|
||||||
|
output_section = statement->data_statement.output_section;
|
||||||
|
ASSERT (output_section->owner == output_bfd);
|
||||||
|
|
||||||
|
link_order = bfd_new_link_order (output_bfd, output_section);
|
||||||
|
if (link_order == NULL)
|
||||||
|
einfo ("%P%F: bfd_new_link_order failed");
|
||||||
|
|
||||||
|
link_order->type = bfd_data_link_order;
|
||||||
|
link_order->offset = statement->data_statement.output_vma;
|
||||||
|
link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
|
||||||
|
|
||||||
|
value = statement->data_statement.value;
|
||||||
|
|
||||||
ASSERT (output_section->owner == output_bfd);
|
ASSERT (output_section->owner == output_bfd);
|
||||||
switch (statement->data_statement.type)
|
switch (statement->data_statement.type)
|
||||||
{
|
{
|
||||||
case QUAD:
|
case QUAD:
|
||||||
bfd_put_64 (output_bfd, value, play_area);
|
bfd_put_64 (output_bfd, value, link_order->u.data.contents);
|
||||||
size = QUAD_SIZE;
|
link_order->size = QUAD_SIZE;
|
||||||
break;
|
break;
|
||||||
case LONG:
|
case LONG:
|
||||||
bfd_put_32 (output_bfd, value, play_area);
|
bfd_put_32 (output_bfd, value, link_order->u.data.contents);
|
||||||
size = LONG_SIZE;
|
link_order->size = LONG_SIZE;
|
||||||
break;
|
break;
|
||||||
case SHORT:
|
case SHORT:
|
||||||
bfd_put_16 (output_bfd, value, play_area);
|
bfd_put_16 (output_bfd, value, link_order->u.data.contents);
|
||||||
size = SHORT_SIZE;
|
link_order->size = SHORT_SIZE;
|
||||||
break;
|
break;
|
||||||
case BYTE:
|
case BYTE:
|
||||||
bfd_put_8 (output_bfd, value, play_area);
|
bfd_put_8 (output_bfd, value, link_order->u.data.contents);
|
||||||
size = BYTE_SIZE;
|
link_order->size = BYTE_SIZE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! bfd_set_section_contents (output_bfd, output_section,
|
|
||||||
play_area,
|
|
||||||
statement->data_statement.output_vma,
|
|
||||||
size))
|
|
||||||
einfo ("%P%X: writing data failed: %E\n");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -196,12 +200,217 @@ build_link_order (statement)
|
|||||||
|
|
||||||
/* Call BFD to write out the linked file. */
|
/* Call BFD to write out the linked file. */
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* Wander around the input sections, make sure that
|
||||||
|
we'll never try and create an output section with more relocs
|
||||||
|
than will fit.. Do this by always assuming the worst case, and
|
||||||
|
creating new output sections with all the right bits */
|
||||||
|
#define TESTIT 1
|
||||||
|
static asection *
|
||||||
|
clone_section (abfd, s, count)
|
||||||
|
bfd *abfd;
|
||||||
|
asection *s;
|
||||||
|
int *count;
|
||||||
|
{
|
||||||
|
#define SSIZE 8
|
||||||
|
char sname[SSIZE]; /* ?? find the name for this size */
|
||||||
|
asection *n;
|
||||||
|
|
||||||
|
/* Invent a section name - use first five
|
||||||
|
chars of base section name and a digit suffix */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char b[6];
|
||||||
|
for (i = 0; i < sizeof (b) - 1 && s->name[i]; i++)
|
||||||
|
b[i] = s->name[i];
|
||||||
|
b[i] = 0;
|
||||||
|
sprintf (sname, "%s%d", b, (*count)++);
|
||||||
|
}
|
||||||
|
while (bfd_get_section_by_name (abfd, sname));
|
||||||
|
|
||||||
|
n = bfd_make_section_anyway (abfd, strdup (sname));
|
||||||
|
|
||||||
|
n->flags = s->flags;
|
||||||
|
n->vma = s->vma;
|
||||||
|
n->user_set_vma = s->user_set_vma;
|
||||||
|
n->lma = s->lma;
|
||||||
|
n->_cooked_size = 0;
|
||||||
|
n->_raw_size = 0;
|
||||||
|
n->output_offset = s->output_offset;
|
||||||
|
n->output_section = n;
|
||||||
|
n->orelocation = 0;
|
||||||
|
n->reloc_count = 0;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TESTING
|
||||||
|
static void
|
||||||
|
ds (s)
|
||||||
|
asection *s;
|
||||||
|
{
|
||||||
|
struct bfd_link_order *l = s->link_order_head;
|
||||||
|
printf ("vma %x size %x\n", s->vma, s->_raw_size);
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
if (l->type == bfd_indirect_link_order)
|
||||||
|
{
|
||||||
|
printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf ("%8x something else\n", l->offset);
|
||||||
|
}
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
dump (s, a1, a2)
|
||||||
|
char *s;
|
||||||
|
asection *a1;
|
||||||
|
asection *a2;
|
||||||
|
{
|
||||||
|
printf ("%s\n", s);
|
||||||
|
ds (a1);
|
||||||
|
ds (a2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sanity_check (abfd)
|
||||||
|
bfd *abfd;
|
||||||
|
{
|
||||||
|
asection *s;
|
||||||
|
for (s = abfd->sections; s; s = s->next)
|
||||||
|
{
|
||||||
|
struct bfd_link_order *p;
|
||||||
|
bfd_vma prev = 0;
|
||||||
|
for (p = s->link_order_head; p; p = p->next)
|
||||||
|
{
|
||||||
|
if (p->offset > 100000)
|
||||||
|
abort ();
|
||||||
|
if (p->offset < prev)
|
||||||
|
abort ();
|
||||||
|
prev = p->offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define sanity_check(a)
|
||||||
|
#define dump(a, b, c)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
split_sections (abfd, info)
|
||||||
|
bfd *abfd;
|
||||||
|
struct bfd_link_info *info;
|
||||||
|
{
|
||||||
|
asection *original_sec;
|
||||||
|
int nsecs = abfd->section_count;
|
||||||
|
sanity_check (abfd);
|
||||||
|
/* look through all the original sections */
|
||||||
|
for (original_sec = abfd->sections;
|
||||||
|
original_sec && nsecs;
|
||||||
|
original_sec = original_sec->next, nsecs--)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
int lines = 0;
|
||||||
|
int relocs = 0;
|
||||||
|
struct bfd_link_order **pp;
|
||||||
|
bfd_vma vma = original_sec->vma;
|
||||||
|
bfd_vma shift_offset = 0;
|
||||||
|
asection *cursor = original_sec;
|
||||||
|
/* count up the relocations and line entries to see if
|
||||||
|
anything would be too big to fit */
|
||||||
|
for (pp = &(cursor->link_order_head); *pp; pp = &((*pp)->next))
|
||||||
|
{
|
||||||
|
struct bfd_link_order *p = *pp;
|
||||||
|
int thislines = 0;
|
||||||
|
int thisrelocs = 0;
|
||||||
|
if (p->type == bfd_indirect_link_order)
|
||||||
|
{
|
||||||
|
asection *sec;
|
||||||
|
|
||||||
|
sec = p->u.indirect.section;
|
||||||
|
|
||||||
|
if (info->strip == strip_none
|
||||||
|
|| info->strip == strip_some)
|
||||||
|
thislines = sec->lineno_count;
|
||||||
|
|
||||||
|
if (info->relocateable)
|
||||||
|
thisrelocs = sec->reloc_count;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (info->relocateable
|
||||||
|
&& (p->type == bfd_section_reloc_link_order
|
||||||
|
|| p->type == bfd_symbol_reloc_link_order))
|
||||||
|
thisrelocs++;
|
||||||
|
|
||||||
|
if (thisrelocs + relocs > config.split_by_reloc
|
||||||
|
|| thislines + lines > config.split_by_reloc
|
||||||
|
|| config.split_by_file)
|
||||||
|
{
|
||||||
|
/* create a new section and put this link order and the
|
||||||
|
following link orders into it */
|
||||||
|
struct bfd_link_order *l = p;
|
||||||
|
asection *n = clone_section (abfd, cursor, &count);
|
||||||
|
*pp = NULL; /* Snip off link orders from old section */
|
||||||
|
n->link_order_head = l; /* attach to new section */
|
||||||
|
pp = &n->link_order_head;
|
||||||
|
|
||||||
|
/* change the size of the original section and
|
||||||
|
update the vma of the new one */
|
||||||
|
|
||||||
|
dump ("before snip", cursor, n);
|
||||||
|
|
||||||
|
n->_raw_size = cursor->_raw_size - l->offset;
|
||||||
|
cursor->_raw_size = l->offset;
|
||||||
|
|
||||||
|
vma += cursor->_raw_size;
|
||||||
|
n->lma = n->vma = vma;
|
||||||
|
|
||||||
|
shift_offset = l->offset;
|
||||||
|
|
||||||
|
/* run down the chain and change the output section to
|
||||||
|
the right one, update the offsets too */
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
l->offset -= shift_offset;
|
||||||
|
if (l->type == bfd_indirect_link_order)
|
||||||
|
{
|
||||||
|
l->u.indirect.section->output_section = n;
|
||||||
|
l->u.indirect.section->output_offset = l->offset;
|
||||||
|
}
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
dump ("after snip", cursor, n);
|
||||||
|
cursor = n;
|
||||||
|
relocs = thisrelocs;
|
||||||
|
lines = thislines;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
relocs += thisrelocs;
|
||||||
|
lines += thislines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sanity_check (abfd);
|
||||||
|
}
|
||||||
|
/**********************************************************************/
|
||||||
void
|
void
|
||||||
ldwrite ()
|
ldwrite ()
|
||||||
{
|
{
|
||||||
lang_for_each_statement (build_link_order);
|
lang_for_each_statement (build_link_order);
|
||||||
|
|
||||||
if (! bfd_final_link (output_bfd, &link_info))
|
if (config.split_by_reloc || config.split_by_file)
|
||||||
|
split_sections (output_bfd, &link_info);
|
||||||
|
if (!bfd_final_link (output_bfd, &link_info))
|
||||||
einfo ("%F%P: final link failed: %E\n", output_bfd);
|
einfo ("%F%P: final link failed: %E\n", output_bfd);
|
||||||
|
|
||||||
if (config.map_file)
|
if (config.map_file)
|
||||||
@ -228,7 +437,7 @@ print_symbol_table ()
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
print_file_stuff (f)
|
print_file_stuff (f)
|
||||||
lang_input_statement_type * f;
|
lang_input_statement_type *f;
|
||||||
{
|
{
|
||||||
fprintf (config.map_file, " %s\n", f->filename);
|
fprintf (config.map_file, " %s\n", f->filename);
|
||||||
if (f->just_syms_flag)
|
if (f->just_syms_flag)
|
||||||
|
Reference in New Issue
Block a user