1 # This shell script emits a C file. -*- C -*-
2 # It does some substitutions.
3 cat >e${EMULATION_NAME}.c <<EOF
4 /* This file is is generated by a shell script. DO NOT EDIT! */
6 /* SunOS emulation code for ${EMULATION_NAME}
7 Copyright (C) 1991, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
8 Written by Steve Chamberlain <sac@cygnus.com>
9 SunOS shared library support by Ian Lance Taylor <ian@cygnus.com>
11 This file is part of GLD, the Gnu Linker.
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 #define TARGET_IS_${EMULATION_NAME}
30 #include <sys/types.h>
36 #include "libiberty.h"
49 # define dirent direct
50 # ifdef HAVE_SYS_NDIR_H
51 # include <sys/ndir.h>
53 # ifdef HAVE_SYS_DIR_H
61 static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
62 static void gld${EMULATION_NAME}_set_symbols PARAMS ((void));
63 static void gld${EMULATION_NAME}_create_output_section_statements
65 static void gld${EMULATION_NAME}_find_so
66 PARAMS ((lang_input_statement_type *));
67 static char *gld${EMULATION_NAME}_search_dir
68 PARAMS ((const char *, const char *, boolean *));
69 static void gld${EMULATION_NAME}_after_open PARAMS ((void));
70 static void gld${EMULATION_NAME}_check_needed
71 PARAMS ((lang_input_statement_type *));
72 static boolean gld${EMULATION_NAME}_search_needed
73 PARAMS ((const char *, const char *));
74 static boolean gld${EMULATION_NAME}_try_needed
75 PARAMS ((const char *, const char *));
76 static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
77 static void gld${EMULATION_NAME}_find_assignment
78 PARAMS ((lang_statement_union_type *));
79 static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
80 static void gld${EMULATION_NAME}_count_need
81 PARAMS ((lang_input_statement_type *));
82 static void gld${EMULATION_NAME}_set_need
83 PARAMS ((lang_input_statement_type *));
84 static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
87 gld${EMULATION_NAME}_before_parse()
89 ldfile_output_architecture = bfd_arch_${ARCH};
90 config.dynamic_link = true;
93 /* This is called after the command line arguments have been parsed,
94 but before the linker script has been read. If this is a native
95 linker, we add the directories in LD_LIBRARY_PATH to the search
99 gld${EMULATION_NAME}_set_symbols ()
102 if [ "x${host}" = "x${target}" ] ; then
103 if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
104 cat >>e${EMULATION_NAME}.c <<EOF
107 env = (const char *) getenv ("LD_LIBRARY_PATH");
121 ldfile_add_library_path (l, false);
130 cat >>e${EMULATION_NAME}.c <<EOF
133 /* Despite the name, we use this routine to search for dynamic
134 libraries. On SunOS this requires a directory search. We need to
135 find the .so file with the highest version number. The user may
136 restrict the major version by saying, e.g., -lc.1. Also, if we
137 find a .so file, we need to look for a the same file after
138 replacing .so with .sa; if it exists, it will be an archive which
139 provide some initializations for data symbols, and we need to
140 search it after including the .so file. */
143 gld${EMULATION_NAME}_create_output_section_statements ()
145 lang_for_each_input_file (gld${EMULATION_NAME}_find_so);
148 /* Search the directory for a .so file for each library search. */
151 gld${EMULATION_NAME}_find_so (inp)
152 lang_input_statement_type *inp;
154 search_dirs_type *search;
159 if (! inp->search_dirs_flag
164 ASSERT (strncmp (inp->local_sym_name, "-l", 2) == 0);
166 for (search = search_head; search != NULL; search = search->next)
168 boolean found_static;
170 found = gld${EMULATION_NAME}_search_dir (search->name, inp->filename,
172 if (found != NULL || found_static)
178 /* We did not find a matching .so file. This isn't an error,
179 since there might still be a matching .a file, which will be
180 found by the usual search. */
184 /* Replace the filename with the one we have found. */
185 alc = (char *) xmalloc (strlen (search->name) + strlen (found) + 2);
186 sprintf (alc, "%s/%s", search->name, found);
189 /* Turn off the search_dirs_flag to prevent ldfile_open_file from
190 searching for this file again. */
191 inp->search_dirs_flag = false;
195 /* Now look for the same file name, but with .sa instead of .so. If
196 found, add it to the list of input files. */
197 alc = (char *) xmalloc (strlen (inp->filename) + 1);
198 strcpy (alc, inp->filename);
199 strstr (alc + strlen (search->name), ".so.")[2] = 'a';
200 if (stat (alc, &st) != 0)
204 lang_input_statement_type *sa;
206 /* Add the .sa file to the statement list just before the .so
207 file. This is really a hack. */
208 sa = ((lang_input_statement_type *)
209 xmalloc (sizeof (lang_input_statement_type)));
213 inp->local_sym_name = alc;
215 inp->header.next = (lang_statement_union_type *) sa;
216 inp->next_real_file = (lang_statement_union_type *) sa;
220 /* Search a directory for a .so file. */
223 gld${EMULATION_NAME}_search_dir (dirname, filename, found_static)
225 const char *filename;
226 boolean *found_static;
228 int force_maj, force_min;
233 int max_maj, max_min;
235 struct dirent *entry;
237 *found_static = false;
241 dot = strchr (filename, '.');
244 len = strlen (filename);
249 force_maj = atoi (dot + 1);
251 len = dot - filename;
252 alc = (char *) xmalloc (len + 1);
253 strncpy (alc, filename, len);
257 dot = strchr (dot + 1, '.');
259 force_min = atoi (dot + 1);
263 max_maj = max_min = 0;
265 dir = opendir (dirname);
269 while ((entry = readdir (dir)) != NULL)
272 int found_maj, found_min;
274 if (strncmp (entry->d_name, "lib", 3) != 0
275 || strncmp (entry->d_name + 3, filename, len) != 0)
279 && strcmp (entry->d_name + 3 + len, ".a") == 0)
281 *found_static = true;
285 if (strncmp (entry->d_name + 3 + len, ".so.", 4) != 0
286 || ! isdigit (entry->d_name[7 + len]))
289 for (s = entry->d_name + 7 + len; *s != '\0'; s++)
290 if (*s != '.' && ! isdigit (*s))
295 /* We've found a .so file. Work out the major and minor
299 sscanf (entry->d_name + 3 + len, ".so.%d.%d",
300 &found_maj, &found_min);
302 if ((force_maj != -1 && force_maj != found_maj)
303 || (force_min != -1 && force_min != found_min))
306 /* We've found a match for the name we are searching for. See
307 if this is the version we should use. If the major and minor
308 versions match, we use the last entry in alphabetical order;
309 I don't know if this is how SunOS distinguishes libc.so.1.8
310 from libc.so.1.8.1, but it ought to suffice. */
312 || (found_maj > max_maj)
313 || (found_maj == max_maj
314 && (found_min > max_min
315 || (found_min == max_min
316 && strcmp (entry->d_name, found) > 0))))
320 found = (char *) xmalloc (strlen (entry->d_name) + 1);
321 strcpy (found, entry->d_name);
335 /* These variables are required to pass information back and forth
336 between after_open and check_needed. */
338 static struct bfd_link_needed_list *global_needed;
339 static boolean global_found;
341 /* This is called after all the input files have been opened. */
344 gld${EMULATION_NAME}_after_open ()
346 struct bfd_link_needed_list *needed, *l;
348 /* We only need to worry about this when doing a final link. */
349 if (link_info.relocateable || link_info.shared)
352 /* Get the list of files which appear in ld_need entries in dynamic
353 objects included in the link. For each such file, we want to
354 track down the corresponding library, and include the symbol
355 table in the link. This is what the runtime dynamic linker will
356 do. Tracking the files down here permits one dynamic object to
357 include another without requiring special action by the person
358 doing the link. Note that the needed list can actually grow
359 while we are stepping through this loop. */
360 needed = bfd_sunos_get_needed_list (output_bfd, &link_info);
361 for (l = needed; l != NULL; l = l->next)
363 struct bfd_link_needed_list *ll;
365 search_dirs_type *search;
369 /* If we've already seen this file, skip it. */
370 for (ll = needed; ll != l; ll = ll->next)
371 if (strcmp (ll->name, lname) == 0)
376 /* See if this file was included in the link explicitly. */
378 global_found = false;
379 lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
383 if (strncmp (lname, "-l", 2) != 0)
387 abfd = bfd_openr (lname, bfd_get_target (output_bfd));
390 if (! bfd_check_format (abfd, bfd_object))
392 (void) bfd_close (abfd);
398 if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
400 (void) bfd_close (abfd);
406 /* We've found the needed dynamic object. */
407 if (! bfd_link_add_symbols (abfd, &link_info))
408 einfo ("%F%B: could not read symbols: %E\n", abfd);
412 einfo ("%P: warning: %s, needed by %B, not found\n",
421 /* We want to search for the file in the same way that the
422 dynamic linker will search. That means that we want to use
423 rpath_link, rpath or -L, then the environment variable
424 LD_LIBRARY_PATH (native only), then (if rpath was used) the
425 linker script LIB_SEARCH_DIRS. */
426 if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
429 if (command_line.rpath != NULL)
431 if (gld${EMULATION_NAME}_search_needed (command_line.rpath, lname))
436 for (search = search_head; search != NULL; search = search->next)
437 if (gld${EMULATION_NAME}_try_needed (search->name, lname))
443 if [ "x${host}" = "x${target}" ] ; then
444 if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
445 cat >>e${EMULATION_NAME}.c <<EOF
447 const char *lib_path;
449 lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
450 if (gld${EMULATION_NAME}_search_needed (lib_path, lname))
456 cat >>e${EMULATION_NAME}.c <<EOF
457 if (command_line.rpath != NULL)
459 for (search = search_head; search != NULL; search = search->next)
463 if (gld${EMULATION_NAME}_try_needed (search->name, lname))
470 einfo ("%P: warning: %s, needed by %B, not found\n",
475 /* Search for a needed file in a path. */
478 gld${EMULATION_NAME}_search_needed (path, name)
484 if (path == NULL || *path == '\0')
491 s = strchr (path, ':');
499 dircopy = (char *) xmalloc (s - path + 1);
500 memcpy (dircopy, path, s - path);
501 dircopy[s - path] = '\0';
505 if (gld${EMULATION_NAME}_try_needed (dir, name))
519 /* This function is called for each possible directory for a needed
523 gld${EMULATION_NAME}_try_needed (dir, name)
532 file = gld${EMULATION_NAME}_search_dir (dir, name, &ignore);
536 alc = (char *) xmalloc (strlen (dir) + strlen (file) + 2);
537 sprintf (alc, "%s/%s", dir, file);
539 abfd = bfd_openr (alc, bfd_get_target (output_bfd));
542 if (! bfd_check_format (abfd, bfd_object))
544 (void) bfd_close (abfd);
547 if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
549 (void) bfd_close (abfd);
553 /* We've found the needed dynamic object. */
555 /* Add this file into the symbol table. */
556 if (! bfd_link_add_symbols (abfd, &link_info))
557 einfo ("%F%B: could not read symbols: %E\n", abfd);
562 /* See if we have already included a needed object in the link. This
563 does not have to be precise, as it does no harm to include a
564 dynamic object more than once. */
567 gld${EMULATION_NAME}_check_needed (s)
568 lang_input_statement_type *s;
570 if (s->filename == NULL)
572 if (strncmp (global_needed->name, "-l", 2) != 0)
574 if (strcmp (s->filename, global_needed->name) == 0)
579 const char *sname, *lname;
580 const char *sdot, *ldot;
581 int lmaj, lmin, smaj, smin;
583 lname = global_needed->name + 2;
585 sname = strrchr (s->filename, '/');
591 if (strncmp (sname, "lib", 3) != 0)
595 ldot = strchr (lname, '.');
597 ldot = lname + strlen (lname);
599 sdot = strstr (sname, ".so.");
603 if (sdot - sname != ldot - lname
604 || strncmp (lname, sname, sdot - sname) != 0)
608 sscanf (ldot, ".%d.%d", &lmaj, &lmin);
610 sscanf (sdot, ".so.%d.%d", &smaj, &smin);
611 if ((smaj != lmaj && smaj != -1 && lmaj != -1)
612 || (smin != lmin && smin != -1 && lmin != -1))
619 /* We need to use static variables to pass information around the call
620 to lang_for_each_statement. Ick. */
622 static const char *find_assign;
623 static boolean found_assign;
625 /* We need to use static variables to pass information around the call
626 to lang_for_each_input_file. Ick. */
628 static bfd_size_type need_size;
629 static bfd_size_type need_entries;
630 static bfd_byte *need_contents;
631 static bfd_byte *need_pinfo;
632 static bfd_byte *need_pnames;
634 /* The size of one entry in the .need section, not including the file
637 #define NEED_ENTRY_SIZE (16)
639 /* This is called after the sections have been attached to output
640 sections, but before any sizes or addresses have been set. */
643 gld${EMULATION_NAME}_before_allocation ()
645 struct bfd_link_hash_entry *hdyn = NULL;
650 /* The SunOS native linker creates a shared library whenever there
651 are any undefined symbols in a link, unless -e is used. This is
652 pretty weird, but we are compatible. */
653 if (! link_info.shared && ! link_info.relocateable && ! entry_from_cmdline)
655 struct bfd_link_hash_entry *h;
657 for (h = link_info.hash->undefs; h != NULL; h = h->next)
659 if (h->type == bfd_link_hash_undefined
660 && h->u.undef.abfd != NULL
661 && (h->u.undef.abfd->flags & DYNAMIC) == 0
662 && strcmp (h->root.string, "__DYNAMIC") != 0
663 && strcmp (h->root.string, "__GLOBAL_OFFSET_TABLE_") != 0)
665 find_assign = h->root.string;
666 found_assign = false;
667 lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
670 link_info.shared = true;
677 if (link_info.shared)
679 lang_output_section_statement_type *os;
681 /* Set the .text section to start at 0x20, not 0x2020. FIXME:
682 This is too magical. */
683 os = lang_output_section_statement_lookup (".text");
684 if (os->addr_tree == NULL)
685 os->addr_tree = exp_intop (0x20);
688 /* We need to create a __DYNAMIC symbol. We don't do this in the
689 linker script because we want to set the value to the start of
690 the dynamic section if there is one, or to zero if there isn't
691 one. We need to create the symbol before calling
692 size_dynamic_sections, although we can't set the value until
694 if (! link_info.relocateable)
696 hdyn = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", true, false,
699 einfo ("%P%F: bfd_link_hash_lookup: %E\n");
700 if (! bfd_sunos_record_link_assignment (output_bfd, &link_info,
702 einfo ("%P%F: failed to record assignment to __DYNAMIC: %E\n");
705 /* If we are going to make any variable assignments, we need to let
706 the backend linker know about them in case the variables are
707 referred to by dynamic objects. */
708 lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
710 /* Let the backend linker work out the sizes of any sections
711 required by dynamic linking. */
712 if (! bfd_sunos_size_dynamic_sections (output_bfd, &link_info, &sdyn,
714 einfo ("%P%F: failed to set dynamic section sizes: %E\n");
718 /* Set up the .need section. See the description of the ld_need
719 field in include/aout/sun4.h. */
724 lang_for_each_input_file (gld${EMULATION_NAME}_count_need);
726 /* We should only have a .need section if we have at least one
728 ASSERT (need_entries != 0);
730 sneed->_raw_size = need_size;
731 sneed->contents = (bfd_byte *) xmalloc (need_size);
733 need_contents = sneed->contents;
734 need_pinfo = sneed->contents;
735 need_pnames = sneed->contents + need_entries * 16;
737 lang_for_each_input_file (gld${EMULATION_NAME}_set_need);
739 ASSERT ((bfd_size_type) (need_pnames - sneed->contents) == need_size);
744 /* Set up the .rules section. This is just a PATH like string
745 of the -L arguments given on the command line. We permit the
746 user to specify the directories using the -rpath command line
748 if (command_line.rpath)
750 srules->_raw_size = strlen (command_line.rpath);
751 srules->contents = (bfd_byte *) command_line.rpath;
756 search_dirs_type *search;
759 for (search = search_head; search != NULL; search = search->next)
761 size += strlen (search->name) + 1;
762 srules->_raw_size = size;
767 srules->contents = (bfd_byte *) xmalloc (size);
768 p = (char *) srules->contents;
770 for (search = search_head; search != NULL; search = search->next)
774 if (p != (char *) srules->contents)
776 strcpy (p, search->name);
784 /* We must assign a value to __DYNAMIC. It should be zero if we are
785 not doing a dynamic link, or the start of the .dynamic section if
787 if (! link_info.relocateable)
789 hdyn->type = bfd_link_hash_defined;
790 hdyn->u.def.value = 0;
792 hdyn->u.def.section = sdyn;
794 hdyn->u.def.section = bfd_abs_section_ptr;
798 /* This is called by the before_allocation routine via
799 lang_for_each_statement. It does one of two things: if the
800 variable find_assign is set, it sets found_assign if it finds an
801 assignment to that variable; otherwise it tells the backend linker
802 about all assignment statements, in case they are assignments to
803 symbols which are referred to by dynamic objects. */
806 gld${EMULATION_NAME}_find_assignment (s)
807 lang_statement_union_type *s;
809 if (s->header.type == lang_assignment_statement_enum
810 && (find_assign == NULL || ! found_assign))
811 gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
814 /* Look through an expression for an assignment statement. */
817 gld${EMULATION_NAME}_find_exp_assignment (exp)
820 switch (exp->type.node_class)
823 if (find_assign != NULL)
825 if (strcmp (find_assign, exp->assign.dst) == 0)
830 if (strcmp (exp->assign.dst, ".") != 0)
832 if (! bfd_sunos_record_link_assignment (output_bfd, &link_info,
834 einfo ("%P%F: failed to record assignment to %s: %E\n",
837 gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
841 gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
842 gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
846 gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
847 gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
848 gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
852 gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
860 /* Work out the size of the .need section, and the number of entries.
861 The backend will set the ld_need field of the dynamic linking
862 information to point to the .need section. See include/aout/sun4.h
863 for more information. */
866 gld${EMULATION_NAME}_count_need (inp)
867 lang_input_statement_type *inp;
869 if (inp->the_bfd != NULL
870 && (inp->the_bfd->flags & DYNAMIC) != 0)
873 need_size += NEED_ENTRY_SIZE;
874 if (! inp->is_archive)
875 need_size += strlen (inp->filename) + 1;
878 ASSERT (inp->local_sym_name[0] == '-'
879 && inp->local_sym_name[1] == 'l');
880 need_size += strlen (inp->local_sym_name + 2) + 1;
885 /* Fill in the contents of the .need section. */
888 gld${EMULATION_NAME}_set_need (inp)
889 lang_input_statement_type *inp;
891 if (inp->the_bfd != NULL
892 && (inp->the_bfd->flags & DYNAMIC) != 0)
896 /* To really fill in the .need section contents, we need to know
897 the final file position of the section, but we don't.
898 Instead, we use offsets, and rely on the BFD backend to
899 finish the section up correctly. FIXME: Talk about lack of
900 referential locality. */
901 bfd_put_32 (output_bfd, need_pnames - need_contents, need_pinfo);
902 if (! inp->is_archive)
904 bfd_put_32 (output_bfd, (bfd_vma) 0, need_pinfo + 4);
905 bfd_put_16 (output_bfd, (bfd_vma) 0, need_pinfo + 8);
906 bfd_put_16 (output_bfd, (bfd_vma) 0, need_pinfo + 10);
907 strcpy (need_pnames, inp->filename);
914 bfd_put_32 (output_bfd, (bfd_vma) 0x80000000, need_pinfo + 4);
917 verstr = strstr (inp->filename, ".so.");
919 sscanf (verstr, ".so.%d.%d", &maj, &min);
920 bfd_put_16 (output_bfd, (bfd_vma) maj, need_pinfo + 8);
921 bfd_put_16 (output_bfd, (bfd_vma) min, need_pinfo + 10);
922 strcpy (need_pnames, inp->local_sym_name + 2);
925 c = (need_pinfo - need_contents) / NEED_ENTRY_SIZE;
926 if (c + 1 >= need_entries)
927 bfd_put_32 (output_bfd, (bfd_vma) 0, need_pinfo + 12);
929 bfd_put_32 (output_bfd, (bfd_vma) (c + 1) * NEED_ENTRY_SIZE,
932 need_pinfo += NEED_ENTRY_SIZE;
933 need_pnames += strlen (need_pnames) + 1;
938 gld${EMULATION_NAME}_get_script(isfile)
942 if test -n "$COMPILE_IN"
944 # Scripts compiled in.
946 # sed commands to quote an ld script as a C string.
953 cat >>e${EMULATION_NAME}.c <<EOF
957 if (link_info.relocateable == true && config.build_constructors == true)
958 return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
959 else if (link_info.relocateable == true)
960 return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
961 else if (!config.text_read_only)
962 return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
963 else if (!config.magic_demand_paged)
964 return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
966 return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
971 # Scripts read from the filesystem.
973 cat >>e${EMULATION_NAME}.c <<EOF
977 if (link_info.relocateable == true && config.build_constructors == true)
978 return "ldscripts/${EMULATION_NAME}.xu";
979 else if (link_info.relocateable == true)
980 return "ldscripts/${EMULATION_NAME}.xr";
981 else if (!config.text_read_only)
982 return "ldscripts/${EMULATION_NAME}.xbn";
983 else if (!config.magic_demand_paged)
984 return "ldscripts/${EMULATION_NAME}.xn";
986 return "ldscripts/${EMULATION_NAME}.x";
992 cat >>e${EMULATION_NAME}.c <<EOF
994 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
996 gld${EMULATION_NAME}_before_parse,
1000 gld${EMULATION_NAME}_after_open,
1001 after_allocation_default,
1002 set_output_arch_default,
1003 ldemul_default_target,
1004 gld${EMULATION_NAME}_before_allocation,
1005 gld${EMULATION_NAME}_get_script,
1006 "${EMULATION_NAME}",
1009 gld${EMULATION_NAME}_create_output_section_statements,
1010 NULL, /* open_dynamic_library */
1011 NULL, /* place_orphan */
1012 gld${EMULATION_NAME}_set_symbols