00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "bfd.h"
00026 #include "sysdep.h"
00027 #include "libbfd.h"
00028
00029 #define ARCH_SIZE 32
00030
00031 #include "nlm/sparc32-ext.h"
00032 #define Nlm_External_Fixed_Header Nlm32_sparc_External_Fixed_Header
00033
00034 #include "libnlm.h"
00035
00036 static bfd_boolean nlm_sparc_read_reloc
00037 PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
00038 static bfd_boolean nlm_sparc_write_reloc
00039 PARAMS ((bfd *, asection *, arelent *));
00040 static bfd_boolean nlm_sparc_mangle_relocs
00041 PARAMS ((bfd *, asection *, const PTR, bfd_vma, bfd_size_type));
00042 static bfd_boolean nlm_sparc_read_import
00043 PARAMS ((bfd *, nlmNAME(symbol_type) *));
00044 static bfd_boolean nlm_sparc_write_import
00045 PARAMS ((bfd *, asection *, arelent *));
00046 static bfd_boolean nlm_sparc_write_external
00047 PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
00048 static bfd_boolean nlm_sparc_write_export
00049 PARAMS ((bfd *, asymbol *, bfd_vma));
00050
00051 enum reloc_type
00052 {
00053 R_SPARC_NONE = 0,
00054 R_SPARC_8, R_SPARC_16, R_SPARC_32,
00055 R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32,
00056 R_SPARC_WDISP30, R_SPARC_WDISP22,
00057 R_SPARC_HI22, R_SPARC_22,
00058 R_SPARC_13, R_SPARC_LO10,
00059 R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22,
00060 R_SPARC_PC10, R_SPARC_PC22,
00061 R_SPARC_WPLT30,
00062 R_SPARC_COPY,
00063 R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT,
00064 R_SPARC_RELATIVE,
00065 R_SPARC_UA32,
00066 R_SPARC_max
00067 };
00068
00069 static reloc_howto_type nlm32_sparc_howto_table[] =
00070 {
00071 HOWTO (R_SPARC_NONE, 0,0, 0,FALSE,0,complain_overflow_dont, 0,"R_SPARC_NONE", FALSE,0,0x00000000,TRUE),
00072 HOWTO (R_SPARC_8, 0,0, 8,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_8", FALSE,0,0x000000ff,TRUE),
00073 HOWTO (R_SPARC_16, 0,1,16,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_16", FALSE,0,0x0000ffff,TRUE),
00074 HOWTO (R_SPARC_32, 0,2,32,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_32", FALSE,0,0xffffffff,TRUE),
00075 HOWTO (R_SPARC_DISP8, 0,0, 8,TRUE, 0,complain_overflow_signed, 0,"R_SPARC_DISP8", FALSE,0,0x000000ff,TRUE),
00076 HOWTO (R_SPARC_DISP16, 0,1,16,TRUE, 0,complain_overflow_signed, 0,"R_SPARC_DISP16", FALSE,0,0x0000ffff,TRUE),
00077 HOWTO (R_SPARC_DISP32, 0,2,32,TRUE, 0,complain_overflow_signed, 0,"R_SPARC_DISP32", FALSE,0,0x00ffffff,TRUE),
00078 HOWTO (R_SPARC_WDISP30, 2,2,30,TRUE, 0,complain_overflow_signed, 0,"R_SPARC_WDISP30", FALSE,0,0x3fffffff,TRUE),
00079 HOWTO (R_SPARC_WDISP22, 2,2,22,TRUE, 0,complain_overflow_signed, 0,"R_SPARC_WDISP22", FALSE,0,0x003fffff,TRUE),
00080 HOWTO (R_SPARC_HI22, 10,2,22,FALSE,0,complain_overflow_dont, 0,"R_SPARC_HI22", FALSE,0,0x003fffff,TRUE),
00081 HOWTO (R_SPARC_22, 0,2,22,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_22", FALSE,0,0x003fffff,TRUE),
00082 HOWTO (R_SPARC_13, 0,2,13,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_13", FALSE,0,0x00001fff,TRUE),
00083 HOWTO (R_SPARC_LO10, 0,2,10,FALSE,0,complain_overflow_dont, 0,"R_SPARC_LO10", FALSE,0,0x000003ff,TRUE),
00084 HOWTO (R_SPARC_GOT10, 0,2,10,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_GOT10", FALSE,0,0x000003ff,TRUE),
00085 HOWTO (R_SPARC_GOT13, 0,2,13,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_GOT13", FALSE,0,0x00001fff,TRUE),
00086 HOWTO (R_SPARC_GOT22, 10,2,22,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_GOT22", FALSE,0,0x003fffff,TRUE),
00087 HOWTO (R_SPARC_PC10, 0,2,10,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_PC10", FALSE,0,0x000003ff,TRUE),
00088 HOWTO (R_SPARC_PC22, 0,2,22,FALSE,0,complain_overflow_bitfield,0,"R_SPARC_PC22", FALSE,0,0x003fffff,TRUE),
00089 HOWTO (R_SPARC_WPLT30, 0,0,00,FALSE,0,complain_overflow_dont, 0,"R_SPARC_WPLT30", FALSE,0,0x00000000,TRUE),
00090 HOWTO (R_SPARC_COPY, 0,0,00,FALSE,0,complain_overflow_dont, 0,"R_SPARC_COPY", FALSE,0,0x00000000,TRUE),
00091 HOWTO (R_SPARC_GLOB_DAT,0,0,00,FALSE,0,complain_overflow_dont, 0,"R_SPARC_GLOB_DAT",FALSE,0,0x00000000,TRUE),
00092 HOWTO (R_SPARC_JMP_SLOT,0,0,00,FALSE,0,complain_overflow_dont, 0,"R_SPARC_JMP_SLOT",FALSE,0,0x00000000,TRUE),
00093 HOWTO (R_SPARC_RELATIVE,0,0,00,FALSE,0,complain_overflow_dont, 0,"R_SPARC_RELATIVE",FALSE,0,0x00000000,TRUE),
00094 HOWTO (R_SPARC_UA32, 0,0,00,FALSE,0,complain_overflow_dont, 0,"R_SPARC_UA32", FALSE,0,0x00000000,TRUE),
00095 };
00096
00097
00098
00099 struct nlm32_sparc_reloc_ext
00100 {
00101 unsigned char offset[4];
00102 unsigned char addend[4];
00103 unsigned char type[1];
00104 unsigned char pad1[3];
00105 };
00106
00107 static bfd_boolean
00108 nlm_sparc_read_reloc (abfd, sym, secp, rel)
00109 bfd *abfd;
00110 nlmNAME(symbol_type) *sym ATTRIBUTE_UNUSED;
00111 asection **secp;
00112 arelent *rel;
00113 {
00114 bfd_vma val, addend;
00115 unsigned int index;
00116 unsigned int type;
00117 struct nlm32_sparc_reloc_ext tmp_reloc;
00118 asection *code_sec, *data_sec;
00119
00120 if (bfd_bread (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
00121 return FALSE;
00122
00123 code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
00124 data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
00125
00126 *secp = code_sec;
00127
00128 val = bfd_get_32 (abfd, tmp_reloc.offset);
00129 addend = bfd_get_32 (abfd, tmp_reloc.addend);
00130 type = bfd_get_8 (abfd, tmp_reloc.type);
00131
00132 rel->address = val;
00133 rel->addend = addend;
00134 rel->howto = NULL;
00135
00136 for (index = 0;
00137 index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
00138 index++)
00139 if (nlm32_sparc_howto_table[index].type == type)
00140 {
00141 rel->howto = &nlm32_sparc_howto_table[index];
00142 break;
00143 }
00144
00145 #ifdef DEBUG
00146 fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
00147 __FUNCTION__, rel->address, rel->addend, type, rel->howto);
00148 #endif
00149 return TRUE;
00150
00151 }
00152
00153
00154
00155 static bfd_boolean
00156 nlm_sparc_write_reloc (abfd, sec, rel)
00157 bfd *abfd;
00158 asection *sec;
00159 arelent *rel;
00160 {
00161 bfd_vma val;
00162 struct nlm32_sparc_reloc_ext tmp_reloc;
00163 unsigned int index;
00164 int type = -1;
00165 reloc_howto_type *tmp;
00166
00167 for (index = 0;
00168 index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
00169 index++)
00170 {
00171 tmp = &nlm32_sparc_howto_table[index];
00172
00173 if (tmp->rightshift == rel->howto->rightshift
00174 && tmp->size == rel->howto->size
00175 && tmp->bitsize == rel->howto->bitsize
00176 && tmp->pc_relative == rel->howto->pc_relative
00177 && tmp->bitpos == rel->howto->bitpos
00178 && tmp->src_mask == rel->howto->src_mask
00179 && tmp->dst_mask == rel->howto->dst_mask)
00180 {
00181 type = tmp->type;
00182 break;
00183 }
00184 }
00185 if (type == -1)
00186 abort ();
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 val = bfd_get_section_vma (abfd, sec) + rel->address;
00200
00201 #ifdef DEBUG
00202 fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n",
00203 __FUNCTION__, val, rel->addend, rel->howto->type);
00204 #endif
00205 bfd_put_32 (abfd, val, tmp_reloc.offset);
00206 bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
00207 bfd_put_8 (abfd, (short) (rel->howto->type), tmp_reloc.type);
00208
00209 if (bfd_bwrite (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
00210 return FALSE;
00211
00212 return TRUE;
00213 }
00214
00215
00216
00217
00218 static bfd_boolean
00219 nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
00220 bfd *abfd ATTRIBUTE_UNUSED;
00221 asection *sec ATTRIBUTE_UNUSED;
00222 const PTR data ATTRIBUTE_UNUSED;
00223 bfd_vma offset ATTRIBUTE_UNUSED;
00224 bfd_size_type count ATTRIBUTE_UNUSED;
00225 {
00226 return TRUE;
00227 }
00228
00229
00230
00231 static bfd_boolean
00232 nlm_sparc_read_import (abfd, sym)
00233 bfd *abfd;
00234 nlmNAME(symbol_type) *sym;
00235 {
00236 struct nlm_relent *nlm_relocs;
00237 bfd_size_type rcount;
00238 bfd_byte temp[NLM_TARGET_LONG_SIZE];
00239 unsigned char symlength;
00240 char *name;
00241
00242
00243
00244 if (bfd_bread ((PTR) temp, (bfd_size_type) 4, abfd) != 4)
00245 return FALSE;
00246
00247 rcount = bfd_get_32 (abfd, temp);
00248
00249
00250
00251 if (bfd_bread ((PTR) &symlength, (bfd_size_type) sizeof (symlength), abfd)
00252 != sizeof (symlength))
00253 return FALSE;
00254 sym -> symbol.the_bfd = abfd;
00255 name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
00256 if (name == NULL)
00257 return FALSE;
00258
00259
00260
00261 if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
00262 return FALSE;
00263 name[symlength] = '\0';
00264 sym -> symbol.name = name;
00265 sym -> symbol.flags = 0;
00266 sym -> symbol.value = 0;
00267 sym -> symbol.section = bfd_und_section_ptr;
00268
00269
00270
00271 nlm_relocs = ((struct nlm_relent *)
00272 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
00273 if (!nlm_relocs)
00274 return FALSE;
00275 sym -> relocs = nlm_relocs;
00276 sym -> rcnt = 0;
00277 while (sym -> rcnt < rcount)
00278 {
00279 asection *section;
00280
00281 if (! nlm_sparc_read_reloc (abfd, sym, §ion, &nlm_relocs -> reloc))
00282 return FALSE;
00283 nlm_relocs -> section = section;
00284 nlm_relocs++;
00285 sym -> rcnt++;
00286 }
00287
00288 return TRUE;
00289 }
00290
00291 static bfd_boolean
00292 nlm_sparc_write_import (abfd, sec, rel)
00293 bfd *abfd;
00294 asection *sec;
00295 arelent *rel;
00296 {
00297 char temp[4];
00298 asection *code, *data, *bss, *symsec;
00299 bfd_vma base;
00300
00301 code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
00302 data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
00303 bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
00304 symsec = (*rel->sym_ptr_ptr)->section;
00305
00306 if (symsec == code)
00307 base = 0;
00308 else if (symsec == data)
00309 base = code->size;
00310 else if (symsec == bss)
00311 base = code->size + data->size;
00312 else
00313 base = 0;
00314
00315 #ifdef DEBUG
00316 fprintf (stderr, "%s: <%x, 1>\n\t",
00317 __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
00318 #endif
00319 bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
00320 if (bfd_bwrite ((PTR) temp, (bfd_size_type) 4, abfd) != 4)
00321 return FALSE;
00322 bfd_put_32 (abfd, (bfd_vma) 1, temp);
00323 if (bfd_bwrite ((PTR) temp, (bfd_size_type) 4, abfd) != 4)
00324 return FALSE;
00325 if (! nlm_sparc_write_reloc (abfd, sec, rel))
00326 return FALSE;
00327 return TRUE;
00328 }
00329
00330
00331
00332 static bfd_boolean
00333 nlm_sparc_write_external (abfd, count, sym, relocs)
00334 bfd *abfd;
00335 bfd_size_type count;
00336 asymbol *sym;
00337 struct reloc_and_sec *relocs;
00338 {
00339 unsigned int i;
00340 bfd_byte len;
00341 unsigned char temp[NLM_TARGET_LONG_SIZE];
00342
00343 bfd_put_32 (abfd, count, temp);
00344 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
00345 return FALSE;
00346
00347 len = strlen (sym->name);
00348 if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
00349 != sizeof (bfd_byte))
00350 || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
00351 return FALSE;
00352
00353 for (i = 0; i < count; i++)
00354 {
00355 if (! nlm_sparc_write_reloc (abfd, relocs[i].sec, relocs[i].rel))
00356 return FALSE;
00357 }
00358
00359 return TRUE;
00360 }
00361
00362 static bfd_boolean
00363 nlm_sparc_write_export (abfd, sym, value)
00364 bfd *abfd;
00365 asymbol *sym;
00366 bfd_vma value;
00367 {
00368 bfd_byte len;
00369 bfd_byte temp[4];
00370
00371 #ifdef DEBUG
00372 fprintf (stderr, "%s: <%x, %d, %s>\n",
00373 __FUNCTION__, value, strlen (sym->name), sym->name);
00374 #endif
00375 bfd_put_32 (abfd, value, temp);
00376 len = strlen (sym->name);
00377
00378 if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4
00379 || bfd_bwrite (&len, (bfd_size_type) 1, abfd) != 1
00380 || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
00381 return FALSE;
00382
00383 return TRUE;
00384 }
00385
00386 #undef nlm_swap_fixed_header_in
00387 #undef nlm_swap_fixed_header_out
00388
00389 #include "nlmswap.h"
00390
00391 static const struct nlm_backend_data nlm32_sparc_backend =
00392 {
00393 "NetWare SPARC Module \032",
00394 sizeof (Nlm32_sparc_External_Fixed_Header),
00395 0,
00396 bfd_arch_sparc,
00397 0,
00398 FALSE,
00399 0,
00400 0,
00401 nlm_sparc_read_reloc,
00402 nlm_sparc_mangle_relocs,
00403 nlm_sparc_read_import,
00404 nlm_sparc_write_import,
00405 0,
00406 0,
00407 nlm_swap_fixed_header_in,
00408 nlm_swap_fixed_header_out,
00409 nlm_sparc_write_external,
00410 nlm_sparc_write_export
00411 };
00412
00413 #define TARGET_BIG_NAME "nlm32-sparc"
00414 #define TARGET_BIG_SYM nlmNAME(sparc_vec)
00415 #define TARGET_BACKEND_DATA & nlm32_sparc_backend
00416
00417 #include "nlm-target.h"