packaging: Add python3-base dependency
[platform/upstream/gdb.git] / bfd / i386lynx.c
1 /* BFD back-end for i386 a.out binaries under LynxOS.
2    Copyright (C) 1990-2022 Free Software Foundation, Inc.
3
4    This file is part of BFD, the Binary File Descriptor library.
5
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 3 of the License, or
9    (at your option) any later version.
10
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.
15
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,
19    MA 02110-1301, USA.  */
20
21 #define TEXT_START_ADDR 0
22 #define TARGET_PAGE_SIZE 4096
23 #define SEGMENT_SIZE TARGET_PAGE_SIZE
24 #define DEFAULT_ARCH bfd_arch_i386
25
26 /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
27    remove whitespace added here, and thus will fail to concatenate
28    the tokens.  */
29 #define MY(OP) CONCAT2 (i386_aout_lynx_,OP)
30 #define TARGETNAME "a.out-i386-lynx"
31
32 #include "sysdep.h"
33 #include "bfd.h"
34 #include "libbfd.h"
35
36 #ifndef WRITE_HEADERS
37 #define WRITE_HEADERS(abfd, execp)                                            \
38       {                                                                       \
39         if (adata(abfd).magic == undecided_magic)                             \
40           NAME(aout,adjust_sizes_and_vmas) (abfd);                            \
41                                                                               \
42         execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;        \
43         execp->a_entry = bfd_get_start_address (abfd);                        \
44                                                                               \
45         execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *                \
46                            obj_reloc_entry_size (abfd));                      \
47         execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *                \
48                            obj_reloc_entry_size (abfd));                      \
49         NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes);           \
50                                                                               \
51         if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0                      \
52             || bfd_bwrite (&exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \
53                           abfd) != EXEC_BYTES_SIZE)                           \
54           return false;                                                       \
55         /* Now write out reloc info, followed by syms and strings */          \
56                                                                               \
57         if (bfd_get_symcount (abfd) != 0)                                     \
58             {                                                                 \
59               if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (execp)), SEEK_SET)    \
60                   != 0)                                                       \
61                 return false;                                                 \
62                                                                               \
63               if (! NAME(aout,write_syms) (abfd)) return false;               \
64                                                                               \
65               if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (execp)), SEEK_SET)   \
66                   != 0)                                                       \
67                 return false;                                                 \
68                                                                               \
69               if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd)))   \
70                 return false;                                                 \
71               if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (execp)), SEEK_SET)   \
72                   != 0)                                                       \
73                 return 0;                                                     \
74                                                                               \
75               if (!NAME(lynx,squirt_out_relocs) (abfd, obj_datasec (abfd)))   \
76                 return false;                                                 \
77             }                                                                 \
78       }
79 #endif
80
81 #include "libaout.h"
82 #include "aout/aout64.h"
83
84
85 #ifdef LYNX_CORE
86
87 char *lynx_core_file_failing_command ();
88 int lynx_core_file_failing_signal ();
89 bool lynx_core_file_matches_executable_p ();
90 bfd_cleanup lynx_core_file_p ();
91
92 #define MY_core_file_failing_command lynx_core_file_failing_command
93 #define MY_core_file_failing_signal lynx_core_file_failing_signal
94 #define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
95 #define MY_core_file_p lynx_core_file_p
96
97 #endif /* LYNX_CORE */
98 \f
99
100 #define KEEPIT udata.i
101
102 extern reloc_howto_type aout_32_ext_howto_table[];
103 extern reloc_howto_type aout_32_std_howto_table[];
104
105 /* Standard reloc stuff */
106 /* Output standard relocation information to a file in target byte order. */
107
108 static void
109 NAME(lynx,swap_std_reloc_out) (bfd *abfd,
110                                arelent *g,
111                                struct reloc_std_external *natptr)
112 {
113   int r_index;
114   asymbol *sym = *(g->sym_ptr_ptr);
115   int r_extern;
116   unsigned int r_length;
117   int r_pcrel;
118   int r_baserel, r_jmptable, r_relative;
119   asection *output_section = sym->section->output_section;
120
121   PUT_WORD (abfd, g->address, natptr->r_address);
122
123   r_length = bfd_log2 (bfd_get_reloc_size (g->howto));
124   r_pcrel = (int) g->howto->pc_relative;        /* Relative to PC? */
125   /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
126   r_baserel = 0;
127   r_jmptable = 0;
128   r_relative = 0;
129
130   /* name was clobbered by aout_write_syms to be symbol index */
131
132   /* If this relocation is relative to a symbol then set the
133      r_index to the symbols index, and the r_extern bit.
134
135      Absolute symbols can come in in two ways, either as an offset
136      from the abs section, or as a symbol which has an abs value.
137      check for that here
138   */
139
140   if (bfd_is_com_section (output_section)
141       || bfd_is_abs_section (output_section)
142       || bfd_is_und_section (output_section))
143     {
144       if (bfd_abs_section_ptr->symbol == sym)
145         {
146           /* Whoops, looked like an abs symbol, but is really an offset
147              from the abs section */
148           r_index = 0;
149           r_extern = 0;
150         }
151       else
152         {
153           /* Fill in symbol */
154           r_extern = 1;
155           r_index = (*g->sym_ptr_ptr)->KEEPIT;
156         }
157     }
158   else
159     {
160       /* Just an ordinary section */
161       r_extern = 0;
162       r_index = output_section->target_index;
163     }
164
165   /* now the fun stuff */
166   if (bfd_header_big_endian (abfd))
167     {
168       natptr->r_index[0] = r_index >> 16;
169       natptr->r_index[1] = r_index >> 8;
170       natptr->r_index[2] = r_index;
171       natptr->r_type[0] =
172         (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
173         | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
174         | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
175         | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
176         | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
177         | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
178     }
179   else
180     {
181       natptr->r_index[2] = r_index >> 16;
182       natptr->r_index[1] = r_index >> 8;
183       natptr->r_index[0] = r_index;
184       natptr->r_type[0] =
185         (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
186         | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
187         | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
188         | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
189         | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
190         | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
191     }
192 }
193
194
195 /* Extended stuff */
196 /* Output extended relocation information to a file in target byte order. */
197
198 static void
199 NAME(lynx,swap_ext_reloc_out) (bfd *abfd,
200                                arelent *g,
201                                struct reloc_ext_external *natptr)
202 {
203   int r_index;
204   int r_extern;
205   unsigned int r_type;
206   unsigned int r_addend;
207   asymbol *sym = *(g->sym_ptr_ptr);
208   asection *output_section = sym->section->output_section;
209
210   PUT_WORD (abfd, g->address, natptr->r_address);
211
212   r_type = (unsigned int) g->howto->type;
213
214   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
215
216
217   /* If this relocation is relative to a symbol then set the
218      r_index to the symbols index, and the r_extern bit.
219
220      Absolute symbols can come in in two ways, either as an offset
221      from the abs section, or as a symbol which has an abs value.
222      check for that here
223      */
224
225   if (bfd_is_com_section (output_section)
226       || bfd_is_abs_section (output_section)
227       || bfd_is_und_section (output_section))
228     {
229       if (bfd_abs_section_ptr->symbol == sym)
230         {
231           /* Whoops, looked like an abs symbol, but is really an offset
232          from the abs section */
233           r_index = 0;
234           r_extern = 0;
235         }
236       else
237         {
238           r_extern = 1;
239           r_index = (*g->sym_ptr_ptr)->KEEPIT;
240         }
241     }
242   else
243     {
244       /* Just an ordinary section */
245       r_extern = 0;
246       r_index = output_section->target_index;
247     }
248
249
250   /* now the fun stuff */
251   if (bfd_header_big_endian (abfd))
252     {
253       natptr->r_index[0] = r_index >> 16;
254       natptr->r_index[1] = r_index >> 8;
255       natptr->r_index[2] = r_index;
256       natptr->r_type[0] =
257         (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
258         | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
259     }
260   else
261     {
262       natptr->r_index[2] = r_index >> 16;
263       natptr->r_index[1] = r_index >> 8;
264       natptr->r_index[0] = r_index;
265       natptr->r_type[0] =
266         (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
267         | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
268     }
269
270   PUT_WORD (abfd, r_addend, natptr->r_addend);
271 }
272
273 /* BFD deals internally with all things based from the section they're
274    in. so, something in 10 bytes into a text section  with a base of
275    50 would have a symbol (.text+10) and know .text vma was 50.
276
277    Aout keeps all it's symbols based from zero, so the symbol would
278    contain 60. This macro subs the base of each section from the value
279    to give the true offset from the section */
280
281
282 #define MOVE_ADDRESS(ad)                                                \
283   if (r_extern)                                                         \
284     {                                                                   \
285       /* undefined symbol */                                            \
286       if (symbols != NULL && r_index < bfd_get_symcount (abfd))         \
287         cache_ptr->sym_ptr_ptr = symbols + r_index;                     \
288       else                                                              \
289         cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;   \
290       cache_ptr->addend = ad;                                           \
291     }                                                                   \
292   else                                                                  \
293     {                                                                   \
294       /* defined, section relative. replace symbol with pointer to      \
295          symbol which points to section  */                             \
296       switch (r_index)                                                  \
297         {                                                               \
298         case N_TEXT:                                                    \
299         case N_TEXT | N_EXT:                                            \
300           cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;  \
301           cache_ptr->addend = ad  - su->textsec->vma;                   \
302           break;                                                        \
303         case N_DATA:                                                    \
304         case N_DATA | N_EXT:                                            \
305           cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;  \
306           cache_ptr->addend = ad - su->datasec->vma;                    \
307           break;                                                        \
308         case N_BSS:                                                     \
309         case N_BSS | N_EXT:                                             \
310           cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;   \
311           cache_ptr->addend = ad - su->bsssec->vma;                     \
312           break;                                                        \
313         default:                                                        \
314         case N_ABS:                                                     \
315         case N_ABS | N_EXT:                                             \
316           cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
317           cache_ptr->addend = ad;                                       \
318           break;                                                        \
319         }                                                               \
320     }                                                                   \
321
322 static void
323 NAME(lynx,swap_ext_reloc_in) (bfd *abfd,
324                               struct reloc_ext_external *bytes,
325                               arelent *cache_ptr,
326                               asymbol **symbols,
327                               bfd_size_type symcount ATTRIBUTE_UNUSED)
328 {
329   unsigned int r_index;
330   int r_extern;
331   unsigned int r_type;
332   struct aoutdata *su = &(abfd->tdata.aout_data->a);
333
334   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
335
336   r_index = bytes->r_index[1];
337   r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG));
338   r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG)
339     >> RELOC_EXT_BITS_TYPE_SH_BIG;
340
341   cache_ptr->howto = aout_32_ext_howto_table + r_type;
342   MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
343 }
344
345 static void
346 NAME(lynx,swap_std_reloc_in) (bfd *abfd,
347                               struct reloc_std_external *bytes,
348                               arelent *cache_ptr,
349                               asymbol **symbols,
350                               bfd_size_type symcount ATTRIBUTE_UNUSED)
351 {
352   unsigned int r_index;
353   int r_extern;
354   unsigned int r_length;
355   int r_pcrel;
356   struct aoutdata *su = &(abfd->tdata.aout_data->a);
357
358   cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
359
360   r_index = bytes->r_index[1];
361   r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
362   r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
363   r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
364     >> RELOC_STD_BITS_LENGTH_SH_BIG;
365
366   cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
367   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
368
369   MOVE_ADDRESS (0);
370 }
371
372 /* Reloc hackery */
373
374 static bool
375 NAME(lynx,slurp_reloc_table) (bfd *abfd,
376                               sec_ptr asect,
377                               asymbol **symbols)
378 {
379   bfd_size_type count;
380   bfd_size_type reloc_size;
381   void * relocs;
382   arelent *reloc_cache;
383   size_t each_size;
384
385   if (asect->relocation)
386     return true;
387
388   if (asect->flags & SEC_CONSTRUCTOR)
389     return true;
390
391   if (asect == obj_datasec (abfd))
392     {
393       reloc_size = exec_hdr (abfd)->a_drsize;
394       goto doit;
395     }
396
397   if (asect == obj_textsec (abfd))
398     {
399       reloc_size = exec_hdr (abfd)->a_trsize;
400       goto doit;
401     }
402
403   bfd_set_error (bfd_error_invalid_operation);
404   return false;
405
406  doit:
407   if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
408     return false;
409   each_size = obj_reloc_entry_size (abfd);
410
411   count = reloc_size / each_size;
412
413
414   reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent));
415   if (!reloc_cache && count != 0)
416     return false;
417
418   relocs = _bfd_alloc_and_read (abfd, reloc_size, reloc_size);
419   if (!relocs && reloc_size != 0)
420     {
421       free (reloc_cache);
422       return false;
423     }
424
425   if (each_size == RELOC_EXT_SIZE)
426     {
427       struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
428       unsigned int counter = 0;
429       arelent *cache_ptr = reloc_cache;
430
431       for (; counter < count; counter++, rptr++, cache_ptr++)
432         {
433           NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
434                                         (bfd_size_type) bfd_get_symcount (abfd));
435         }
436     }
437   else
438     {
439       struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
440       unsigned int counter = 0;
441       arelent *cache_ptr = reloc_cache;
442
443       for (; counter < count; counter++, rptr++, cache_ptr++)
444         {
445           NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
446                                         (bfd_size_type) bfd_get_symcount (abfd));
447         }
448
449     }
450
451   bfd_release (abfd, relocs);
452   asect->relocation = reloc_cache;
453   asect->reloc_count = count;
454   return true;
455 }
456
457
458
459 /* Write out a relocation section into an object file.  */
460
461 static bool
462 NAME(lynx,squirt_out_relocs) (bfd *abfd, asection *section)
463 {
464   arelent **generic;
465   unsigned char *native, *natptr;
466   size_t each_size;
467   unsigned int count = section->reloc_count;
468   bfd_size_type natsize;
469
470   if (count == 0)
471     return true;
472
473   each_size = obj_reloc_entry_size (abfd);
474   natsize = count;
475   natsize *= each_size;
476   native = (unsigned char *) bfd_zalloc (abfd, natsize);
477   if (!native)
478     return false;
479
480   generic = section->orelocation;
481
482   if (each_size == RELOC_EXT_SIZE)
483     {
484       for (natptr = native;
485            count != 0;
486            --count, natptr += each_size, ++generic)
487         NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
488     }
489   else
490     {
491       for (natptr = native;
492            count != 0;
493            --count, natptr += each_size, ++generic)
494         NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
495     }
496
497   if (bfd_bwrite (native, natsize, abfd) != natsize)
498     {
499       bfd_release (abfd, native);
500       return false;
501     }
502   bfd_release (abfd, native);
503
504   return true;
505 }
506
507 /* This is stupid.  This function should be a boolean predicate */
508 static long
509 NAME(lynx,canonicalize_reloc) (bfd *abfd,
510                                sec_ptr section,
511                                arelent **relptr,
512                                asymbol **symbols)
513 {
514   arelent *tblptr = section->relocation;
515   unsigned int count;
516
517   if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
518     return -1;
519
520   if (section->flags & SEC_CONSTRUCTOR)
521     {
522       arelent_chain *chain = section->constructor_chain;
523       for (count = 0; count < section->reloc_count; count++)
524         {
525           *relptr++ = &chain->relent;
526           chain = chain->next;
527         }
528     }
529   else
530     {
531       tblptr = section->relocation;
532
533       for (count = 0; count++ < section->reloc_count;)
534         {
535           *relptr++ = tblptr++;
536         }
537     }
538   *relptr = 0;
539
540   return section->reloc_count;
541 }
542
543 #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
544
545 #include "aout-target.h"