+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.
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));
lang_memory_region_lookup (name)
CONST char *CONST name;
{
-
lang_memory_region_type *p;
for (p = lang_memory_region_list;
*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;
}
+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;
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;
++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");
*/
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)
}
}
+/* 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. */
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);
}
}
}
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 'W': case 'w':
+ *ptr_flags |= SEC_DATA;
break;
- case 'L':
- case 'I':
- /* ptr->flag_loadable= state;*/
+
+ 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;