[gdb/contrib] Fix shellcheck warnings in spellcheck.sh
[binutils-gdb.git] / ld / emultempl / nto.em
blob7cda6650bc6188b25ce5d36cfab06c856f9aecb3
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright (C) 2023-2024 Free Software Foundation, Inc.
4 # This file is part of GLD, the Gnu Linker.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
21 # This file is sourced from elf.em, and defines extra Neutrino
22 # specific routines.
24 # NTO templates aims to refine the default ${ARCH}elf.em template.
25 . "${srcdir}/emultempl/${ARCH}elf.em"
27 cat >>e${EMULATION_NAME}.c <<EOF
29 #include "elf/internal.h"
30 #include "elf/common.h"
31 #include "elf-bfd.h"
32 #include "../bfd/libbfd.h"
34 bool nto_lazy_stack = false;
35 struct nto_stack_note
37   unsigned char stacksize[4];
38   unsigned char stackalloc[4];
39   unsigned char execstack[4];
42 static asection*
43 nto_create_QNX_note_section(int type)
45   asection *note_sec;
46   flagword flags;
47   Elf_External_Note *e_note;
48   bfd_size_type size;
50   /* As ${ARCH}elf.em is imported and ${ARCH}_elf_create_output_section_statements
51      is called before this function, stub_file should already be defined.  */
52   if (!stub_file)
53     {
54       einfo (_("%F%P: cannot create .note section in stub BFD.\n"));
55       return NULL;
56     }
58   flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
59            | SEC_IN_MEMORY | SEC_LINKER_CREATED);
60   note_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd, ".note", flags);
61   if (! note_sec)
62     {
63       einfo (_("%F%P: failed to create .note section\n"));
64       return NULL;
65     }
67   size = offsetof (Elf_External_Note, name[sizeof "QNX"]);
68   size = (size + 3) & -(bfd_size_type) 4;
69   size += sizeof (struct nto_stack_note);
70   note_sec->size = size;
72   elf_section_type (note_sec) = SHT_NOTE;
73   note_sec->contents = xmalloc (note_sec->size);
74   e_note = (Elf_External_Note *) note_sec->contents;
75   bfd_h_put_32 (stub_file->the_bfd, sizeof "QNX", &e_note->namesz);
76   bfd_h_put_32 (stub_file->the_bfd, sizeof (struct nto_stack_note), &e_note->descsz);
77   bfd_h_put_32 (stub_file->the_bfd, type, &e_note->type);
78   memcpy (e_note->name, "QNX", sizeof "QNX");
80   return note_sec;
83 /* Lookup for a section holding a QNX note or create a new section.  */
84 static asection*
85 nto_lookup_QNX_note_section(int type)
87   asection *stack_note_sec = NULL;
88   bfd *abfd;
89   bool duplicated_notes_detected = false;
90   for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
91     {
92       Elf_External_Note *e_note;
93       asection *sec;
95       /* QNX notes are held under a note section simply named ".note".  */
96       sec = bfd_get_section_by_name (abfd, ".note");
97       if (!sec)
98         continue;
100       /* Verify that this is a QNX note of the expected type.  */
101       sec->contents = xmalloc(sec->size);
102       if (!bfd_get_section_contents (sec->owner, sec, sec->contents, (file_ptr) 0,
103                                      sec->size))
104         einfo (_("%F%P: %pB: can't read contents of section .note: %E\n"),
105                sec->owner);
107       e_note = (Elf_External_Note *) sec->contents;
108       if (! strcmp("QNX", e_note->name) && *e_note->type == type)
109         {
110           if (stack_note_sec)
111             {
112               if (!duplicated_notes_detected)
113                 {
114                   einfo (_("%P: %pB: warning: duplicated QNX stack .note detected\n"),
115                          stack_note_sec->owner);
116                   duplicated_notes_detected = true;
117                 }
118               einfo (_("%P: %pB: warning: duplicated QNX stack .note detected\n"),
119                      sec->owner);
120             }
121           else
122             {
123               stack_note_sec = sec;
124               /* Allow modification of this .note content.  */
125               stack_note_sec->flags |= SEC_IN_MEMORY;
126             }
127         }
128     }
130   if (stack_note_sec)
131     return stack_note_sec;
132   else
133     return nto_create_QNX_note_section(type);
137 /* Generate the QNX stack .note section.  */
138 static void
139 nto_add_note_section (void) {
140   asection *note_sec;
141   struct nto_stack_note *n_note;
142   bfd_size_type h_size;
143   bool is_update = false;
145   if (nto_lazy_stack && !link_info.stacksize)
146     {
147       einfo (_("%F%P: error: --lazy-stack must follow -zstack-size=<size>\n"));
148       return;
149     }
151   /* Don't create a note if none of the stack parameter have to be modified.  */
152   if (link_info.stacksize <= 0 && (link_info.execstack == link_info.noexecstack))
153     return;
155   note_sec = nto_lookup_QNX_note_section(QNT_STACK);
156   if (! note_sec)
157     return;
159   /* Update QNX stack note content.  */
160   h_size = note_sec->size - sizeof(struct nto_stack_note);
161   n_note = (struct nto_stack_note *) (note_sec->contents + h_size);
162   is_update = note_sec->owner != stub_file->the_bfd;
164   if (link_info.stacksize > 0)
165     bfd_h_put_32 (note_sec->owner, link_info.stacksize, &n_note->stacksize);
166   else if (!is_update)
167     bfd_h_put_32 (note_sec->owner, 0, &n_note->stacksize);
169   if (nto_lazy_stack || (!is_update && link_info.stacksize <= 0))
170     bfd_h_put_32 (note_sec->owner, 4096, &n_note->stackalloc);
171   else if (link_info.stacksize > 0)
172     bfd_h_put_32 (note_sec->owner, link_info.stacksize, &n_note->stackalloc);
174   if (link_info.execstack)
175     bfd_h_put_32 (note_sec->owner, 0, &n_note->execstack);
176   else if (!is_update || link_info.noexecstack)
177     bfd_h_put_32 (note_sec->owner, 1, &n_note->execstack);
180 static void
181 nto_after_open (void)
183   nto_add_note_section();
184   gld${EMULATION_NAME}_after_open ();
189 # Define some shell vars to insert bits of code into the standard elf
190 # parse_args and list_options functions.
193 PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
194   { "stack", required_argument, NULL, OPTION_STACK },
195   { "lazy-stack", no_argument, NULL, OPTION_LAZY_STACK },
198 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
199   fprintf (file, _("\
200   --stack <size>              Set size of the initial stack\n\
201   --lazy-stack                Set lazy allocation of stack\n\
202 "));
205 PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
206     case OPTION_STACK:
207       {
208         char *end;
209         link_info.stacksize = strtoul (optarg, &end, 0);
210         if (*end || link_info.stacksize < 0)
211           einfo (_("%F%P: invalid stack size `%s'\''\n"), optarg + 11);
212         if (!link_info.stacksize)
213           /* Use -1 for explicit no-stack, because zero means
214              'default'.   */
215           link_info.stacksize = -1;
216         break;
217       }
218     case OPTION_LAZY_STACK:
219       nto_lazy_stack = true;
220       break;
223 # Put these extra Neutrino routines in ld_${EMULATION_NAME}_emulation
226 LDEMUL_AFTER_OPEN=nto_after_open