source: branches/libc-0.6/src/binutils/bfd/coff-sparc.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 8.8 KB
Line 
1/* BFD back-end for Sparc COFF files.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Written by Cygnus Support.
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "libbfd.h"
25#include "coff/sparc.h"
26#include "coff/internal.h"
27#include "libcoff.h"
28
29#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
30
31#define BADMAG(x) ((x).f_magic != SPARCMAGIC && (x).f_magic != LYNXCOFFMAGIC)
32
33/* The page size is a guess based on ELF. */
34#define COFF_PAGE_SIZE 0x10000
35
36
37static reloc_howto_type *coff_sparc_reloc_type_lookup
38 PARAMS ((bfd *, bfd_reloc_code_real_type));
39static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
40
41enum reloc_type
42 {
43 R_SPARC_NONE = 0,
44 R_SPARC_8, R_SPARC_16, R_SPARC_32,
45 R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32,
46 R_SPARC_WDISP30, R_SPARC_WDISP22,
47 R_SPARC_HI22, R_SPARC_22,
48 R_SPARC_13, R_SPARC_LO10,
49 R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22,
50 R_SPARC_PC10, R_SPARC_PC22,
51 R_SPARC_WPLT30,
52 R_SPARC_COPY,
53 R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT,
54 R_SPARC_RELATIVE,
55 R_SPARC_UA32,
56 R_SPARC_max
57 };
58
59#if 0
60static const char *const reloc_type_names[] =
61{
62 "R_SPARC_NONE",
63 "R_SPARC_8", "R_SPARC_16", "R_SPARC_32",
64 "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32",
65 "R_SPARC_WDISP30", "R_SPARC_WDISP22",
66 "R_SPARC_HI22", "R_SPARC_22",
67 "R_SPARC_13", "R_SPARC_LO10",
68 "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22",
69 "R_SPARC_PC10", "R_SPARC_PC22",
70 "R_SPARC_WPLT30",
71 "R_SPARC_COPY",
72 "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT",
73 "R_SPARC_RELATIVE",
74 "R_SPARC_UA32",
75};
76#endif
77
78/* This is stolen pretty directly from elf.c. */
79static bfd_reloc_status_type
80bfd_coff_generic_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR,
81 asection *, bfd *, char **));
82
83static bfd_reloc_status_type
84bfd_coff_generic_reloc (abfd, reloc_entry, symbol, data, input_section,
85 output_bfd, error_message)
86 bfd *abfd ATTRIBUTE_UNUSED;
87 arelent *reloc_entry;
88 asymbol *symbol;
89 PTR data ATTRIBUTE_UNUSED;
90 asection *input_section;
91 bfd *output_bfd;
92 char **error_message ATTRIBUTE_UNUSED;
93{
94 if (output_bfd != (bfd *) NULL
95 && (symbol->flags & BSF_SECTION_SYM) == 0)
96 {
97 reloc_entry->address += input_section->output_offset;
98 return bfd_reloc_ok;
99 }
100
101 return bfd_reloc_continue;
102}
103
104static reloc_howto_type coff_sparc_howto_table[] =
105{
106 HOWTO(R_SPARC_NONE, 0,0, 0,FALSE,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_NONE", FALSE,0,0x00000000,TRUE),
107 HOWTO(R_SPARC_8, 0,0, 8,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_8", FALSE,0,0x000000ff,TRUE),
108 HOWTO(R_SPARC_16, 0,1,16,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_16", FALSE,0,0x0000ffff,TRUE),
109 HOWTO(R_SPARC_32, 0,2,32,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_32", FALSE,0,0xffffffff,TRUE),
110 HOWTO(R_SPARC_DISP8, 0,0, 8,TRUE, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP8", FALSE,0,0x000000ff,TRUE),
111 HOWTO(R_SPARC_DISP16, 0,1,16,TRUE, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP16", FALSE,0,0x0000ffff,TRUE),
112 HOWTO(R_SPARC_DISP32, 0,2,32,TRUE, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP32", FALSE,0,0x00ffffff,TRUE),
113 HOWTO(R_SPARC_WDISP30, 2,2,30,TRUE, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_WDISP30", FALSE,0,0x3fffffff,TRUE),
114 HOWTO(R_SPARC_WDISP22, 2,2,22,TRUE, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_WDISP22", FALSE,0,0x003fffff,TRUE),
115 HOWTO(R_SPARC_HI22, 10,2,22,FALSE,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_HI22", FALSE,0,0x003fffff,TRUE),
116 HOWTO(R_SPARC_22, 0,2,22,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_22", FALSE,0,0x003fffff,TRUE),
117 HOWTO(R_SPARC_13, 0,2,13,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_13", FALSE,0,0x00001fff,TRUE),
118 HOWTO(R_SPARC_LO10, 0,2,10,FALSE,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_LO10", FALSE,0,0x000003ff,TRUE),
119 HOWTO(R_SPARC_GOT10, 0,2,10,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT10", FALSE,0,0x000003ff,TRUE),
120 HOWTO(R_SPARC_GOT13, 0,2,13,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT13", FALSE,0,0x00001fff,TRUE),
121 HOWTO(R_SPARC_GOT22, 10,2,22,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT22", FALSE,0,0x003fffff,TRUE),
122 HOWTO(R_SPARC_PC10, 0,2,10,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC10", FALSE,0,0x000003ff,TRUE),
123 HOWTO(R_SPARC_PC22, 0,2,22,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC22", FALSE,0,0x003fffff,TRUE),
124 HOWTO(R_SPARC_WPLT30, 0,0,00,FALSE,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_WPLT30", FALSE,0,0x00000000,TRUE),
125 HOWTO(R_SPARC_COPY, 0,0,00,FALSE,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_COPY", FALSE,0,0x00000000,TRUE),
126 HOWTO(R_SPARC_GLOB_DAT,0,0,00,FALSE,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_GLOB_DAT",FALSE,0,0x00000000,TRUE),
127 HOWTO(R_SPARC_JMP_SLOT,0,0,00,FALSE,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_JMP_SLOT",FALSE,0,0x00000000,TRUE),
128 HOWTO(R_SPARC_RELATIVE,0,0,00,FALSE,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_RELATIVE",FALSE,0,0x00000000,TRUE),
129 HOWTO(R_SPARC_UA32, 0,0,00,FALSE,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_UA32", FALSE,0,0x00000000,TRUE),
130};
131
132struct coff_reloc_map {
133 bfd_reloc_code_real_type bfd_reloc_val;
134 unsigned char coff_reloc_val;
135};
136
137static const struct coff_reloc_map sparc_reloc_map[] =
138{
139 { BFD_RELOC_NONE, R_SPARC_NONE, },
140 { BFD_RELOC_16, R_SPARC_16, },
141 { BFD_RELOC_8, R_SPARC_8 },
142 { BFD_RELOC_8_PCREL, R_SPARC_DISP8 },
143 { BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits. */
144 { BFD_RELOC_32, R_SPARC_32 },
145 { BFD_RELOC_32_PCREL, R_SPARC_DISP32 },
146 { BFD_RELOC_HI22, R_SPARC_HI22 },
147 { BFD_RELOC_LO10, R_SPARC_LO10, },
148 { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 },
149 { BFD_RELOC_SPARC22, R_SPARC_22 },
150 { BFD_RELOC_SPARC13, R_SPARC_13 },
151 { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 },
152 { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 },
153 { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 },
154 { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 },
155 { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 },
156 { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 },
157 { BFD_RELOC_SPARC_COPY, R_SPARC_COPY },
158 { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT },
159 { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT },
160 { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE },
161 { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 },
162 /* { BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */
163};
164
165static reloc_howto_type *
166coff_sparc_reloc_type_lookup (abfd, code)
167 bfd *abfd ATTRIBUTE_UNUSED;
168 bfd_reloc_code_real_type code;
169{
170 unsigned int i;
171 for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct coff_reloc_map); i++)
172 {
173 if (sparc_reloc_map[i].bfd_reloc_val == code)
174 return &coff_sparc_howto_table[(int) sparc_reloc_map[i].coff_reloc_val];
175 }
176 return 0;
177}
178#define coff_bfd_reloc_type_lookup coff_sparc_reloc_type_lookup
179
180static void
181rtype2howto (cache_ptr, dst)
182 arelent *cache_ptr;
183 struct internal_reloc *dst;
184{
185 BFD_ASSERT (dst->r_type < (unsigned int) R_SPARC_max);
186 cache_ptr->howto = &coff_sparc_howto_table[dst->r_type];
187}
188
189#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
190
191#define SWAP_IN_RELOC_OFFSET H_GET_32
192#define SWAP_OUT_RELOC_OFFSET H_PUT_32
193#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
194 cache_ptr->addend = reloc.r_offset;
195
196/* Clear the r_spare field in relocs. */
197#define SWAP_OUT_RELOC_EXTRA(abfd,src,dst) \
198 do { \
199 dst->r_spare[0] = 0; \
200 dst->r_spare[1] = 0; \
201 } while (0)
202
203#define __A_MAGIC_SET__
204
205/* Enable Sparc-specific hacks in coffcode.h. */
206
207#define COFF_SPARC
208
209#include "coffcode.h"
210
211#ifndef TARGET_SYM
212#define TARGET_SYM sparccoff_vec
213#endif
214
215#ifndef TARGET_NAME
216#define TARGET_NAME "coff-sparc"
217#endif
218
219CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL)
Note: See TracBrowser for help on using the repository browser.