static bfd_boolean ar_emul_aix_parse_arg (char *arg) { if (CONST_STRNEQ (arg, "-X32_64")) { big_archive = TRUE; X32 = TRUE; X64 = TRUE; } else if (CONST_STRNEQ (arg, "-X32")) { big_archive = TRUE; X32 = TRUE; X64 = FALSE; } else if (CONST_STRNEQ (arg, "-X64")) { big_archive = TRUE; X32 = FALSE; X64 = TRUE; } else if (CONST_STRNEQ (arg, "-g")) { big_archive = FALSE; X32 = TRUE; X64 = FALSE; } else return FALSE; return TRUE; }
static void init_disasm (struct disassemble_info *info) { int i; const char *p; memset (opc_index, 0, sizeof (opc_index)); /* Reverse order, such that each opc_index ends up pointing to the first matching entry instead of the last. */ for (i = s390_num_opcodes; i--; ) opc_index[s390_opcodes[i].opcode[0]] = i; for (p = info->disassembler_options; p != NULL; ) { if (CONST_STRNEQ (p, "esa")) current_arch_mask = 1 << S390_OPCODE_ESA; else if (CONST_STRNEQ (p, "zarch")) current_arch_mask = 1 << S390_OPCODE_ZARCH; else fprintf (stderr, "Unknown S/390 disassembler option: %s\n", p); p = strchr (p, ','); if (p != NULL) p++; } if (!current_arch_mask) current_arch_mask = 1 << S390_OPCODE_ZARCH; init_flag = 1; }
void disassemble_init_s390 (struct disassemble_info *info) { int i; const char *p; memset (opc_index, 0, sizeof (opc_index)); /* Reverse order, such that each opc_index ends up pointing to the first matching entry instead of the last. */ for (i = s390_num_opcodes; i--; ) opc_index[s390_opcodes[i].opcode[0]] = i; current_arch_mask = 1 << S390_OPCODE_ZARCH; option_use_insn_len_bits_p = 0; for (p = info->disassembler_options; p != NULL; ) { if (CONST_STRNEQ (p, "esa")) current_arch_mask = 1 << S390_OPCODE_ESA; else if (CONST_STRNEQ (p, "zarch")) current_arch_mask = 1 << S390_OPCODE_ZARCH; else if (CONST_STRNEQ (p, "insnlength")) option_use_insn_len_bits_p = 1; else /* xgettext:c-format */ opcodes_error_handler (_("unknown S/390 disassembler option: %s"), p); p = strchr (p, ','); if (p != NULL) p++; } }
static void bfd_pef_print_symbol (bfd *abfd, void * afile, asymbol *symbol, bfd_print_symbol_type how) { FILE *file = (FILE *) afile; switch (how) { case bfd_print_symbol_name: fprintf (file, "%s", symbol->name); break; default: bfd_print_symbol_vandf (abfd, (void *) file, symbol); fprintf (file, " %-5s %s", symbol->section->name, symbol->name); if (CONST_STRNEQ (symbol->name, "__traceback_")) { unsigned char *buf = xmalloc (symbol->udata.i); size_t offset = symbol->value + 4; size_t len = symbol->udata.i; int ret; bfd_get_section_contents (abfd, symbol->section, buf, offset, len); ret = bfd_pef_parse_traceback_table (abfd, symbol->section, buf, len, 0, NULL, file); if (ret < 0) fprintf (file, " [ERROR]"); free (buf); } } }
/* Helper function for bfd_map_over_section. */ static void pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *obj) { if (CONST_STRNEQ (pdata->name, ".pdata")) { if (pex64_bfd_print_pdata_section (abfd, obj, pdata)) pdata_count++; } }
bfd_boolean bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec, int *compression_header_size_p, bfd_size_type *uncompressed_size_p) { bfd_byte header[MAX_COMPRESSION_HEADER_SIZE]; int compression_header_size; int header_size; unsigned int saved = sec->compress_status; bfd_boolean compressed; compression_header_size = bfd_get_compression_header_size (abfd, sec); if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE) abort (); header_size = compression_header_size ? compression_header_size : 12; /* Don't decompress the section. */ sec->compress_status = COMPRESS_SECTION_NONE; /* Read the header. */ if (bfd_get_section_contents (abfd, sec, header, 0, header_size)) { if (compression_header_size == 0) /* In this case, it should be "ZLIB" followed by the uncompressed section size, 8 bytes in big-endian order. */ compressed = CONST_STRNEQ ((char*) header , "ZLIB"); else compressed = TRUE; } else compressed = FALSE; *uncompressed_size_p = sec->size; if (compressed) { if (compression_header_size != 0) { if (!bfd_check_compression_header (abfd, header, sec, uncompressed_size_p)) compression_header_size = -1; } /* Check for the pathalogical case of a debug string section that contains the string ZLIB.... as the first entry. We assume that no uncompressed .debug_str section would ever be big enough to have the first byte of its (big-endian) size be non-zero. */ else if (strcmp (sec->name, ".debug_str") == 0 && ISPRINT (header[4])) compressed = FALSE; else *uncompressed_size_p = bfd_getb64 (header + 4); } /* Restore compress_status. */ sec->compress_status = saved; *compression_header_size_p = compression_header_size; return compressed; }
bfd_boolean bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec) { bfd_byte header[MAX_COMPRESSION_HEADER_SIZE]; int compression_header_size; int header_size; bfd_size_type uncompressed_size; compression_header_size = bfd_get_compression_header_size (abfd, sec); if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE) abort (); header_size = compression_header_size ? compression_header_size : 12; /* Read the header. */ if (sec->rawsize != 0 || sec->contents != NULL || sec->compress_status != COMPRESS_SECTION_NONE || !bfd_get_section_contents (abfd, sec, header, 0, header_size)) { bfd_set_error (bfd_error_invalid_operation); return FALSE; } if (compression_header_size == 0) { /* In this case, it should be "ZLIB" followed by the uncompressed section size, 8 bytes in big-endian order. */ if (! CONST_STRNEQ ((char*) header, "ZLIB")) { bfd_set_error (bfd_error_wrong_format); return FALSE; } uncompressed_size = bfd_getb64 (header + 4); } else if (!bfd_check_compression_header (abfd, header, sec, &uncompressed_size)) { bfd_set_error (bfd_error_wrong_format); return FALSE; } sec->compressed_size = sec->size; sec->size = uncompressed_size; sec->compress_status = DECOMPRESS_SECTION_SIZED; return TRUE; }
static int ctor_prio (const char *name) { /* The name will look something like _GLOBAL_$I$65535$test02__Fv. There might be extra leading underscores, and the $ characters might be something else. The I might be a D. */ while (*name == '_') ++name; if (! CONST_STRNEQ (name, "GLOBAL_")) return -1; name += sizeof "GLOBAL_" - 1; if (name[0] != name[2]) return -1; if (name[1] != 'I' && name[1] != 'D') return -1; if (! ISDIGIT (name[3])) return -1; return atoi (name + 3); }
bfd_boolean bfd_elf64_archive_slurp_armap (bfd *abfd) { struct artdata *ardata = bfd_ardata (abfd); char nextname[17]; bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize; struct areltdata *mapdata; bfd_byte int_buf[8]; char *stringbase; char *stringend; bfd_byte *raw_armap = NULL; carsym *carsyms; bfd_size_type amt; ardata->symdefs = NULL; /* Get the name of the first element. */ i = bfd_bread (nextname, 16, abfd); if (i == 0) return TRUE; if (i != 16) return FALSE; if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0) return FALSE; /* Archives with traditional armaps are still permitted. */ if (CONST_STRNEQ (nextname, "/ ")) return bfd_slurp_armap (abfd); if (! CONST_STRNEQ (nextname, "/SYM64/ ")) { bfd_has_map (abfd) = FALSE; return TRUE; } mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); if (mapdata == NULL) return FALSE; parsed_size = mapdata->parsed_size; free (mapdata); if (bfd_bread (int_buf, 8, abfd) != 8) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_malformed_archive); return FALSE; } nsymz = bfd_getb64 (int_buf); stringsize = parsed_size - 8 * nsymz - 8; carsym_size = nsymz * sizeof (carsym); ptrsize = 8 * nsymz; amt = carsym_size + stringsize + 1; if (carsym_size < nsymz || ptrsize < nsymz || amt < nsymz) { bfd_set_error (bfd_error_malformed_archive); return FALSE; } ardata->symdefs = (struct carsym *) bfd_zalloc (abfd, amt); if (ardata->symdefs == NULL) return FALSE; carsyms = ardata->symdefs; stringbase = ((char *) ardata->symdefs) + carsym_size; stringbase[stringsize] = 0; stringend = stringbase + stringsize; raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize); if (raw_armap == NULL) goto release_symdefs; if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize || bfd_bread (stringbase, stringsize, abfd) != stringsize) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_malformed_archive); goto release_raw_armap; } for (i = 0; i < nsymz; i++) { carsyms->file_offset = bfd_getb64 (raw_armap + i * 8); carsyms->name = stringbase; if (stringbase < stringend) stringbase += strlen (stringbase) + 1; ++carsyms; } *stringbase = '\0'; ardata->symdef_count = nsymz; ardata->first_file_filepos = bfd_tell (abfd); /* Pad to an even boundary if you have to. */ ardata->first_file_filepos += (ardata->first_file_filepos) % 2; bfd_has_map (abfd) = TRUE; bfd_release (abfd, raw_armap); return TRUE; release_raw_armap: bfd_release (abfd, raw_armap); release_symdefs: bfd_release (abfd, ardata->symdefs); return FALSE; }
static bfd_boolean scan_960_mach (const bfd_arch_info_type *ap, const char *string) { unsigned long machine; int fail_because_not_80960 = FALSE; /* Look for the string i960 at the front of the string. */ if (strncasecmp ("i960", string, 4) == 0) { string += 4; /* i960 on it's own means core to us. */ if (* string == 0) return ap->mach == bfd_mach_i960_core; /* "i960:*" is valid, anything else is not. */ if (* string != ':') return FALSE; string ++; } /* In some bfds the cpu-id is written as "80960KA", "80960KB", "80960CA" or "80960MC". */ else if (CONST_STRNEQ (string, "80960")) { string += 5; /* Set this to TRUE here. If a correct matching postfix is detected below it will be reset to FALSE. */ fail_because_not_80960 = TRUE; } /* No match, can't be us. */ else return FALSE; if (* string == '\0') return FALSE; if (string[0] == 'c' && string[1] == 'o' && string[2] == 'r' && string[3] == 'e' && string[4] == '\0') machine = bfd_mach_i960_core; else if (strcasecmp (string, "ka_sa") == 0) machine = bfd_mach_i960_ka_sa; else if (strcasecmp (string, "kb_sb") == 0) machine = bfd_mach_i960_kb_sb; else if (string[1] == '\0' || string[2] != '\0') /* rest are 2-char. */ return FALSE; else if (string[0] == 'k' && string[1] == 'b') { machine = bfd_mach_i960_kb_sb; fail_because_not_80960 = FALSE; } else if (string[0] == 's' && string[1] == 'b') machine = bfd_mach_i960_kb_sb; else if (string[0] == 'm' && string[1] == 'c') { machine = bfd_mach_i960_mc; fail_because_not_80960 = FALSE; } else if (string[0] == 'x' && string[1] == 'a') machine = bfd_mach_i960_xa; else if (string[0] == 'c' && string[1] == 'a') { machine = bfd_mach_i960_ca; fail_because_not_80960 = FALSE; } else if (string[0] == 'k' && string[1] == 'a') { machine = bfd_mach_i960_ka_sa; fail_because_not_80960 = FALSE; } else if (string[0] == 's' && string[1] == 'a') machine = bfd_mach_i960_ka_sa; else if (string[0] == 'j' && string[1] == 'x') machine = bfd_mach_i960_jx; else if (string[0] == 'h' && string[1] == 'x') machine = bfd_mach_i960_hx; else return FALSE; if (fail_because_not_80960) return FALSE; if (machine == ap->mach) return TRUE; return FALSE; }
static unsigned int bfd_h8_disassemble (bfd_vma addr, disassemble_info *info, int mach) { /* Find the first entry in the table for this opcode. */ int regno[3] = { 0, 0, 0 }; int dispregno[3] = { 0, 0, 0 }; int cst[3] = { 0, 0, 0 }; int cstlen[3] = { 0, 0, 0 }; static bfd_boolean init = 0; const struct h8_instruction *qi; char const **pregnames = mach != 0 ? lregnames : wregnames; int status; unsigned int l; unsigned char data[MAX_CODE_NIBBLES]; void *stream = info->stream; fprintf_ftype outfn = info->fprintf_func; if (!init) { bfd_h8_disassemble_init (); init = 1; } status = info->read_memory_func (addr, data, 2, info); if (status != 0) { info->memory_error_func (status, addr, info); return -1; } for (l = 2; status == 0 && l < sizeof (data) / 2; l += 2) status = info->read_memory_func (addr + l, data + l, 2, info); /* Find the exact opcode/arg combo. */ for (qi = h8_instructions; qi->opcode->name; qi++) { const struct h8_opcode *q = qi->opcode; const op_type *nib = q->data.nib; unsigned int len = 0; while (1) { op_type looking_for = *nib; int thisnib = data[len / 2]; int opnr; thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib / 16) & 0xf); opnr = ((looking_for & OP3) == OP3 ? 2 : (looking_for & DST) == DST ? 1 : 0); if (looking_for < 16 && looking_for >= 0) { if (looking_for != thisnib) goto fail; } else { if ((int) looking_for & (int) B31) { if (!((thisnib & 0x8) != 0)) goto fail; looking_for = (op_type) ((int) looking_for & ~(int) B31); thisnib &= 0x7; } else if ((int) looking_for & (int) B30) { if (!((thisnib & 0x8) == 0)) goto fail; looking_for = (op_type) ((int) looking_for & ~(int) B30); } if ((int) looking_for & (int) B21) { if (!((thisnib & 0x4) != 0)) goto fail; looking_for = (op_type) ((int) looking_for & ~(int) B21); thisnib &= 0xb; } else if ((int) looking_for & (int) B20) { if (!((thisnib & 0x4) == 0)) goto fail; looking_for = (op_type) ((int) looking_for & ~(int) B20); } if ((int) looking_for & (int) B11) { if (!((thisnib & 0x2) != 0)) goto fail; looking_for = (op_type) ((int) looking_for & ~(int) B11); thisnib &= 0xd; } else if ((int) looking_for & (int) B10) { if (!((thisnib & 0x2) == 0)) goto fail; looking_for = (op_type) ((int) looking_for & ~(int) B10); } if ((int) looking_for & (int) B01) { if (!((thisnib & 0x1) != 0)) goto fail; looking_for = (op_type) ((int) looking_for & ~(int) B01); thisnib &= 0xe; } else if ((int) looking_for & (int) B00) { if (!((thisnib & 0x1) == 0)) goto fail; looking_for = (op_type) ((int) looking_for & ~(int) B00); } if (looking_for & IGNORE) { /* Hitachi has declared that IGNORE must be zero. */ if (thisnib != 0) goto fail; } else if ((looking_for & MODE) == DATA) { ; /* Skip embedded data. */ } else if ((looking_for & MODE) == DBIT) { /* Exclude adds/subs by looking at bit 0 and 2, and make sure the operand size, either w or l, matches by looking at bit 1. */ if ((looking_for & 7) != (thisnib & 7)) goto fail; cst[opnr] = (thisnib & 0x8) ? 2 : 1; } else if ((looking_for & MODE) == DISP || (looking_for & MODE) == ABS || (looking_for & MODE) == PCREL || (looking_for & MODE) == INDEXB || (looking_for & MODE) == INDEXW || (looking_for & MODE) == INDEXL) { extract_immediate (stream, looking_for, thisnib, data + len / 2, cst + opnr, cstlen + opnr, q); /* Even address == bra, odd == bra/s. */ if (q->how == O (O_BRAS, SB)) cst[opnr] -= 1; } else if ((looking_for & MODE) == REG || (looking_for & MODE) == LOWREG || (looking_for & MODE) == IND || (looking_for & MODE) == PREINC || (looking_for & MODE) == POSTINC || (looking_for & MODE) == PREDEC || (looking_for & MODE) == POSTDEC) { regno[opnr] = thisnib; } else if (looking_for & CTRL) /* Control Register. */ { thisnib &= 7; if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) || ((looking_for & MODE) == EXR && (thisnib != C_EXR)) || ((looking_for & MODE) == MACH && (thisnib != C_MACH)) || ((looking_for & MODE) == MACL && (thisnib != C_MACL)) || ((looking_for & MODE) == VBR && (thisnib != C_VBR)) || ((looking_for & MODE) == SBR && (thisnib != C_SBR))) goto fail; if (((looking_for & MODE) == CCR_EXR && (thisnib != C_CCR && thisnib != C_EXR)) || ((looking_for & MODE) == VBR_SBR && (thisnib != C_VBR && thisnib != C_SBR)) || ((looking_for & MODE) == MACREG && (thisnib != C_MACH && thisnib != C_MACL))) goto fail; if (((looking_for & MODE) == CC_EX_VB_SB && (thisnib != C_CCR && thisnib != C_EXR && thisnib != C_VBR && thisnib != C_SBR))) goto fail; regno[opnr] = thisnib; } else if ((looking_for & SIZE) == L_5) { cst[opnr] = data[len / 2] & 31; cstlen[opnr] = 5; } else if ((looking_for & SIZE) == L_4) { cst[opnr] = thisnib; cstlen[opnr] = 4; } else if ((looking_for & SIZE) == L_16 || (looking_for & SIZE) == L_16U) { cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2]; cstlen[opnr] = 16; } else if ((looking_for & MODE) == MEMIND) { cst[opnr] = data[1]; } else if ((looking_for & MODE) == VECIND) { cst[opnr] = data[1] & 0x7f; } else if ((looking_for & SIZE) == L_32) { int i = len / 2; cst[opnr] = ((data[i] << 24) | (data[i + 1] << 16) | (data[i + 2] << 8) | (data[i + 3])); cstlen[opnr] = 32; } else if ((looking_for & SIZE) == L_24) { int i = len / 2; cst[opnr] = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]); cstlen[opnr] = 24; } else if (looking_for & IGNORE) { ; } else if (looking_for & DISPREG) { dispregno[opnr] = thisnib & 7; } else if ((looking_for & MODE) == KBIT) { switch (thisnib) { case 9: cst[opnr] = 4; break; case 8: cst[opnr] = 2; break; case 0: cst[opnr] = 1; break; default: goto fail; } } else if ((looking_for & SIZE) == L_8) { cstlen[opnr] = 8; cst[opnr] = data[len / 2]; } else if ((looking_for & SIZE) == L_3 || (looking_for & SIZE) == L_3NZ) { cst[opnr] = thisnib & 0x7; if (cst[opnr] == 0 && (looking_for & SIZE) == L_3NZ) goto fail; } else if ((looking_for & SIZE) == L_2) { cstlen[opnr] = 2; cst[opnr] = thisnib & 0x3; } else if ((looking_for & MODE) == MACREG) { cst[opnr] = (thisnib == 3); } else if (looking_for == (op_type) E) { outfn (stream, "%s\t", q->name); /* Gross. Disgusting. */ if (strcmp (q->name, "ldm.l") == 0) { int count, high; count = (data[1] / 16) & 0x3; high = regno[1]; outfn (stream, "@sp+,er%d-er%d", high - count, high); return qi->length; } if (strcmp (q->name, "stm.l") == 0) { int count, low; count = (data[1] / 16) & 0x3; low = regno[0]; outfn (stream, "er%d-er%d,@-sp", low, low + count); return qi->length; } if (strcmp (q->name, "rte/l") == 0 || strcmp (q->name, "rts/l") == 0) { if (regno[0] == 0) outfn (stream, "er%d", regno[1]); else outfn (stream, "er%d-er%d", regno[1] - regno[0], regno[1]); return qi->length; } if (CONST_STRNEQ (q->name, "mova")) { const op_type *args = q->args.nib; if (args[1] == (op_type) E) { /* Short form. */ print_one_arg (info, addr, args[0], cst[0], cstlen[0], dispregno[0], regno[0], pregnames, qi->length); outfn (stream, ",er%d", dispregno[0]); } else { outfn (stream, "@(0x%x:%d,", cst[0], cstlen[0]); print_one_arg (info, addr, args[1], cst[1], cstlen[1], dispregno[1], regno[1], pregnames, qi->length); outfn (stream, ".%c),", (args[0] & MODE) == INDEXB ? 'b' : 'w'); print_one_arg (info, addr, args[2], cst[2], cstlen[2], dispregno[2], regno[2], pregnames, qi->length); } return qi->length; } /* Fill in the args. */ { const op_type *args = q->args.nib; int hadone = 0; int nargs; /* Special case handling for the adds and subs instructions since in H8 mode thay can only take the r0-r7 registers but in other (higher) modes they can take the er0-er7 registers as well. */ if (strcmp (qi->opcode->name, "adds") == 0 || strcmp (qi->opcode->name, "subs") == 0) { outfn (stream, "#%d,%s", cst[0], pregnames[regno[1] & 0x7]); return qi->length; } for (nargs = 0; nargs < 3 && args[nargs] != (op_type) E; nargs++) { int x = args[nargs]; if (hadone) outfn (stream, ","); print_one_arg (info, addr, x, cst[nargs], cstlen[nargs], dispregno[nargs], regno[nargs], pregnames, qi->length); hadone = 1; } } return qi->length; } else /* xgettext:c-format */ outfn (stream, _("Don't understand 0x%x \n"), looking_for); } len++; nib++; } fail: ; } /* Fell off the end. */ outfn (stream, ".word\tH'%x,H'%x", data[0], data[1]); return 2; }
static const bfd_target * osf_core_core_file_p (bfd *abfd) { int val; int i; char *secname; struct core_filehdr core_header; bfd_size_type amt; amt = sizeof core_header; val = bfd_bread (& core_header, amt, abfd); if (val != sizeof core_header) return NULL; if (! CONST_STRNEQ (core_header.magic, "Core")) return NULL; core_hdr (abfd) = (struct osf_core_struct *) bfd_zalloc (abfd, (bfd_size_type) sizeof (struct osf_core_struct)); if (!core_hdr (abfd)) return NULL; strncpy (core_command (abfd), core_header.name, MAXCOMLEN + 1); core_signal (abfd) = core_header.signo; for (i = 0; i < core_header.nscns; i++) { struct core_scnhdr core_scnhdr; flagword flags; amt = sizeof core_scnhdr; val = bfd_bread (& core_scnhdr, amt, abfd); if (val != sizeof core_scnhdr) break; /* Skip empty sections. */ if (core_scnhdr.size == 0 || core_scnhdr.scnptr == 0) continue; switch (core_scnhdr.scntype) { case SCNRGN: secname = ".data"; flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; break; case SCNSTACK: secname = ".stack"; flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; break; case SCNREGS: secname = ".reg"; flags = SEC_HAS_CONTENTS; break; default: (*_bfd_error_handler) (_("Unhandled OSF/1 core file section type %d\n"), core_scnhdr.scntype); continue; } if (!make_bfd_asection (abfd, secname, flags, (bfd_size_type) core_scnhdr.size, (bfd_vma) core_scnhdr.vaddr, (file_ptr) core_scnhdr.scnptr)) goto fail; } /* OK, we believe you. You're a core file (sure, sure). */ return abfd->xvec; fail: bfd_release (abfd, core_hdr (abfd)); core_hdr (abfd) = NULL; bfd_section_list_clear (abfd); return NULL; }