New "find" command.
[deliverable/binutils-gdb.git] / bfd / nlm32-sparc.c
CommitLineData
252b5132 1/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
3db64b00
AM
2 Copyright 1993, 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 2007 Free Software Foundation, Inc.
252b5132 4
42ef282f 5 This file is part of BFD, the Binary File Descriptor library.
252b5132 6
42ef282f
NC
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
cd123cb7 9 the Free Software Foundation; either version 3 of the License, or
42ef282f 10 (at your option) any later version.
252b5132 11
42ef282f
NC
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.
252b5132 16
42ef282f
NC
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
cd123cb7
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
252b5132 21
252b5132 22#include "sysdep.h"
3db64b00 23#include "bfd.h"
252b5132
RH
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
252b5132 33enum reloc_type
7920ce38
NC
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};
252b5132 50
1518639e 51static reloc_howto_type nlm32_sparc_howto_table[] =
7920ce38
NC
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),
252b5132
RH
77};
78
79/* Read a NetWare sparc reloc. */
80
42ef282f 81struct nlm32_sparc_reloc_ext
7920ce38
NC
82{
83 unsigned char offset[4];
84 unsigned char addend[4];
85 unsigned char type[1];
86 unsigned char pad1[3];
87};
252b5132 88
b34976b6 89static bfd_boolean
7920ce38
NC
90nlm_sparc_read_reloc (bfd *abfd,
91 nlmNAME (symbol_type) *sym ATTRIBUTE_UNUSED,
92 asection **secp,
93 arelent *rel)
252b5132
RH
94{
95 bfd_vma val, addend;
96 unsigned int index;
97 unsigned int type;
98 struct nlm32_sparc_reloc_ext tmp_reloc;
99 asection *code_sec, *data_sec;
100
dc810e39 101 if (bfd_bread (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
b34976b6 102 return FALSE;
252b5132
RH
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 (index = 0;
1518639e 118 index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
252b5132 119 index++)
42ef282f
NC
120 if (nlm32_sparc_howto_table[index].type == type)
121 {
122 rel->howto = &nlm32_sparc_howto_table[index];
123 break;
124 }
252b5132
RH
125
126#ifdef DEBUG
e460dd0d
AM
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);
252b5132 130#endif
b34976b6 131 return TRUE;
252b5132
RH
132
133}
134
135/* Write a NetWare sparc reloc. */
136
b34976b6 137static bfd_boolean
7920ce38 138nlm_sparc_write_reloc (bfd * abfd, asection * sec, arelent * rel)
252b5132
RH
139{
140 bfd_vma val;
141 struct nlm32_sparc_reloc_ext tmp_reloc;
142 unsigned int index;
143 int type = -1;
144 reloc_howto_type *tmp;
145
252b5132 146 for (index = 0;
1518639e 147 index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
42ef282f
NC
148 index++)
149 {
150 tmp = &nlm32_sparc_howto_table[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 }
252b5132 163 }
252b5132 164 if (type == -1)
1518639e 165 abort ();
252b5132 166
42ef282f
NC
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. */
252b5132
RH
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. */
252b5132 178 val = bfd_get_section_vma (abfd, sec) + rel->address;
252b5132
RH
179
180#ifdef DEBUG
e460dd0d
AM
181 fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %u\n",
182 __FUNCTION__, (unsigned long) val, (unsigned long) rel->addend,
183 rel->howto->type);
252b5132
RH
184#endif
185 bfd_put_32 (abfd, val, tmp_reloc.offset);
186 bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
1518639e 187 bfd_put_8 (abfd, (short) (rel->howto->type), tmp_reloc.type);
252b5132 188
dc810e39 189 if (bfd_bwrite (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
b34976b6 190 return FALSE;
252b5132 191
b34976b6 192 return TRUE;
252b5132
RH
193}
194
195/* Mangle relocs for SPARC NetWare. We can just use the standard
196 SPARC relocs. */
197
b34976b6 198static bfd_boolean
7920ce38
NC
199nlm_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)
252b5132 204{
b34976b6 205 return TRUE;
252b5132
RH
206}
207
42ef282f
NC
208/* Read a NetWare sparc import record. */
209
b34976b6 210static bfd_boolean
7920ce38 211nlm_sparc_read_import (bfd *abfd, nlmNAME (symbol_type) *sym)
252b5132 212{
42ef282f
NC
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. */
252b5132 217 char *name;
1518639e 218
42ef282f
NC
219 /* First, read in the number of relocation
220 entries for this symbol. */
7920ce38 221 if (bfd_bread (temp, (bfd_size_type) 4, abfd) != 4)
b34976b6 222 return FALSE;
1518639e 223
252b5132 224 rcount = bfd_get_32 (abfd, temp);
1518639e 225
42ef282f 226 /* Next, read in the length of the symbol. */
7920ce38 227 if (bfd_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
252b5132 228 != sizeof (symlength))
b34976b6 229 return FALSE;
252b5132 230 sym -> symbol.the_bfd = abfd;
dc810e39 231 name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
252b5132 232 if (name == NULL)
b34976b6 233 return FALSE;
1518639e 234
42ef282f 235 /* Then read in the symbol. */
dc810e39 236 if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
b34976b6 237 return FALSE;
252b5132
RH
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;
1518639e 243
42ef282f 244 /* Next, start reading in the relocs. */
7920ce38 245 nlm_relocs = bfd_alloc (abfd, rcount * sizeof (struct nlm_relent));
252b5132 246 if (!nlm_relocs)
b34976b6 247 return FALSE;
252b5132
RH
248 sym -> relocs = nlm_relocs;
249 sym -> rcnt = 0;
250 while (sym -> rcnt < rcount)
251 {
252 asection *section;
1518639e 253
82e51918 254 if (! nlm_sparc_read_reloc (abfd, sym, &section, &nlm_relocs -> reloc))
b34976b6 255 return FALSE;
252b5132
RH
256 nlm_relocs -> section = section;
257 nlm_relocs++;
258 sym -> rcnt++;
259 }
42ef282f 260
b34976b6 261 return TRUE;
252b5132
RH
262}
263
b34976b6 264static bfd_boolean
7920ce38 265nlm_sparc_write_import (bfd * abfd, asection * sec, arelent * rel)
252b5132
RH
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
42ef282f 276 if (symsec == code)
252b5132 277 base = 0;
42ef282f 278 else if (symsec == data)
eea6121a 279 base = code->size;
42ef282f 280 else if (symsec == bss)
eea6121a 281 base = code->size + data->size;
42ef282f 282 else
252b5132
RH
283 base = 0;
284
285#ifdef DEBUG
e460dd0d
AM
286 fprintf (stderr, "%s: <%lx, 1>\n\t",
287 __FUNCTION__, (unsigned long) (base + (*rel->sym_ptr_ptr)->value));
252b5132
RH
288#endif
289 bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
7920ce38 290 if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4)
b34976b6 291 return FALSE;
dc810e39 292 bfd_put_32 (abfd, (bfd_vma) 1, temp);
7920ce38 293 if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4)
b34976b6 294 return FALSE;
82e51918 295 if (! nlm_sparc_write_reloc (abfd, sec, rel))
b34976b6
AM
296 return FALSE;
297 return TRUE;
252b5132
RH
298}
299
300/* Write out an external reference. */
301
b34976b6 302static bfd_boolean
7920ce38
NC
303nlm_sparc_write_external (bfd *abfd,
304 bfd_size_type count,
305 asymbol *sym,
306 struct reloc_and_sec *relocs)
252b5132
RH
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);
dc810e39 313 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
b34976b6 314 return FALSE;
252b5132
RH
315
316 len = strlen (sym->name);
dc810e39
AM
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)
b34976b6 320 return FALSE;
252b5132
RH
321
322 for (i = 0; i < count; i++)
7920ce38
NC
323 if (! nlm_sparc_write_reloc (abfd, relocs[i].sec, relocs[i].rel))
324 return FALSE;
252b5132 325
b34976b6 326 return TRUE;
252b5132
RH
327}
328
b34976b6 329static bfd_boolean
7920ce38 330nlm_sparc_write_export (bfd * abfd, asymbol * sym, bfd_vma value)
252b5132
RH
331{
332 bfd_byte len;
333 bfd_byte temp[4];
334
335#ifdef DEBUG
e460dd0d
AM
336 fprintf (stderr, "%s: <%lx, %u, %s>\n",
337 __FUNCTION__, (unsigned long) value, strlen (sym->name), sym->name);
252b5132
RH
338#endif
339 bfd_put_32 (abfd, value, temp);
340 len = strlen (sym->name);
341
dc810e39
AM
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)
b34976b6 345 return FALSE;
252b5132 346
b34976b6 347 return TRUE;
252b5132
RH
348}
349
350#undef nlm_swap_fixed_header_in
351#undef nlm_swap_fixed_header_out
352
353#include "nlmswap.h"
354
355static const struct nlm_backend_data nlm32_sparc_backend =
7920ce38
NC
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};
252b5132
RH
376
377#define TARGET_BIG_NAME "nlm32-sparc"
7920ce38 378#define TARGET_BIG_SYM nlmNAME (sparc_vec)
42ef282f 379#define TARGET_BACKEND_DATA & nlm32_sparc_backend
252b5132
RH
380
381#include "nlm-target.h"
This page took 0.636324 seconds and 4 git commands to generate.