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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "bfd.h"
00048 #include "sysdep.h"
00049 #include "libbfd.h"
00050
00051
00052 extern const size_t _bfd_target_vector_entries;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 bfd_boolean
00093 bfd_check_format (bfd *abfd, bfd_format format)
00094 {
00095 return bfd_check_format_matches (abfd, format, NULL);
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 bfd_boolean
00119 bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
00120 {
00121 extern const bfd_target binary_vec;
00122 const bfd_target * const *target;
00123 const bfd_target **matching_vector = NULL;
00124 const bfd_target *save_targ, *right_targ, *ar_right_targ;
00125 int match_count;
00126 int ar_match_index;
00127
00128 if (!bfd_read_p (abfd)
00129 || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
00130 {
00131 bfd_set_error (bfd_error_invalid_operation);
00132 return FALSE;
00133 }
00134
00135 if (abfd->format != bfd_unknown)
00136 return abfd->format == format;
00137
00138
00139
00140 save_targ = abfd->xvec;
00141 match_count = 0;
00142 ar_match_index = _bfd_target_vector_entries;
00143
00144 if (matching)
00145 {
00146 bfd_size_type amt;
00147
00148 *matching = NULL;
00149 amt = sizeof (*matching_vector) * 2 * _bfd_target_vector_entries;
00150 matching_vector = bfd_malloc (amt);
00151 if (!matching_vector)
00152 return FALSE;
00153 }
00154
00155 right_targ = 0;
00156 ar_right_targ = 0;
00157
00158
00159 abfd->format = format;
00160
00161
00162 if (!abfd->target_defaulted)
00163 {
00164 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
00165 {
00166 if (matching)
00167 free (matching_vector);
00168 return FALSE;
00169 }
00170
00171 right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
00172
00173 if (right_targ)
00174 {
00175 abfd->xvec = right_targ;
00176
00177 if (matching)
00178 free (matching_vector);
00179
00180 return TRUE;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 if (format == bfd_archive && save_targ == &binary_vec)
00196 {
00197 abfd->xvec = save_targ;
00198 abfd->format = bfd_unknown;
00199
00200 if (matching)
00201 free (matching_vector);
00202
00203 bfd_set_error (bfd_error_file_not_recognized);
00204
00205 return FALSE;
00206 }
00207 }
00208
00209 for (target = bfd_target_vector; *target != NULL; target++)
00210 {
00211 const bfd_target *temp;
00212 bfd_error_type err;
00213
00214 if (*target == &binary_vec)
00215 continue;
00216
00217 abfd->xvec = *target;
00218
00219 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
00220 {
00221 if (matching)
00222 free (matching_vector);
00223 return FALSE;
00224 }
00225
00226
00227
00228
00229
00230 bfd_set_error (bfd_error_wrong_format);
00231
00232 temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
00233
00234 if (temp)
00235 {
00236
00237 right_targ = temp;
00238
00239
00240
00241
00242 if (temp == bfd_default_vector[0])
00243 {
00244 match_count = 1;
00245 break;
00246 }
00247
00248 if (matching)
00249 matching_vector[match_count] = temp;
00250
00251 match_count++;
00252 }
00253 else if ((err = bfd_get_error ()) == bfd_error_wrong_object_format
00254 || err == bfd_error_file_ambiguously_recognized)
00255 {
00256
00257
00258
00259 if (ar_right_targ != bfd_default_vector[0])
00260 ar_right_targ = *target;
00261 if (matching)
00262 matching_vector[ar_match_index] = *target;
00263 ar_match_index++;
00264 }
00265 else if (err != bfd_error_wrong_format)
00266 {
00267 abfd->xvec = save_targ;
00268 abfd->format = bfd_unknown;
00269
00270 if (matching)
00271 free (matching_vector);
00272
00273 return FALSE;
00274 }
00275 }
00276
00277 if (match_count == 0)
00278 {
00279
00280 right_targ = ar_right_targ;
00281
00282 if (right_targ == bfd_default_vector[0])
00283 {
00284 match_count = 1;
00285 }
00286 else
00287 {
00288 match_count = ar_match_index - _bfd_target_vector_entries;
00289
00290 if (matching && match_count > 1)
00291 memcpy (matching_vector,
00292 matching_vector + _bfd_target_vector_entries,
00293 sizeof (*matching_vector) * match_count);
00294 }
00295 }
00296
00297 if (match_count > 1
00298 && bfd_associated_vector != NULL
00299 && matching)
00300 {
00301 const bfd_target * const *assoc = bfd_associated_vector;
00302
00303 while ((right_targ = *assoc++) != NULL)
00304 {
00305 int i = match_count;
00306
00307 while (--i >= 0)
00308 if (matching_vector[i] == right_targ)
00309 break;
00310
00311 if (i >= 0)
00312 {
00313 match_count = 1;
00314 break;
00315 }
00316 }
00317 }
00318
00319 if (match_count == 1)
00320 {
00321 abfd->xvec = right_targ;
00322
00323 if (matching)
00324 free (matching_vector);
00325
00326 return TRUE;
00327 }
00328
00329 abfd->xvec = save_targ;
00330 abfd->format = bfd_unknown;
00331
00332 if (match_count == 0)
00333 {
00334 bfd_set_error (bfd_error_file_not_recognized);
00335
00336 if (matching)
00337 free (matching_vector);
00338 }
00339 else
00340 {
00341 bfd_set_error (bfd_error_file_ambiguously_recognized);
00342
00343 if (matching)
00344 {
00345 *matching = (char **) matching_vector;
00346 matching_vector[match_count] = NULL;
00347
00348
00349 while (--match_count >= 0)
00350 {
00351 const char *name = matching_vector[match_count]->name;
00352 *(const char **) &matching_vector[match_count] = name;
00353 }
00354 }
00355 }
00356
00357 return FALSE;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 bfd_boolean
00375 bfd_set_format (bfd *abfd, bfd_format format)
00376 {
00377 if (bfd_read_p (abfd)
00378 || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
00379 {
00380 bfd_set_error (bfd_error_invalid_operation);
00381 return FALSE;
00382 }
00383
00384 if (abfd->format != bfd_unknown)
00385 return abfd->format == format;
00386
00387
00388 abfd->format = format;
00389
00390 if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd)))
00391 {
00392 abfd->format = bfd_unknown;
00393 return FALSE;
00394 }
00395
00396 return TRUE;
00397 }
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 const char *
00413 bfd_format_string (bfd_format format)
00414 {
00415 if (((int) format < (int) bfd_unknown)
00416 || ((int) format >= (int) bfd_type_end))
00417 return "invalid";
00418
00419 switch (format)
00420 {
00421 case bfd_object:
00422 return "object";
00423 case bfd_archive:
00424 return "archive";
00425 case bfd_core:
00426 return "core";
00427 default:
00428 return "unknown";
00429 }
00430 }