Implement MEMORY attributes for unknown sections
This commit is contained in:
parent
a26171caf4
commit
d3c324e51d
5 changed files with 214 additions and 30 deletions
27
ld/ChangeLog
27
ld/ChangeLog
|
@ -1,4 +1,31 @@
|
|||
Fri Jan 2 20:15:37 1998 Michael Meissner <meissner@cygnus.com>
|
||||
|
||||
* ldgram.y (attributes_opt): Pass region pointer to
|
||||
lang_set_flags, not ®ion->flags.
|
||||
|
||||
* ldlang.c (lang_memory_default): New function to figure out a
|
||||
default memory region for a section if it was not specified.
|
||||
(lang_memory_region_lookup): Zero flags, not_flags field.
|
||||
(lang_map{,_flags}): Print attribute flags in memory map.
|
||||
(lang_size_sections): Call lang_memory_default to get default
|
||||
memory region.
|
||||
(lang_set_flags): Implement attribute flags for real. Take new
|
||||
argument to give the flags we are to skip for this region.
|
||||
|
||||
* ldlang.h (memory_region_struct): Add not_flags field, make both
|
||||
flags fields flagword type.
|
||||
(lang_output_section_state): Make flags field flagword type.
|
||||
(lang_set_flags): Update prototype to match new calling sequence.
|
||||
(lang_memory_region_default): Add prototype.
|
||||
|
||||
start-sanitize-d30v
|
||||
* emulparams/d30v{_e,_o,elf}.sh ({TEXT,DATA,EMEM}_DEF_SECTION):
|
||||
Define whether or not the region gets default sections, and if so,
|
||||
what sections.
|
||||
|
||||
* scripttempl/elfd30v.sc (MEMORY): Set up which of the regions get
|
||||
default sections.
|
||||
|
||||
Thu Jan 1 22:58:04 1998 Michael Meissner <meissner@cygnus.com>
|
||||
|
||||
* scripttempl/elfd30v.sc (.eh_frame): Link into the data section.
|
||||
|
|
18
ld/emulparams/d30v_e.sh
Normal file
18
ld/emulparams/d30v_e.sh
Normal file
|
@ -0,0 +1,18 @@
|
|||
MACHINE=
|
||||
SCRIPT_NAME=elfd30v
|
||||
OUTPUT_FORMAT="elf32-d30v"
|
||||
TEXT_START_ADDR=0x00000000
|
||||
DATA_START_ADDR=0x20000000
|
||||
EMEM_START_ADDR=0x80000000
|
||||
STACK_START_ADDR=0x20008000
|
||||
TEXT_SIZE=64K
|
||||
DATA_SIZE=32K
|
||||
EMEM_SIZE=8M
|
||||
TEXT_MEMORY=emem
|
||||
DATA_MEMORY=emem
|
||||
BSS_MEMORY=emem
|
||||
TEXT_DEF_SECTION=""
|
||||
DATA_DEF_SECTION=""
|
||||
EMEM_DEF_SECTION="(rwx)"
|
||||
ARCH=d30v
|
||||
EMBEDDED=t
|
18
ld/emulparams/d30v_o.sh
Normal file
18
ld/emulparams/d30v_o.sh
Normal file
|
@ -0,0 +1,18 @@
|
|||
MACHINE=
|
||||
SCRIPT_NAME=elfd30v
|
||||
OUTPUT_FORMAT="elf32-d30v"
|
||||
TEXT_START_ADDR=0x00000000
|
||||
DATA_START_ADDR=0x20000000
|
||||
EMEM_START_ADDR=0x80000000
|
||||
STACK_START_ADDR=0x20008000
|
||||
TEXT_SIZE=64K
|
||||
DATA_SIZE=32K
|
||||
EMEM_SIZE=8M
|
||||
TEXT_MEMORY=text
|
||||
DATA_MEMORY=data
|
||||
BSS_MEMORY=data
|
||||
TEXT_DEF_SECTION="(x)"
|
||||
DATA_DEF_SECTION="(rw)"
|
||||
EMEM_DEF_SECTION=""
|
||||
ARCH=d30v
|
||||
EMBEDDED=t
|
18
ld/emulparams/d30velf.sh
Normal file
18
ld/emulparams/d30velf.sh
Normal file
|
@ -0,0 +1,18 @@
|
|||
MACHINE=
|
||||
SCRIPT_NAME=elfd30v
|
||||
OUTPUT_FORMAT="elf32-d30v"
|
||||
TEXT_START_ADDR=0x00000000
|
||||
DATA_START_ADDR=0x20000000
|
||||
EMEM_START_ADDR=0x80000000
|
||||
STACK_START_ADDR=0x20008000
|
||||
TEXT_SIZE=64K
|
||||
DATA_SIZE=32K
|
||||
EMEM_SIZE=8M
|
||||
TEXT_MEMORY=text
|
||||
DATA_MEMORY=data
|
||||
BSS_MEMORY=data
|
||||
TEXT_DEF_SECTION="(x)"
|
||||
DATA_DEF_SECTION="(rw)"
|
||||
EMEM_DEF_SECTION=""
|
||||
ARCH=d30v
|
||||
EMBEDDED=t
|
163
ld/ldlang.c
163
ld/ldlang.c
|
@ -128,6 +128,7 @@ static bfd_vma size_input_section
|
|||
lang_output_section_statement_type *output_section_statement,
|
||||
fill_type fill, bfd_vma dot, boolean relax));
|
||||
static void lang_finish PARAMS ((void));
|
||||
static void ignore_bfd_errors PARAMS ((const char *, ...));
|
||||
static void lang_check PARAMS ((void));
|
||||
static void lang_common PARAMS ((void));
|
||||
static boolean lang_one_common PARAMS ((struct bfd_link_hash_entry *, PTR));
|
||||
|
@ -412,7 +413,6 @@ lang_memory_region_type *
|
|||
lang_memory_region_lookup (name)
|
||||
CONST char *CONST name;
|
||||
{
|
||||
|
||||
lang_memory_region_type *p;
|
||||
|
||||
for (p = lang_memory_region_list;
|
||||
|
@ -451,6 +451,8 @@ lang_memory_region_lookup (name)
|
|||
*lang_memory_region_list_tail = new;
|
||||
lang_memory_region_list_tail = &new->next;
|
||||
new->origin = 0;
|
||||
new->flags = 0;
|
||||
new->not_flags = 0;
|
||||
new->length = ~(bfd_size_type)0;
|
||||
new->current = 0;
|
||||
new->had_full_message = false;
|
||||
|
@ -460,6 +462,31 @@ lang_memory_region_lookup (name)
|
|||
}
|
||||
|
||||
|
||||
lang_memory_region_type *
|
||||
lang_memory_default (section)
|
||||
asection *section;
|
||||
{
|
||||
lang_memory_region_type *p;
|
||||
|
||||
flagword sec_flags = section->flags;
|
||||
|
||||
/* Override SEC_DATA to mean a writable section. */
|
||||
if (sec_flags & (SEC_ALLOC | SEC_READONLY | SEC_CODE) == SEC_ALLOC)
|
||||
sec_flags |= SEC_DATA;
|
||||
|
||||
for (p = lang_memory_region_list;
|
||||
p != (lang_memory_region_type *) NULL;
|
||||
p = p->next)
|
||||
{
|
||||
if ((p->flags & sec_flags) != 0
|
||||
&& (p->not_flags & sec_flags) == 0)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return lang_memory_region_lookup ("*default*");
|
||||
}
|
||||
|
||||
lang_output_section_statement_type *
|
||||
lang_output_section_find (name)
|
||||
CONST char *CONST name;
|
||||
|
@ -518,14 +545,34 @@ lang_output_section_statement_lookup (name)
|
|||
return lookup;
|
||||
}
|
||||
|
||||
static void
|
||||
lang_map_flags (flag)
|
||||
flagword flag;
|
||||
{
|
||||
if (flag & SEC_ALLOC)
|
||||
minfo ("a");
|
||||
|
||||
if (flag & SEC_CODE)
|
||||
minfo ("x");
|
||||
|
||||
if (flag & SEC_READONLY)
|
||||
minfo ("r");
|
||||
|
||||
if (flag & SEC_DATA)
|
||||
minfo ("w");
|
||||
|
||||
if (flag & SEC_LOAD)
|
||||
minfo ("l");
|
||||
}
|
||||
|
||||
void
|
||||
lang_map ()
|
||||
{
|
||||
lang_memory_region_type *m;
|
||||
|
||||
minfo ("\nMemory Configuration\n\n");
|
||||
fprintf (config.map_file, "%-16s %-18s %-18s\n",
|
||||
"Name", "Origin", "Length");
|
||||
fprintf (config.map_file, "%-16s %-18s %-18s %s\n",
|
||||
"Name", "Origin", "Length", "Attributes");
|
||||
|
||||
for (m = lang_memory_region_list;
|
||||
m != (lang_memory_region_type *) NULL;
|
||||
|
@ -545,7 +592,26 @@ lang_map ()
|
|||
++len;
|
||||
}
|
||||
|
||||
minfo ("0x%V\n", m->length);
|
||||
minfo ("0x%V", m->length);
|
||||
if (m->flags || m->not_flags)
|
||||
{
|
||||
#ifndef BFD64
|
||||
minfo (" ");
|
||||
#endif
|
||||
if (m->flags)
|
||||
{
|
||||
print_space ();
|
||||
lang_map_flags (m->flags);
|
||||
}
|
||||
|
||||
if (m->not_flags)
|
||||
{
|
||||
minfo (" !");
|
||||
lang_map_flags (m->not_flags);
|
||||
}
|
||||
}
|
||||
|
||||
print_nl ();
|
||||
}
|
||||
|
||||
fprintf (config.map_file, "\nLinker script and memory map\n\n");
|
||||
|
@ -2101,7 +2167,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
|
|||
*/
|
||||
if (os->region == (lang_memory_region_type *) NULL)
|
||||
{
|
||||
os->region = lang_memory_region_lookup ("*default*");
|
||||
os->region = lang_memory_default (os->bfd_section);
|
||||
}
|
||||
dot = os->region->current;
|
||||
if (os->section_alignment == -1)
|
||||
|
@ -2630,6 +2696,20 @@ lang_finish ()
|
|||
}
|
||||
}
|
||||
|
||||
/* This is a small function used when we want to ignore errors from
|
||||
BFD. */
|
||||
|
||||
static void
|
||||
#ifdef ANSI_PROTOTYPES
|
||||
ignore_bfd_errors (const char *s, ...)
|
||||
#else
|
||||
ignore_bfd_errors (s)
|
||||
const char *s;
|
||||
#endif
|
||||
{
|
||||
/* Don't do anything. */
|
||||
}
|
||||
|
||||
/* Check that the architecture of all the input files is compatible
|
||||
with the output file. Also call the backend to let it do any
|
||||
other checking that is needed. */
|
||||
|
@ -2649,13 +2729,31 @@ lang_check ()
|
|||
compatible = bfd_arch_get_compatible (input_bfd,
|
||||
output_bfd);
|
||||
if (compatible == NULL)
|
||||
einfo ("%P: warning: %s architecture of input file `%B' is incompatible with %s output\n",
|
||||
bfd_printable_name (input_bfd), input_bfd,
|
||||
bfd_printable_name (output_bfd));
|
||||
|
||||
else if (! bfd_merge_private_bfd_data (input_bfd, output_bfd))
|
||||
{
|
||||
einfo ("%E%X: failed to merge target specific data of file %B\n", input_bfd);
|
||||
if (command_line.warn_mismatch)
|
||||
einfo ("%P: warning: %s architecture of input file `%B' is incompatible with %s output\n",
|
||||
bfd_printable_name (input_bfd), input_bfd,
|
||||
bfd_printable_name (output_bfd));
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_error_handler_type pfn;
|
||||
|
||||
/* If we aren't supposed to warn about mismatched input
|
||||
files, temporarily set the BFD error handler to a
|
||||
function which will do nothing. We still want to call
|
||||
bfd_merge_private_bfd_data, since it may set up
|
||||
information which is needed in the output file. */
|
||||
if (! command_line.warn_mismatch)
|
||||
pfn = bfd_set_error_handler (ignore_bfd_errors);
|
||||
if (! bfd_merge_private_bfd_data (input_bfd, output_bfd))
|
||||
{
|
||||
if (command_line.warn_mismatch)
|
||||
einfo ("%E%X: failed to merge target specific data of file %B\n",
|
||||
input_bfd);
|
||||
}
|
||||
if (! command_line.warn_mismatch)
|
||||
bfd_set_error_handler (pfn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2853,36 +2951,41 @@ lang_place_orphans ()
|
|||
|
||||
void
|
||||
lang_set_flags (ptr, flags)
|
||||
int *ptr;
|
||||
lang_memory_region_type *ptr;
|
||||
CONST char *flags;
|
||||
{
|
||||
boolean state = false;
|
||||
flagword *ptr_flags = &ptr->flags;
|
||||
|
||||
*ptr = 0;
|
||||
ptr->flags = ptr->not_flags = 0;
|
||||
while (*flags)
|
||||
{
|
||||
if (*flags == '!')
|
||||
{
|
||||
state = false;
|
||||
flags++;
|
||||
}
|
||||
else
|
||||
state = true;
|
||||
switch (*flags)
|
||||
{
|
||||
case 'R':
|
||||
/* ptr->flag_read = state; */
|
||||
case '!':
|
||||
ptr_flags = (ptr_flags == &ptr->flags) ? &ptr->not_flags : &ptr->flags;
|
||||
break;
|
||||
case 'W':
|
||||
/* ptr->flag_write = state; */
|
||||
|
||||
case 'A': case 'a':
|
||||
*ptr_flags |= SEC_ALLOC;
|
||||
break;
|
||||
case 'X':
|
||||
/* ptr->flag_executable= state;*/
|
||||
|
||||
case 'R': case 'r':
|
||||
*ptr_flags |= SEC_READONLY;
|
||||
break;
|
||||
case 'L':
|
||||
case 'I':
|
||||
/* ptr->flag_loadable= state;*/
|
||||
|
||||
case 'W': case 'w':
|
||||
*ptr_flags |= SEC_DATA;
|
||||
break;
|
||||
|
||||
case 'X': case 'x':
|
||||
*ptr_flags |= SEC_CODE;
|
||||
break;
|
||||
|
||||
case 'L': case 'l':
|
||||
case 'I': case 'i':
|
||||
*ptr_flags |= SEC_LOAD;
|
||||
break;
|
||||
|
||||
default:
|
||||
einfo ("%P%F: invalid syntax in flags\n");
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue