00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define M88 1
00024 #include "bfd.h"
00025 #include "sysdep.h"
00026 #include "libbfd.h"
00027 #include "coff/m88k.h"
00028 #include "coff/internal.h"
00029 #include "libcoff.h"
00030
00031 static bfd_boolean m88k_is_local_label_name PARAMS ((bfd *, const char *));
00032 static bfd_reloc_status_type m88k_special_reloc
00033 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00034 static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
00035 static void reloc_processing
00036 PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
00037
00038 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
00039
00040 #define GET_SCNHDR_NRELOC H_GET_32
00041 #define GET_SCNHDR_NLNNO H_GET_32
00042
00043
00044
00045 #define coff_bfd_is_local_label_name m88k_is_local_label_name
00046
00047 static bfd_boolean
00048 m88k_is_local_label_name (abfd, name)
00049 bfd *abfd ATTRIBUTE_UNUSED;
00050 const char *name;
00051 {
00052 return name[0] == '@';
00053 }
00054
00055 static bfd_reloc_status_type
00056 m88k_special_reloc (abfd, reloc_entry, symbol, data,
00057 input_section, output_bfd, error_message)
00058 bfd *abfd;
00059 arelent *reloc_entry;
00060 asymbol *symbol;
00061 PTR data;
00062 asection *input_section;
00063 bfd *output_bfd;
00064 char **error_message ATTRIBUTE_UNUSED;
00065 {
00066 reloc_howto_type *howto = reloc_entry->howto;
00067
00068 switch (howto->type)
00069 {
00070 case R_HVRT16:
00071 case R_LVRT16:
00072 if (output_bfd != (bfd *) NULL)
00073 {
00074
00075
00076
00077
00078 reloc_entry->address += input_section->output_offset;
00079 }
00080 else
00081 {
00082 bfd_vma output_base = 0;
00083 bfd_vma addr = reloc_entry->address;
00084 bfd_vma x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
00085 asection *reloc_target_output_section;
00086 long relocation = 0;
00087
00088
00089
00090
00091
00092 if (bfd_is_com_section (symbol->section))
00093 relocation = 0;
00094 else
00095 relocation = symbol->value;
00096
00097 reloc_target_output_section = symbol->section->output_section;
00098
00099
00100 if (output_bfd)
00101 output_base = 0;
00102 else
00103 output_base = reloc_target_output_section->vma;
00104
00105 relocation += output_base + symbol->section->output_offset;
00106
00107
00108 relocation += ((reloc_entry->addend << howto->bitsize) + x);
00109
00110 reloc_entry->addend = 0;
00111
00112 relocation >>= (bfd_vma) howto->rightshift;
00113
00114
00115
00116 relocation <<= (bfd_vma) howto->bitpos;
00117
00118 if (relocation)
00119 bfd_put_16 (abfd, (bfd_vma) relocation,
00120 (unsigned char *) data + addr);
00121 }
00122
00123
00124
00125 if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
00126 return bfd_reloc_undefined;
00127
00128 return bfd_reloc_ok;
00129
00130 default:
00131 if (output_bfd != (bfd *) NULL)
00132 {
00133
00134
00135
00136
00137 reloc_entry->address += input_section->output_offset;
00138 return bfd_reloc_ok;
00139 }
00140 break;
00141 }
00142
00143 if (output_bfd == (bfd *) NULL)
00144 return bfd_reloc_continue;
00145
00146 return bfd_reloc_ok;
00147 }
00148
00149 static reloc_howto_type howto_table[] =
00150 {
00151 HOWTO (R_PCR16L,
00152 02,
00153 1,
00154 16,
00155 TRUE,
00156 0,
00157 complain_overflow_signed,
00158 m88k_special_reloc,
00159 "PCR16L",
00160 FALSE,
00161 0x0000ffff,
00162 0x0000ffff,
00163 TRUE),
00164
00165 HOWTO (R_PCR26L,
00166 02,
00167 2,
00168 26,
00169 TRUE,
00170 0,
00171 complain_overflow_signed,
00172 m88k_special_reloc,
00173 "PCR26L",
00174 FALSE,
00175 0x03ffffff,
00176 0x03ffffff,
00177 TRUE),
00178
00179 HOWTO (R_VRT16,
00180 00,
00181 1,
00182 16,
00183 FALSE,
00184 0,
00185 complain_overflow_bitfield,
00186 m88k_special_reloc,
00187 "VRT16",
00188 FALSE,
00189 0x0000ffff,
00190 0x0000ffff,
00191 TRUE),
00192
00193 HOWTO (R_HVRT16,
00194 16,
00195 1,
00196 16,
00197 FALSE,
00198 0,
00199 complain_overflow_dont,
00200 m88k_special_reloc,
00201 "HVRT16",
00202 FALSE,
00203 0x0000ffff,
00204 0x0000ffff,
00205 TRUE),
00206
00207 HOWTO (R_LVRT16,
00208 00,
00209 1,
00210 16,
00211 FALSE,
00212 0,
00213 complain_overflow_dont,
00214 m88k_special_reloc,
00215 "LVRT16",
00216 FALSE,
00217 0x0000ffff,
00218 0x0000ffff,
00219 TRUE),
00220
00221 HOWTO (R_VRT32,
00222 00,
00223 2,
00224 32,
00225 FALSE,
00226 0,
00227 complain_overflow_bitfield,
00228 m88k_special_reloc,
00229 "VRT32",
00230 FALSE,
00231 0xffffffff,
00232 0xffffffff,
00233 TRUE),
00234 };
00235
00236
00237
00238 static void
00239 rtype2howto (cache_ptr, dst)
00240 arelent *cache_ptr;
00241 struct internal_reloc *dst;
00242 {
00243 if (dst->r_type >= R_PCR16L && dst->r_type <= R_VRT32)
00244 {
00245 cache_ptr->howto = howto_table + dst->r_type - R_PCR16L;
00246 }
00247 else
00248 {
00249 BFD_ASSERT (0);
00250 }
00251 }
00252
00253 #define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
00254
00255
00256 #define SWAP_IN_RELOC_OFFSET H_GET_16
00257 #define SWAP_OUT_RELOC_OFFSET H_PUT_16
00258
00259 #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
00260 reloc_processing(relent, reloc, symbols, abfd, section)
00261
00262 static void
00263 reloc_processing (relent, reloc, symbols, abfd, section)
00264 arelent *relent;
00265 struct internal_reloc *reloc;
00266 asymbol **symbols;
00267 bfd *abfd;
00268 asection *section;
00269 {
00270 relent->address = reloc->r_vaddr;
00271 rtype2howto (relent, reloc);
00272
00273 if (((int) reloc->r_symndx) > 0)
00274 {
00275 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
00276 }
00277 else
00278 {
00279 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
00280 }
00281
00282 relent->addend = reloc->r_offset;
00283 relent->address -= section->vma;
00284 }
00285
00286 #define BADMAG(x) MC88BADMAG(x)
00287 #include "coffcode.h"
00288
00289 #undef coff_write_armap
00290
00291 CREATE_BIG_COFF_TARGET_VEC (m88kbcs_vec, "coff-m88kbcs", 0, 0, '_', NULL, COFF_SWAP_TABLE)