]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/nlm32-sparc.c
* ld-cris/libdso-13.d: Adjust for --enable-new-dtags now
[thirdparty/binutils-gdb.git] / bfd / nlm32-sparc.c
CommitLineData
252b5132 1/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
3db64b00 2 Copyright 1993, 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
c7e2358a 3 2007, 2009, 2010 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;
91d6fa6a 96 unsigned int howto_index;
252b5132
RH
97 unsigned int type;
98 struct nlm32_sparc_reloc_ext tmp_reloc;
c7e2358a 99 asection *code_sec;
252b5132 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);
252b5132
RH
105 *secp = code_sec;
106
107 val = bfd_get_32 (abfd, tmp_reloc.offset);
108 addend = bfd_get_32 (abfd, tmp_reloc.addend);
109 type = bfd_get_8 (abfd, tmp_reloc.type);
110
111 rel->address = val;
112 rel->addend = addend;
113 rel->howto = NULL;
114
91d6fa6a
NC
115 for (howto_index = 0;
116 howto_index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
117 howto_index++)
118 if (nlm32_sparc_howto_table[howto_index].type == type)
42ef282f 119 {
91d6fa6a 120 rel->howto = &nlm32_sparc_howto_table[howto_index];
42ef282f
NC
121 break;
122 }
252b5132
RH
123
124#ifdef DEBUG
e460dd0d
AM
125 fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %u, howto = %p\n",
126 __FUNCTION__, (unsigned long) rel->address,
127 (unsigned long) rel->addend, type, rel->howto);
252b5132 128#endif
b34976b6 129 return TRUE;
252b5132
RH
130
131}
132
133/* Write a NetWare sparc reloc. */
134
b34976b6 135static bfd_boolean
7920ce38 136nlm_sparc_write_reloc (bfd * abfd, asection * sec, arelent * rel)
252b5132
RH
137{
138 bfd_vma val;
139 struct nlm32_sparc_reloc_ext tmp_reloc;
91d6fa6a 140 unsigned int howto_index;
252b5132
RH
141 int type = -1;
142 reloc_howto_type *tmp;
143
91d6fa6a
NC
144 for (howto_index = 0;
145 howto_index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
146 howto_index++)
42ef282f 147 {
91d6fa6a 148 tmp = &nlm32_sparc_howto_table[howto_index];
42ef282f
NC
149
150 if (tmp->rightshift == rel->howto->rightshift
151 && tmp->size == rel->howto->size
152 && tmp->bitsize == rel->howto->bitsize
153 && tmp->pc_relative == rel->howto->pc_relative
154 && tmp->bitpos == rel->howto->bitpos
155 && tmp->src_mask == rel->howto->src_mask
156 && tmp->dst_mask == rel->howto->dst_mask)
157 {
158 type = tmp->type;
159 break;
160 }
252b5132 161 }
252b5132 162 if (type == -1)
1518639e 163 abort ();
252b5132 164
42ef282f
NC
165 /* Netware wants a list of relocs for each address.
166 Format is:
167 long offset
168 long addend
169 char type
170 That should be it. */
252b5132
RH
171
172 /* The value we write out is the offset into the appropriate
173 segment. This offset is the section vma, adjusted by the vma of
174 the lowest section in that segment, plus the address of the
175 relocation. */
252b5132 176 val = bfd_get_section_vma (abfd, sec) + rel->address;
252b5132
RH
177
178#ifdef DEBUG
e460dd0d
AM
179 fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %u\n",
180 __FUNCTION__, (unsigned long) val, (unsigned long) rel->addend,
181 rel->howto->type);
252b5132
RH
182#endif
183 bfd_put_32 (abfd, val, tmp_reloc.offset);
184 bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
1518639e 185 bfd_put_8 (abfd, (short) (rel->howto->type), tmp_reloc.type);
252b5132 186
dc810e39 187 if (bfd_bwrite (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
b34976b6 188 return FALSE;
252b5132 189
b34976b6 190 return TRUE;
252b5132
RH
191}
192
193/* Mangle relocs for SPARC NetWare. We can just use the standard
194 SPARC relocs. */
195
b34976b6 196static bfd_boolean
7920ce38
NC
197nlm_sparc_mangle_relocs (bfd *abfd ATTRIBUTE_UNUSED,
198 asection *sec ATTRIBUTE_UNUSED,
199 const void * data ATTRIBUTE_UNUSED,
200 bfd_vma offset ATTRIBUTE_UNUSED,
201 bfd_size_type count ATTRIBUTE_UNUSED)
252b5132 202{
b34976b6 203 return TRUE;
252b5132
RH
204}
205
42ef282f
NC
206/* Read a NetWare sparc import record. */
207
b34976b6 208static bfd_boolean
7920ce38 209nlm_sparc_read_import (bfd *abfd, nlmNAME (symbol_type) *sym)
252b5132 210{
42ef282f
NC
211 struct nlm_relent *nlm_relocs; /* Relocation records for symbol. */
212 bfd_size_type rcount; /* Number of relocs. */
213 bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Temporary 32-bit value. */
214 unsigned char symlength; /* Length of symbol name. */
252b5132 215 char *name;
1518639e 216
42ef282f
NC
217 /* First, read in the number of relocation
218 entries for this symbol. */
7920ce38 219 if (bfd_bread (temp, (bfd_size_type) 4, abfd) != 4)
b34976b6 220 return FALSE;
1518639e 221
252b5132 222 rcount = bfd_get_32 (abfd, temp);
1518639e 223
42ef282f 224 /* Next, read in the length of the symbol. */
7920ce38 225 if (bfd_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
252b5132 226 != sizeof (symlength))
b34976b6 227 return FALSE;
252b5132 228 sym -> symbol.the_bfd = abfd;
dc810e39 229 name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
252b5132 230 if (name == NULL)
b34976b6 231 return FALSE;
1518639e 232
42ef282f 233 /* Then read in the symbol. */
dc810e39 234 if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
b34976b6 235 return FALSE;
252b5132
RH
236 name[symlength] = '\0';
237 sym -> symbol.name = name;
238 sym -> symbol.flags = 0;
239 sym -> symbol.value = 0;
240 sym -> symbol.section = bfd_und_section_ptr;
1518639e 241
42ef282f 242 /* Next, start reading in the relocs. */
7920ce38 243 nlm_relocs = bfd_alloc (abfd, rcount * sizeof (struct nlm_relent));
252b5132 244 if (!nlm_relocs)
b34976b6 245 return FALSE;
252b5132
RH
246 sym -> relocs = nlm_relocs;
247 sym -> rcnt = 0;
248 while (sym -> rcnt < rcount)
249 {
250 asection *section;
1518639e 251
82e51918 252 if (! nlm_sparc_read_reloc (abfd, sym, &section, &nlm_relocs -> reloc))
b34976b6 253 return FALSE;
252b5132
RH
254 nlm_relocs -> section = section;
255 nlm_relocs++;
256 sym -> rcnt++;
257 }
42ef282f 258
b34976b6 259 return TRUE;
252b5132
RH
260}
261
b34976b6 262static bfd_boolean
7920ce38 263nlm_sparc_write_import (bfd * abfd, asection * sec, arelent * rel)
252b5132
RH
264{
265 char temp[4];
266 asection *code, *data, *bss, *symsec;
267 bfd_vma base;
268
269 code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
270 data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
271 bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
272 symsec = (*rel->sym_ptr_ptr)->section;
273
42ef282f 274 if (symsec == code)
252b5132 275 base = 0;
42ef282f 276 else if (symsec == data)
eea6121a 277 base = code->size;
42ef282f 278 else if (symsec == bss)
eea6121a 279 base = code->size + data->size;
42ef282f 280 else
252b5132
RH
281 base = 0;
282
283#ifdef DEBUG
e460dd0d
AM
284 fprintf (stderr, "%s: <%lx, 1>\n\t",
285 __FUNCTION__, (unsigned long) (base + (*rel->sym_ptr_ptr)->value));
252b5132
RH
286#endif
287 bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
7920ce38 288 if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4)
b34976b6 289 return FALSE;
dc810e39 290 bfd_put_32 (abfd, (bfd_vma) 1, temp);
7920ce38 291 if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4)
b34976b6 292 return FALSE;
82e51918 293 if (! nlm_sparc_write_reloc (abfd, sec, rel))
b34976b6
AM
294 return FALSE;
295 return TRUE;
252b5132
RH
296}
297
298/* Write out an external reference. */
299
b34976b6 300static bfd_boolean
7920ce38
NC
301nlm_sparc_write_external (bfd *abfd,
302 bfd_size_type count,
303 asymbol *sym,
304 struct reloc_and_sec *relocs)
252b5132
RH
305{
306 unsigned int i;
307 bfd_byte len;
308 unsigned char temp[NLM_TARGET_LONG_SIZE];
309
310 bfd_put_32 (abfd, count, temp);
dc810e39 311 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
b34976b6 312 return FALSE;
252b5132
RH
313
314 len = strlen (sym->name);
dc810e39
AM
315 if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
316 != sizeof (bfd_byte))
317 || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
b34976b6 318 return FALSE;
252b5132
RH
319
320 for (i = 0; i < count; i++)
7920ce38
NC
321 if (! nlm_sparc_write_reloc (abfd, relocs[i].sec, relocs[i].rel))
322 return FALSE;
252b5132 323
b34976b6 324 return TRUE;
252b5132
RH
325}
326
b34976b6 327static bfd_boolean
7920ce38 328nlm_sparc_write_export (bfd * abfd, asymbol * sym, bfd_vma value)
252b5132
RH
329{
330 bfd_byte len;
331 bfd_byte temp[4];
332
333#ifdef DEBUG
e460dd0d
AM
334 fprintf (stderr, "%s: <%lx, %u, %s>\n",
335 __FUNCTION__, (unsigned long) value, strlen (sym->name), sym->name);
252b5132
RH
336#endif
337 bfd_put_32 (abfd, value, temp);
338 len = strlen (sym->name);
339
dc810e39
AM
340 if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4
341 || bfd_bwrite (&len, (bfd_size_type) 1, abfd) != 1
342 || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
b34976b6 343 return FALSE;
252b5132 344
b34976b6 345 return TRUE;
252b5132
RH
346}
347
348#undef nlm_swap_fixed_header_in
349#undef nlm_swap_fixed_header_out
350
351#include "nlmswap.h"
352
353static const struct nlm_backend_data nlm32_sparc_backend =
7920ce38
NC
354{
355 "NetWare SPARC Module \032",
356 sizeof (Nlm32_sparc_External_Fixed_Header),
357 0, /* Optional_prefix_size. */
358 bfd_arch_sparc,
359 0,
360 FALSE,
361 0, /* Backend_object_p. */
362 0, /* Write_prefix_func. */
363 nlm_sparc_read_reloc,
364 nlm_sparc_mangle_relocs,
365 nlm_sparc_read_import,
366 nlm_sparc_write_import,
367 0, /* Set_public_section. */
368 0, /* Get_public_offset. */
369 nlm_swap_fixed_header_in,
370 nlm_swap_fixed_header_out,
371 nlm_sparc_write_external,
372 nlm_sparc_write_export
373};
252b5132
RH
374
375#define TARGET_BIG_NAME "nlm32-sparc"
7920ce38 376#define TARGET_BIG_SYM nlmNAME (sparc_vec)
42ef282f 377#define TARGET_BACKEND_DATA & nlm32_sparc_backend
252b5132
RH
378
379#include "nlm-target.h"