OSDN Git Service

Add -Wshadow to the gcc command line options used when compiling the binutils.
[pf3gnuchains/pf3gnuchains4x.git] / bfd / nlm32-sparc.c
1 /* Support for 32-bit SPARC NLM (NetWare Loadable Module)
2    Copyright 1993, 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3    2007, 2009 Free Software Foundation, Inc.
4
5    This file is part of BFD, the Binary File Descriptor library.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "libbfd.h"
25
26 #define ARCH_SIZE 32
27
28 #include "nlm/sparc32-ext.h"
29 #define Nlm_External_Fixed_Header       Nlm32_sparc_External_Fixed_Header
30
31 #include "libnlm.h"
32
33 enum reloc_type
34 {
35   R_SPARC_NONE = 0,
36   R_SPARC_8,            R_SPARC_16,             R_SPARC_32,
37   R_SPARC_DISP8,        R_SPARC_DISP16,         R_SPARC_DISP32,
38   R_SPARC_WDISP30,      R_SPARC_WDISP22,
39   R_SPARC_HI22,         R_SPARC_22,
40   R_SPARC_13,           R_SPARC_LO10,
41   R_SPARC_GOT10,        R_SPARC_GOT13,          R_SPARC_GOT22,
42   R_SPARC_PC10,         R_SPARC_PC22,
43   R_SPARC_WPLT30,
44   R_SPARC_COPY,
45   R_SPARC_GLOB_DAT,     R_SPARC_JMP_SLOT,
46   R_SPARC_RELATIVE,
47   R_SPARC_UA32,
48   R_SPARC_max
49 };
50
51 static reloc_howto_type nlm32_sparc_howto_table[] =
52 {
53   HOWTO (R_SPARC_NONE,    0,0, 0,FALSE,0,complain_overflow_dont,    0,"R_SPARC_NONE",    FALSE,0,0x00000000,TRUE),
54   HOWTO (R_SPARC_8,       0,0, 8,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_8",       FALSE,0,0x000000ff,TRUE),
55   HOWTO (R_SPARC_16,      0,1,16,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_16",      FALSE,0,0x0000ffff,TRUE),
56   HOWTO (R_SPARC_32,      0,2,32,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_32",      FALSE,0,0xffffffff,TRUE),
57   HOWTO (R_SPARC_DISP8,   0,0, 8,TRUE, 0,complain_overflow_signed,  0,"R_SPARC_DISP8",   FALSE,0,0x000000ff,TRUE),
58   HOWTO (R_SPARC_DISP16,  0,1,16,TRUE, 0,complain_overflow_signed,  0,"R_SPARC_DISP16",  FALSE,0,0x0000ffff,TRUE),
59   HOWTO (R_SPARC_DISP32,  0,2,32,TRUE, 0,complain_overflow_signed,  0,"R_SPARC_DISP32",  FALSE,0,0x00ffffff,TRUE),
60   HOWTO (R_SPARC_WDISP30, 2,2,30,TRUE, 0,complain_overflow_signed,  0,"R_SPARC_WDISP30", FALSE,0,0x3fffffff,TRUE),
61   HOWTO (R_SPARC_WDISP22, 2,2,22,TRUE, 0,complain_overflow_signed,  0,"R_SPARC_WDISP22", FALSE,0,0x003fffff,TRUE),
62   HOWTO (R_SPARC_HI22,   10,2,22,FALSE,0,complain_overflow_dont,    0,"R_SPARC_HI22",    FALSE,0,0x003fffff,TRUE),
63   HOWTO (R_SPARC_22,      0,2,22,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_22",      FALSE,0,0x003fffff,TRUE),
64   HOWTO (R_SPARC_13,      0,2,13,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_13",      FALSE,0,0x00001fff,TRUE),
65   HOWTO (R_SPARC_LO10,    0,2,10,FALSE,0,complain_overflow_dont,    0,"R_SPARC_LO10",    FALSE,0,0x000003ff,TRUE),
66   HOWTO (R_SPARC_GOT10,   0,2,10,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_GOT10",   FALSE,0,0x000003ff,TRUE),
67   HOWTO (R_SPARC_GOT13,   0,2,13,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_GOT13",   FALSE,0,0x00001fff,TRUE),
68   HOWTO (R_SPARC_GOT22,  10,2,22,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_GOT22",   FALSE,0,0x003fffff,TRUE),
69   HOWTO (R_SPARC_PC10,    0,2,10,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_PC10",    FALSE,0,0x000003ff,TRUE),
70   HOWTO (R_SPARC_PC22,    0,2,22,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_PC22",    FALSE,0,0x003fffff,TRUE),
71   HOWTO (R_SPARC_WPLT30,  0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_WPLT30",  FALSE,0,0x00000000,TRUE),
72   HOWTO (R_SPARC_COPY,    0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_COPY",    FALSE,0,0x00000000,TRUE),
73   HOWTO (R_SPARC_GLOB_DAT,0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_GLOB_DAT",FALSE,0,0x00000000,TRUE),
74   HOWTO (R_SPARC_JMP_SLOT,0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_JMP_SLOT",FALSE,0,0x00000000,TRUE),
75   HOWTO (R_SPARC_RELATIVE,0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_RELATIVE",FALSE,0,0x00000000,TRUE),
76   HOWTO (R_SPARC_UA32,    0,0,00,FALSE,0,complain_overflow_dont,    0,"R_SPARC_UA32",    FALSE,0,0x00000000,TRUE),
77 };
78
79 /* Read a NetWare sparc reloc.  */
80
81 struct nlm32_sparc_reloc_ext
82 {
83   unsigned char offset[4];
84   unsigned char addend[4];
85   unsigned char type[1];
86   unsigned char pad1[3];
87 };
88
89 static bfd_boolean
90 nlm_sparc_read_reloc (bfd *abfd,
91                       nlmNAME (symbol_type) *sym ATTRIBUTE_UNUSED,
92                       asection **secp,
93                       arelent *rel)
94 {
95   bfd_vma val, addend;
96   unsigned int howto_index;
97   unsigned int type;
98   struct nlm32_sparc_reloc_ext tmp_reloc;
99   asection *code_sec, *data_sec;
100
101   if (bfd_bread (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
102     return FALSE;
103
104   code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
105   data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
106
107   *secp = code_sec;
108
109   val = bfd_get_32 (abfd, tmp_reloc.offset);
110   addend = bfd_get_32 (abfd, tmp_reloc.addend);
111   type = bfd_get_8 (abfd, tmp_reloc.type);
112
113   rel->address = val;
114   rel->addend = addend;
115   rel->howto = NULL;
116
117   for (howto_index = 0;
118        howto_index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
119        howto_index++)
120     if (nlm32_sparc_howto_table[howto_index].type == type)
121       {
122         rel->howto = &nlm32_sparc_howto_table[howto_index];
123         break;
124       }
125
126 #ifdef DEBUG
127   fprintf (stderr, "%s:  address = %08lx, addend = %08lx, type = %u, howto = %p\n",
128            __FUNCTION__, (unsigned long) rel->address,
129            (unsigned long) rel->addend, type, rel->howto);
130 #endif
131   return TRUE;
132
133 }
134
135 /* Write a NetWare sparc reloc.  */
136
137 static bfd_boolean
138 nlm_sparc_write_reloc (bfd * abfd, asection * sec, arelent * rel)
139 {
140   bfd_vma val;
141   struct nlm32_sparc_reloc_ext tmp_reloc;
142   unsigned int howto_index;
143   int type = -1;
144   reloc_howto_type *tmp;
145
146   for (howto_index = 0;
147        howto_index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
148        howto_index++)
149     {
150       tmp = &nlm32_sparc_howto_table[howto_index];
151
152       if (tmp->rightshift == rel->howto->rightshift
153           && tmp->size == rel->howto->size
154           && tmp->bitsize == rel->howto->bitsize
155           && tmp->pc_relative == rel->howto->pc_relative
156           && tmp->bitpos == rel->howto->bitpos
157           && tmp->src_mask == rel->howto->src_mask
158           && tmp->dst_mask == rel->howto->dst_mask)
159         {
160           type = tmp->type;
161           break;
162         }
163     }
164   if (type == -1)
165     abort ();
166
167   /* Netware wants a list of relocs for each address.
168      Format is:
169         long    offset
170         long    addend
171         char    type
172      That should be it.  */
173
174   /* The value we write out is the offset into the appropriate
175      segment.  This offset is the section vma, adjusted by the vma of
176      the lowest section in that segment, plus the address of the
177      relocation.  */
178   val = bfd_get_section_vma (abfd, sec) + rel->address;
179
180 #ifdef DEBUG
181   fprintf (stderr, "%s:  val = %08lx, addend = %08lx, type = %u\n",
182            __FUNCTION__, (unsigned long) val, (unsigned long) rel->addend,
183            rel->howto->type);
184 #endif
185   bfd_put_32 (abfd, val, tmp_reloc.offset);
186   bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
187   bfd_put_8 (abfd, (short) (rel->howto->type), tmp_reloc.type);
188
189   if (bfd_bwrite (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
190     return FALSE;
191
192   return TRUE;
193 }
194
195 /* Mangle relocs for SPARC NetWare.  We can just use the standard
196    SPARC relocs.  */
197
198 static bfd_boolean
199 nlm_sparc_mangle_relocs (bfd *abfd ATTRIBUTE_UNUSED,
200                          asection *sec ATTRIBUTE_UNUSED,
201                          const void * data ATTRIBUTE_UNUSED,
202                          bfd_vma offset ATTRIBUTE_UNUSED,
203                          bfd_size_type count ATTRIBUTE_UNUSED)
204 {
205   return TRUE;
206 }
207
208 /* Read a NetWare sparc import record.  */
209
210 static bfd_boolean
211 nlm_sparc_read_import (bfd *abfd, nlmNAME (symbol_type) *sym)
212 {
213   struct nlm_relent *nlm_relocs;        /* Relocation records for symbol.  */
214   bfd_size_type rcount;                 /* Number of relocs.  */
215   bfd_byte temp[NLM_TARGET_LONG_SIZE];  /* Temporary 32-bit value.  */
216   unsigned char symlength;              /* Length of symbol name.  */
217   char *name;
218
219   /* First, read in the number of relocation
220      entries for this symbol.  */
221   if (bfd_bread (temp, (bfd_size_type) 4, abfd) != 4)
222     return FALSE;
223
224   rcount = bfd_get_32 (abfd, temp);
225
226   /* Next, read in the length of the symbol.  */
227   if (bfd_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
228       != sizeof (symlength))
229     return FALSE;
230   sym -> symbol.the_bfd = abfd;
231   name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
232   if (name == NULL)
233     return FALSE;
234
235   /* Then read in the symbol.  */
236   if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
237     return FALSE;
238   name[symlength] = '\0';
239   sym -> symbol.name = name;
240   sym -> symbol.flags = 0;
241   sym -> symbol.value = 0;
242   sym -> symbol.section = bfd_und_section_ptr;
243
244   /* Next, start reading in the relocs.  */
245   nlm_relocs = bfd_alloc (abfd, rcount * sizeof (struct nlm_relent));
246   if (!nlm_relocs)
247     return FALSE;
248   sym -> relocs = nlm_relocs;
249   sym -> rcnt = 0;
250   while (sym -> rcnt < rcount)
251     {
252       asection *section;
253
254       if (! nlm_sparc_read_reloc (abfd, sym, &section, &nlm_relocs -> reloc))
255         return FALSE;
256       nlm_relocs -> section = section;
257       nlm_relocs++;
258       sym -> rcnt++;
259     }
260
261   return TRUE;
262 }
263
264 static bfd_boolean
265 nlm_sparc_write_import (bfd * abfd, asection * sec, arelent * rel)
266 {
267   char temp[4];
268   asection *code, *data, *bss, *symsec;
269   bfd_vma base;
270
271   code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
272   data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
273   bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
274   symsec = (*rel->sym_ptr_ptr)->section;
275
276   if (symsec == code)
277     base = 0;
278   else if (symsec == data)
279     base = code->size;
280   else if (symsec == bss)
281     base = code->size + data->size;
282   else
283     base = 0;
284
285 #ifdef DEBUG
286   fprintf (stderr, "%s:  <%lx, 1>\n\t",
287            __FUNCTION__, (unsigned long) (base + (*rel->sym_ptr_ptr)->value));
288 #endif
289   bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
290   if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4)
291     return FALSE;
292   bfd_put_32 (abfd, (bfd_vma) 1, temp);
293   if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4)
294     return FALSE;
295   if (! nlm_sparc_write_reloc (abfd, sec, rel))
296     return FALSE;
297   return TRUE;
298 }
299
300 /* Write out an external reference.  */
301
302 static bfd_boolean
303 nlm_sparc_write_external (bfd *abfd,
304                           bfd_size_type count,
305                           asymbol *sym,
306                           struct reloc_and_sec *relocs)
307 {
308   unsigned int i;
309   bfd_byte len;
310   unsigned char temp[NLM_TARGET_LONG_SIZE];
311
312   bfd_put_32 (abfd, count, temp);
313   if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
314     return FALSE;
315
316   len = strlen (sym->name);
317   if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
318        != sizeof (bfd_byte))
319       || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
320     return FALSE;
321
322   for (i = 0; i < count; i++)
323     if (! nlm_sparc_write_reloc (abfd, relocs[i].sec, relocs[i].rel))
324       return FALSE;
325
326   return TRUE;
327 }
328
329 static bfd_boolean
330 nlm_sparc_write_export (bfd * abfd, asymbol * sym, bfd_vma value)
331 {
332   bfd_byte len;
333   bfd_byte temp[4];
334
335 #ifdef DEBUG
336   fprintf (stderr, "%s: <%lx, %u, %s>\n",
337            __FUNCTION__, (unsigned long) value, strlen (sym->name), sym->name);
338 #endif
339   bfd_put_32 (abfd, value, temp);
340   len = strlen (sym->name);
341
342   if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4
343       || bfd_bwrite (&len, (bfd_size_type) 1, abfd) != 1
344       || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
345     return FALSE;
346
347   return TRUE;
348 }
349
350 #undef nlm_swap_fixed_header_in
351 #undef nlm_swap_fixed_header_out
352
353 #include "nlmswap.h"
354
355 static const struct nlm_backend_data nlm32_sparc_backend =
356 {
357   "NetWare SPARC Module   \032",
358   sizeof (Nlm32_sparc_External_Fixed_Header),
359   0,    /* Optional_prefix_size.  */
360   bfd_arch_sparc,
361   0,
362   FALSE,
363   0,    /* Backend_object_p.  */
364   0,    /* Write_prefix_func.  */
365   nlm_sparc_read_reloc,
366   nlm_sparc_mangle_relocs,
367   nlm_sparc_read_import,
368   nlm_sparc_write_import,
369   0,    /* Set_public_section.  */
370   0,    /* Get_public_offset.  */
371   nlm_swap_fixed_header_in,
372   nlm_swap_fixed_header_out,
373   nlm_sparc_write_external,
374   nlm_sparc_write_export
375 };
376
377 #define TARGET_BIG_NAME         "nlm32-sparc"
378 #define TARGET_BIG_SYM          nlmNAME (sparc_vec)
379 #define TARGET_BACKEND_DATA     & nlm32_sparc_backend
380
381 #include "nlm-target.h"