]> Git Repo - binutils.git/blob - bfd/nlm32-sparc.c
* elf32-i386.c (elf_i386_size_dynamic_sections): Add DT_DEBUG to
[binutils.git] / bfd / nlm32-sparc.c
1 /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2    Copyright (C) 1993 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "bfd.h"
21 #include "sysdep.h"
22 #include "libbfd.h"
23
24 #define ARCH_SIZE 32
25
26 #include "nlm/sparc32-ext.h"
27 #define Nlm_External_Fixed_Header       Nlm32_sparc_External_Fixed_Header
28
29 #include "libnlm.h"
30
31 static boolean nlm_sparc_read_reloc
32   PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
33 static boolean nlm_sparc_write_reloc
34   PARAMS ((bfd *, asection *, arelent *));
35 static boolean nlm_sparc_mangle_relocs
36   PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
37 static boolean nlm_sparc_read_import
38   PARAMS ((bfd *, nlmNAME(symbol_type) *));
39 static boolean nlm_sparc_write_import
40   PARAMS ((bfd *, asection *, arelent *));
41 static boolean nlm_sparc_write_external
42   PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
43
44 enum reloc_type
45   {
46     R_SPARC_NONE = 0,
47     R_SPARC_8,          R_SPARC_16,             R_SPARC_32, 
48     R_SPARC_DISP8,      R_SPARC_DISP16,         R_SPARC_DISP32, 
49     R_SPARC_WDISP30,    R_SPARC_WDISP22,
50     R_SPARC_HI22,       R_SPARC_22,
51     R_SPARC_13,         R_SPARC_LO10,
52     R_SPARC_GOT10,      R_SPARC_GOT13,          R_SPARC_GOT22,
53     R_SPARC_PC10,       R_SPARC_PC22,
54     R_SPARC_WPLT30,
55     R_SPARC_COPY,
56     R_SPARC_GLOB_DAT,   R_SPARC_JMP_SLOT,
57     R_SPARC_RELATIVE,
58     R_SPARC_UA32,
59     R_SPARC_max
60   };
61
62 #if 0
63 static CONST char *CONST reloc_type_names[] =
64 {
65   "R_SPARC_NONE",
66   "R_SPARC_8",          "R_SPARC_16",           "R_SPARC_32",
67   "R_SPARC_DISP8",      "R_SPARC_DISP16",       "R_SPARC_DISP32",
68   "R_SPARC_WDISP30",    "R_SPARC_WDISP22",
69   "R_SPARC_HI22",       "R_SPARC_22",
70   "R_SPARC_13",         "R_SPARC_LO10",
71   "R_SPARC_GOT10",      "R_SPARC_GOT13",        "R_SPARC_GOT22",
72   "R_SPARC_PC10",       "R_SPARC_PC22",
73   "R_SPARC_WPLT30",
74   "R_SPARC_COPY",
75   "R_SPARC_GLOB_DAT",   "R_SPARC_JMP_SLOT",
76   "R_SPARC_RELATIVE",
77   "R_SPARC_UA32",
78 };
79 #endif
80
81 static reloc_howto_type nlm32_sparc_howto_table[] = 
82 {
83   HOWTO(R_SPARC_NONE,    0,0, 0,false,0,complain_overflow_dont,    0,"R_SPARC_NONE",    false,0,0x00000000,true),
84   HOWTO(R_SPARC_8,       0,0, 8,false,0,complain_overflow_bitfield,0,"R_SPARC_8",       false,0,0x000000ff,true),
85   HOWTO(R_SPARC_16,      0,1,16,false,0,complain_overflow_bitfield,0,"R_SPARC_16",      false,0,0x0000ffff,true),
86   HOWTO(R_SPARC_32,      0,2,32,false,0,complain_overflow_bitfield,0,"R_SPARC_32",      false,0,0xffffffff,true),
87   HOWTO(R_SPARC_DISP8,   0,0, 8,true, 0,complain_overflow_signed,  0,"R_SPARC_DISP8",   false,0,0x000000ff,true),
88   HOWTO(R_SPARC_DISP16,  0,1,16,true, 0,complain_overflow_signed,  0,"R_SPARC_DISP16",  false,0,0x0000ffff,true),
89   HOWTO(R_SPARC_DISP32,  0,2,32,true, 0,complain_overflow_signed,  0,"R_SPARC_DISP32",  false,0,0x00ffffff,true),
90   HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed,  0,"R_SPARC_WDISP30", false,0,0x3fffffff,true),
91   HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed,  0,"R_SPARC_WDISP22", false,0,0x003fffff,true),
92   HOWTO(R_SPARC_HI22,   10,2,22,false,0,complain_overflow_dont,    0,"R_SPARC_HI22",    false,0,0x003fffff,true),
93   HOWTO(R_SPARC_22,      0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_22",      false,0,0x003fffff,true),
94   HOWTO(R_SPARC_13,      0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_13",      false,0,0x00001fff,true),
95   HOWTO(R_SPARC_LO10,    0,2,10,false,0,complain_overflow_dont,    0,"R_SPARC_LO10",    false,0,0x000003ff,true),
96   HOWTO(R_SPARC_GOT10,   0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT10",   false,0,0x000003ff,true),
97   HOWTO(R_SPARC_GOT13,   0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT13",   false,0,0x00001fff,true),
98   HOWTO(R_SPARC_GOT22,  10,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT22",   false,0,0x003fffff,true),
99   HOWTO(R_SPARC_PC10,    0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_PC10",    false,0,0x000003ff,true),
100   HOWTO(R_SPARC_PC22,    0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_PC22",    false,0,0x003fffff,true),
101   HOWTO(R_SPARC_WPLT30,  0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_WPLT30",  false,0,0x00000000,true),
102   HOWTO(R_SPARC_COPY,    0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_COPY",    false,0,0x00000000,true),
103   HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_GLOB_DAT",false,0,0x00000000,true),
104   HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_JMP_SLOT",false,0,0x00000000,true),
105   HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_RELATIVE",false,0,0x00000000,true),
106   HOWTO(R_SPARC_UA32,    0,0,00,false,0,complain_overflow_dont,    0,"R_SPARC_UA32",    false,0,0x00000000,true),
107 };
108
109 /* Read a NetWare sparc reloc.  */
110
111 struct nlm32_sparc_reloc_ext {
112   unsigned char offset[4];
113   unsigned char addend[4];
114   unsigned char type[1];
115   unsigned char pad1[3];
116 };
117
118 static boolean
119 nlm_sparc_read_reloc (abfd, sym, secp, rel)
120      bfd *abfd;
121      nlmNAME(symbol_type) *sym;
122      asection **secp;
123      arelent *rel;
124 {
125   bfd_vma val, addend;
126   int index;
127   unsigned int type;
128   struct nlm32_sparc_reloc_ext tmp_reloc;
129   asection *code_sec, *data_sec;
130
131   if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12)
132     return false;
133
134   code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
135   data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
136
137   *secp = code_sec;
138
139   val = bfd_get_32 (abfd, tmp_reloc.offset);
140   addend = bfd_get_32 (abfd, tmp_reloc.addend);
141   type = bfd_get_8 (abfd, tmp_reloc.type);
142
143   rel->address = val;
144   rel->addend = addend;
145   rel->howto = NULL;
146
147   for (index = 0;
148        index < sizeof(nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
149        index++)
150     if (nlm32_sparc_howto_table[index].type == type) {
151       rel->howto = &nlm32_sparc_howto_table[index];
152       break;
153     }
154
155 #ifdef DEBUG
156   fprintf (stderr, "%s:  address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
157            __FUNCTION__, rel->address, rel->addend, type, rel->howto);
158 #endif
159   return true;
160
161 }
162
163 /* Write a NetWare sparc reloc.  */
164
165 static boolean
166 nlm_sparc_write_reloc (abfd, sec, rel)
167      bfd *abfd;
168      asection *sec;
169      arelent *rel;
170 {
171   bfd_vma val;
172   struct nlm32_sparc_reloc_ext tmp_reloc;
173   int index;
174   int type = -1;
175   reloc_howto_type *tmp;
176
177   
178   for (index = 0;
179        index < sizeof (nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
180        index++) {
181     tmp = &nlm32_sparc_howto_table[index];
182
183     if (tmp->rightshift == rel->howto->rightshift
184         && tmp->size == rel->howto->size
185         && tmp->bitsize == rel->howto->bitsize
186         && tmp->pc_relative == rel->howto->pc_relative
187         && tmp->bitpos == rel->howto->bitpos
188         && tmp->src_mask == rel->howto->src_mask
189         && tmp->dst_mask == rel->howto->dst_mask) {
190       type = tmp->type;
191       break;
192     }
193   }
194   if (type == -1)
195     abort();
196
197   /*
198    * Netware wants a list of relocs for each address.
199    * Format is:
200    *    long    offset
201    *    long    addend
202    *    char    type
203    * That should be it.
204    */
205
206   /* The value we write out is the offset into the appropriate
207      segment.  This offset is the section vma, adjusted by the vma of
208      the lowest section in that segment, plus the address of the
209      relocation.  */
210 #if 0
211   val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
212 #else
213   val = bfd_get_section_vma (abfd, sec) + rel->address;
214 #endif
215
216 #ifdef DEBUG
217   fprintf (stderr, "%s:  val = %08lx, addend = %08lx, type = %d\n",
218            __FUNCTION__, val, rel->addend, rel->howto->type);
219 #endif
220   bfd_put_32 (abfd, val, tmp_reloc.offset);
221   bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
222   bfd_put_8 (abfd, (short)(rel->howto->type), tmp_reloc.type);
223
224   if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12)
225     {
226       abort();
227     }
228
229   return true;
230 }
231
232 /* Mangle relocs for SPARC NetWare.  We can just use the standard
233    SPARC relocs.  */
234
235 static boolean
236 nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
237      bfd *abfd;
238      asection *sec;
239      PTR data;
240      bfd_vma offset;
241      bfd_size_type count;
242 {
243   return true;
244 }
245
246 /* Read a NetWare sparc import record */
247 static boolean
248 nlm_sparc_read_import (abfd, sym)
249      bfd *abfd;
250      nlmNAME(symbol_type) *sym;
251 {
252   struct nlm_relent *nlm_relocs;        /* relocation records for symbol */
253   bfd_size_type rcount;                 /* number of relocs */
254   bfd_byte temp[NLM_TARGET_LONG_SIZE];  /* temporary 32-bit value */
255   unsigned char symlength;              /* length of symbol name */
256   char *name;
257   
258   /*
259    * First, read in the number of relocation
260    * entries for this symbol
261    */
262   if (bfd_read ((PTR) temp, 4, 1, abfd) != 4)
263     return false;
264   
265   rcount = bfd_get_32 (abfd, temp);
266   
267   /*
268    * Next, read in the length of the symbol
269    */
270   
271   if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
272       != sizeof (symlength))
273     return false;
274   sym -> symbol.the_bfd = abfd;
275   name = bfd_alloc (abfd, symlength + 1);
276   if (name == NULL)
277     {
278       bfd_set_error (bfd_error_no_memory);
279       return false;
280     }
281   
282   /*
283    * Then read in the symbol
284    */
285   
286   if (bfd_read (name, symlength, 1, abfd) != symlength)
287     return false;
288   name[symlength] = '\0';
289   sym -> symbol.name = name;
290   sym -> symbol.flags = 0;
291   sym -> symbol.value = 0;
292   sym -> symbol.section = &bfd_und_section;
293   
294   /*
295    * Next, start reading in the relocs.
296    */
297   
298   nlm_relocs = ((struct nlm_relent *)
299                 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
300   if (!nlm_relocs)
301     {
302       bfd_set_error (bfd_error_no_memory);
303       return false;
304     }
305   sym -> relocs = nlm_relocs;
306   sym -> rcnt = 0;
307   while (sym -> rcnt < rcount)
308     {
309       asection *section;
310       
311       if (nlm_sparc_read_reloc (abfd, sym, &section,
312                               &nlm_relocs -> reloc)
313           == false)
314         return false;
315       nlm_relocs -> section = section;
316       nlm_relocs++;
317       sym -> rcnt++;
318     }
319   return true;
320 }
321
322 static boolean
323 nlm_sparc_write_import (abfd, sec, rel)
324      bfd *abfd;
325      asection *sec;
326      arelent *rel;
327 {
328   char temp[4];
329   asection *code, *data, *bss, *symsec;
330   bfd_vma base;
331
332   code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
333   data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
334   bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
335   symsec = (*rel->sym_ptr_ptr)->section;
336
337   if (symsec == code) {
338     base = 0;
339   } else if (symsec == data) {
340     base = bfd_section_size (abfd, code);
341   } else if (symsec == bss) {
342     base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data);
343   } else
344     base = 0;
345
346 #ifdef DEBUG
347   fprintf (stderr, "%s:  <%x, 1>\n\t",
348            __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
349 #endif
350   bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
351   bfd_write ((PTR)temp, 4, 1, abfd);
352   bfd_put_32 (abfd, 1, temp);
353   bfd_write ((PTR)temp, 4, 1, abfd);
354   if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
355     return false;
356   return true;
357 }
358
359 /* Write out an external reference.  */
360
361 static boolean
362 nlm_sparc_write_external (abfd, count, sym, relocs)
363      bfd *abfd;
364      bfd_size_type count;
365      asymbol *sym;
366      struct reloc_and_sec *relocs;
367 {
368   int i;
369   bfd_byte len;
370   unsigned char temp[NLM_TARGET_LONG_SIZE];
371
372   bfd_put_32 (abfd, count, temp);
373   if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
374     return false;
375
376   len = strlen (sym->name);
377   if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
378       || bfd_write (sym->name, len, 1, abfd) != len)
379     return false;
380
381   for (i = 0; i < count; i++)
382     {
383       if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
384                                  relocs[i].rel) == false)
385         return false;
386     }
387
388   return true;
389 }
390
391 static boolean
392 nlm_sparc_write_export (abfd, sym, value)
393      bfd *abfd;
394      asymbol *sym;
395      bfd_vma value;
396 {
397   bfd_byte len;
398   bfd_byte temp[4];
399
400 #ifdef DEBUG
401   fprintf (stderr, "%s: <%x, %d, %s>\n",
402            __FUNCTION__, value, strlen (sym->name), sym->name);
403 #endif
404   bfd_put_32 (abfd, value, temp);
405   len = strlen (sym->name);
406
407   if (bfd_write (temp, 4, 1, abfd) != 4
408       || bfd_write (&len, 1, 1, abfd) != 1
409       || bfd_write (sym->name, len, 1, abfd) != len)
410     return false;
411
412   return true;
413 }
414
415 #undef nlm_swap_fixed_header_in
416 #undef nlm_swap_fixed_header_out
417
418 #include "nlmswap.h"
419
420 static const struct nlm_backend_data nlm32_sparc_backend =
421 {
422   "NetWare SPARC Module   \032",
423   sizeof (Nlm32_sparc_External_Fixed_Header),
424   0,    /* optional_prefix_size */
425   bfd_arch_sparc,
426   0,
427   false,
428   0,    /* backend_object_p */
429   0,    /* write_prefix_func */
430   nlm_sparc_read_reloc,
431   nlm_sparc_mangle_relocs,
432   nlm_sparc_read_import,
433   nlm_sparc_write_import,
434   0,    /* set_public_section */
435   0,    /* get_public_offset */
436   nlm_swap_fixed_header_in,
437   nlm_swap_fixed_header_out,
438   nlm_sparc_write_external,
439   nlm_sparc_write_export
440 };
441
442 #define TARGET_BIG_NAME         "nlm32-sparc"
443 #define TARGET_BIG_SYM          nlmNAME(sparc_vec)
444 #define TARGET_BACKEND_DATA             &nlm32_sparc_backend
445
446 #include "nlm-target.h"
This page took 0.048983 seconds and 4 git commands to generate.