static void s_segm (int segm) { if (segm) { segmented_mode = 1; bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8001); } else { segmented_mode = 0; bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8002); } }
static void MY(set_arch_mach)(bfd *abfd, unsigned long machtype) { enum bfd_architecture arch; unsigned int machine; /* Determine the architecture and machine type of the object file. */ switch (machtype) { case M_MIPS1: arch = bfd_arch_mips; machine = bfd_mach_mips3000; break; case M_MIPS2: arch = bfd_arch_mips; machine = bfd_mach_mips4000; break; default: arch = bfd_arch_obscure; machine = 0; break; } bfd_set_arch_mach(abfd, arch, machine); }
static void xc16xlmode (int arg ATTRIBUTE_UNUSED) { if (stdoutput != NULL) if (!bfd_set_arch_mach (stdoutput, bfd_arch_xc16x, bfd_mach_xc16xl)) as_warn (_("could not set architecture and machine")); }
void NAME(lynx,set_arch_mach)(bfd *abfd, unsigned long machtype) { /* Determine the architecture and machine type of the object file: */ enum bfd_architecture arch; unsigned long machine; switch (machtype) { case M_UNKNOWN: /* Some Sun3s make magic numbers without cpu types in them, so we'll default to the 68000. */ arch = bfd_arch_m68k; machine = bfd_mach_m68000; break; case M_68010: case M_HP200: arch = bfd_arch_m68k; machine = bfd_mach_m68010; break; case M_68020: case M_HP300: arch = bfd_arch_m68k; machine = bfd_mach_m68020; break; case M_SPARC: arch = bfd_arch_sparc; machine = 0; break; case M_386: case M_386_DYNIX: arch = bfd_arch_i386; machine = 0; break; case M_29K: arch = bfd_arch_a29k; machine = 0; break; case M_HPUX: arch = bfd_arch_m68k; machine = 0; break; default: arch = bfd_arch_obscure; machine = 0; break; } bfd_set_arch_mach (abfd, arch, machine); }
bfd * create_gcore_bfd (char *filename) { bfd *obfd = gdb_bfd_openw (filename, default_gcore_target ()); if (!obfd) error (_("Failed to open '%s' for output."), filename); bfd_set_format (obfd, bfd_core); bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ()); return obfd; }
bfd_boolean bfd_arm_merge_machines (bfd *ibfd, bfd *obfd) { unsigned int in = bfd_get_mach (ibfd); unsigned int out = bfd_get_mach (obfd); /* If the output architecture is unknown, we now have a value to set. */ if (out == bfd_mach_arm_unknown) bfd_set_arch_mach (obfd, bfd_arch_arm, in); /* If the input architecture is unknown, then so must be the output architecture. */ else if (in == bfd_mach_arm_unknown) /* FIXME: We ought to have some way to override this on the command line. */ bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown); /* If they are the same then nothing needs to be done. */ else if (out == in) ; /* Otherwise the general principle that a earlier architecture can be linked with a later architecture to produce a binary that will execute on the later architecture. We fail however if we attempt to link a Cirrus EP9312 binary with an Intel XScale binary, since these architecture have co-processors which will not both be present on the same physical hardware. */ else if (in == bfd_mach_arm_ep9312 && (out == bfd_mach_arm_XScale || out == bfd_mach_arm_iWMMXt || out == bfd_mach_arm_iWMMXt2)) { _bfd_error_handler (_("\ error: %B is compiled for the EP9312, whereas %B is compiled for XScale"), ibfd, obfd); bfd_set_error (bfd_error_wrong_format); return FALSE; }
void md_begin (void) { int count; const bexkat1_opc_info_t *opcode; opcode_hash_control = hash_new(); bfd_set_arch_mach(stdoutput, TARGET_ARCH, 0); opcode = bexkat1_opc_info; for (count=0; count < bexkat1_opc_count; count++) { hash_insert(opcode_hash_control, opcode->name, (char *)opcode); opcode++; } }
static bfd_boolean elf32_sparc_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) { bfd *obfd = info->output_bfd; bfd_boolean error; unsigned long ibfd_mach; /* FIXME: This should not be static. */ static unsigned long previous_ibfd_e_flags = (unsigned long) -1; if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) return TRUE; error = FALSE; ibfd_mach = bfd_get_mach (ibfd); if (bfd_mach_sparc_64bit_p (ibfd_mach)) { error = TRUE; _bfd_error_handler (_("%B: compiled for a 64 bit system and target is 32 bit"), ibfd); } else if ((ibfd->flags & DYNAMIC) == 0) { if (bfd_get_mach (obfd) < ibfd_mach) bfd_set_arch_mach (obfd, bfd_arch_sparc, ibfd_mach); } if (((elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA) != previous_ibfd_e_flags) && previous_ibfd_e_flags != (unsigned long) -1) { _bfd_error_handler (_("%B: linking little endian files with big endian files"), ibfd); error = TRUE; } previous_ibfd_e_flags = elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA; if (error) { bfd_set_error (bfd_error_bad_value); return FALSE; } return _bfd_sparc_elf_merge_private_bfd_data (ibfd, info); }
static const bfd_target * os9k_callback (bfd *abfd) { struct internal_exec *execp = exec_hdr (abfd); unsigned long bss_start; /* Architecture and machine type. */ bfd_set_arch_mach (abfd, bfd_arch_i386, 0); /* The positions of the string table and symbol table. */ obj_str_filepos (abfd) = 0; obj_sym_filepos (abfd) = 0; /* The alignments of the sections. */ obj_textsec (abfd)->alignment_power = execp->a_talign; obj_datasec (abfd)->alignment_power = execp->a_dalign; obj_bsssec (abfd)->alignment_power = execp->a_balign; /* The starting addresses of the sections. */ obj_textsec (abfd)->vma = execp->a_tload; obj_datasec (abfd)->vma = execp->a_dload; /* And reload the sizes, since the aout module zaps them. */ obj_textsec (abfd)->size = execp->a_text; bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section. */ obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign); /* The file positions of the sections. */ obj_textsec (abfd)->filepos = execp->a_entry; obj_datasec (abfd)->filepos = execp->a_dload; /* The file positions of the relocation info *** obj_textsec (abfd)->rel_filepos = N_TROFF(*execp); obj_datasec (abfd)->rel_filepos = N_DROFF(*execp); */ adata (abfd).page_size = 1; /* Not applicable. */ adata (abfd).segment_size = 1;/* Not applicable. */ adata (abfd).exec_bytes_size = MHCOM_BYTES_SIZE; return abfd->xvec; }
void output_file_create (char *name) { if (name[0] == '-' && name[1] == '\0') as_fatal (_("can't open a bfd on stdout %s"), name); else if (!(stdoutput = bfd_openw (name, TARGET_FORMAT))) { bfd_error_type err = bfd_get_error (); if (err == bfd_error_invalid_target) as_fatal (_("selected target format '%s' unknown"), TARGET_FORMAT); else as_fatal (_("can't create %s: %s"), name, bfd_errmsg (err)); } bfd_set_format (stdoutput, bfd_object); bfd_set_arch_mach (stdoutput, TARGET_ARCH, TARGET_MACH); if (flag_traditional_format) stdoutput->flags |= BFD_TRADITIONAL_FORMAT; }
void md_begin (void) { int count; const moxie_opc_info_t *opcode; opcode_hash_control = hash_new (); /* Insert names into hash table. */ for (count = 0, opcode = moxie_form1_opc_info; count++ < 64; opcode++) hash_insert (opcode_hash_control, opcode->name, (char *) opcode); for (count = 0, opcode = moxie_form2_opc_info; count++ < 4; opcode++) hash_insert (opcode_hash_control, opcode->name, (char *) opcode); for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++) hash_insert (opcode_hash_control, opcode->name, (char *) opcode); target_big_endian = TARGET_BYTES_BIG_ENDIAN; bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0); }
static const bfd_target * aout_adobe_callback (bfd *abfd) { struct internal_exec *execp = exec_hdr (abfd); asection *sect; struct external_segdesc ext[1]; char *section_name; char try_again[30]; /* Name and number. */ char *newname; int trynum; flagword flags; /* Architecture and machine type -- unknown in this format. */ bfd_set_arch_mach (abfd, bfd_arch_unknown, 0L); /* The positions of the string table and symbol table. */ obj_str_filepos (abfd) = N_STROFF (*execp); obj_sym_filepos (abfd) = N_SYMOFF (*execp); /* Suck up the section information from the file, one section at a time. */ for (;;) { bfd_size_type amt = sizeof (*ext); if (bfd_bread ( ext, amt, abfd) != amt) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_wrong_format); return NULL; } switch (ext->e_type[0]) { case N_TEXT: section_name = ".text"; flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS; break; case N_DATA: section_name = ".data"; flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS; break; case N_BSS: section_name = ".bss"; flags = SEC_DATA | SEC_HAS_CONTENTS; break; case 0: goto no_more_sections; default: (*_bfd_error_handler) (_("%B: Unknown section type in a.out.adobe file: %x\n"), abfd, ext->e_type[0]); goto no_more_sections; } /* First one is called ".text" or whatever; subsequent ones are ".text1", ".text2", ... */ bfd_set_error (bfd_error_no_error); sect = bfd_make_section_with_flags (abfd, section_name, flags); trynum = 0; while (!sect) { if (bfd_get_error () != bfd_error_no_error) /* Some other error -- slide into the sunset. */ return NULL; sprintf (try_again, "%s%d", section_name, ++trynum); sect = bfd_make_section_with_flags (abfd, try_again, flags); } /* Fix the name, if it is a sprintf'd name. */ if (sect->name == try_again) { amt = strlen (sect->name); newname = bfd_zalloc (abfd, amt); if (newname == NULL) return NULL; strcpy (newname, sect->name); sect->name = newname; } /* Assumed big-endian. */ sect->size = ((ext->e_size[0] << 8) | ext->e_size[1] << 8 | ext->e_size[2]); sect->vma = H_GET_32 (abfd, ext->e_virtbase); sect->filepos = H_GET_32 (abfd, ext->e_filebase); /* FIXME XXX alignment? */ /* Set relocation information for first section of each type. */ if (trynum == 0) switch (ext->e_type[0]) { case N_TEXT: sect->rel_filepos = N_TRELOFF (*execp); sect->reloc_count = execp->a_trsize; break; case N_DATA: sect->rel_filepos = N_DRELOFF (*execp); sect->reloc_count = execp->a_drsize; break; default: break; } } no_more_sections: adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external); adata (abfd).symbol_entry_size = sizeof (struct external_nlist); adata (abfd).page_size = 1; /* Not applicable. */ adata (abfd).segment_size = 1; /* Not applicable. */ adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; return abfd->xvec; }
static void gcore_command (char *args, int from_tty) { struct cleanup *old_chain; char *corefilename, corefilename_buffer[40]; asection *note_sec = NULL; bfd *obfd; void *note_data = NULL; int note_size = 0; /* No use generating a corefile without a target process. */ if (!target_has_execution) noprocess (); if (args && *args) corefilename = args; else { /* Default corefile name is "core.PID". */ sprintf (corefilename_buffer, "core.%d", PIDGET (inferior_ptid)); corefilename = corefilename_buffer; } if (info_verbose) fprintf_filtered (gdb_stdout, "Opening corefile '%s' for output.\n", corefilename); /* Open the output file. */ obfd = bfd_openw (corefilename, default_gcore_target ()); if (!obfd) error (_("Failed to open '%s' for output."), corefilename); /* Need a cleanup that will close the file (FIXME: delete it?). */ old_chain = make_cleanup_bfd_close (obfd); bfd_set_format (obfd, bfd_core); bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ()); /* An external target method must build the notes section. */ note_data = target_make_corefile_notes (obfd, ¬e_size); /* Create the note section. */ if (note_data != NULL && note_size != 0) { note_sec = bfd_make_section_anyway_with_flags (obfd, "note0", SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC); if (note_sec == NULL) error (_("Failed to create 'note' section for corefile: %s"), bfd_errmsg (bfd_get_error ())); bfd_set_section_vma (obfd, note_sec, 0); bfd_set_section_alignment (obfd, note_sec, 0); bfd_set_section_size (obfd, note_sec, note_size); } /* Now create the memory/load sections. */ if (gcore_memory_sections (obfd) == 0) error (_("gcore: failed to get corefile memory sections from target.")); /* Write out the contents of the note section. */ if (note_data != NULL && note_size != 0) { if (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size)) warning (_("writing note section (%s)"), bfd_errmsg (bfd_get_error ())); } /* Succeeded. */ fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename); /* Clean-ups will close the output file and free malloc memory. */ do_cleanups (old_chain); return; }
static void emit_so_bfd(const Chunk *base, uint64_t textOffs, uint64_t textLen, std::vector<MethBlock> &blocks, std::vector<DebugInfo> &debugInfos) { bfd_init(); bfd *abfd = bfd_openw("jit.o", #ifdef __MACH__ "mach-o-i386" #else "elf32-i386" #endif ) ; bfd_set_format(abfd, bfd_object); #ifdef __MACH__ bfd_set_arch_mach(abfd, bfd_arch_i386, bfd_mach_i386_i386); #else bfd_set_arch_mach(abfd, bfd_arch_i386, bfd_mach_i386_i386); #endif asection *textSection = bfd_make_section(abfd, ".text"); bfd_set_section_flags( abfd, textSection, SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_HAS_CONTENTS); #ifdef __MACH__ bfd_set_section_size(abfd, textSection, textLen); // for mach-o, the .o we generate is linked into a .dylib // so just set the alignment to make sure things end up // in the right place after link textSection->alignment_power = l2(textOffs); static const uint64_t textAdj = 0; #else bfd_set_section_size(abfd, textSection, textLen + textOffs); // for linux (and oprofile) the generated object is used // directly, so just offset the symbols uint64_t textAdj = textOffs; #endif asymbol **symbols = (asymbol **) malloc( sizeof(asymbol *) * (6 + blocks.size())); uint64_t start = ((uint64_t *) base->data)[0] + textOffs; int n = 0; std::map<std::string, int> namesSeen; std::vector<MethBlock>::const_iterator i, e; symbols[n++] = make_glob_symbol(abfd, "__jitStart", textSection, textAdj); symbols[n++] = make_glob_symbol(abfd, "_jitStart", textSection, textAdj); for (i = blocks.begin(), e = blocks.end(); i != e; i++, n++) { std::string name = i->name(); int seen = namesSeen[name]++; if (seen) { char buf[16]; sprintf(buf, " (%d)", seen); name += buf; } symbols[n] = make_glob_symbol(abfd, name.c_str(), textSection, i->start() - start + textAdj); } symbols[n++] = make_glob_symbol(abfd, "__jitUnused", textSection, blocks.back().end() - start + textAdj); symbols[n++] = make_glob_symbol(abfd, "_jitUnused", textSection, blocks.back().end() - start + textAdj); symbols[n++] = make_glob_symbol(abfd, "__jitEnd", textSection, textLen + textAdj); symbols[n++] = make_glob_symbol(abfd, "_jitEnd", textSection, textLen + textAdj); bfd_set_symtab(abfd, symbols, n); for (i = blocks.begin(), e = blocks.end(); i != e; i++, n++) if (i->codeBytes()) bfd_set_section_contents(abfd, textSection, i->codeBytes(), i->start() - start, i->codeLen()); bfd_close(abfd); for (int n = 0; n < blocks.size(); n++) free((void *) symbols[n]->name); free(symbols); }
main (int argc, char **argv) { bfd *ibfd, *obfd; asection *p; static asymbol **osympp, **delsympp; long symsize, symcount, delsymcount; int i; int c; int idx; struct add_reloc_struct *new_reloc; struct change_reloc_struct *new_change; struct delete_reloc_struct *new_delete; struct modify_byte_struct *new_modify; struct globalize_sym_struct *new_globalize; while ((c = getopt (argc, argv, "a:d:c:m:G:")) != -1) { switch (c) { case 'a': /* check to see if we have two args: name and loc */ if ((index(optarg, ',') == NULL) || (index(optarg, ',') != rindex(optarg, ','))) { fprintf(stderr, "usage: -a argument should be <symbolname>,<location>, not \"%s\"\n", optarg); exit(1); } /* record the add reloc command in the global array */ new_reloc = (add_reloc_struct *)malloc(sizeof(add_reloc_struct)); new_reloc->symbol_name = strndup(optarg, (index(optarg, ',') - optarg)); new_reloc->loc = strtol(index(optarg, ',') + 1, NULL, 0); if (errno == EINVAL) { fprintf(stderr, "the value %s is not a valid location for the add command\n", index(optarg, ',') + 1); exit(1); } new_reloc->next = additional_relocs; additional_relocs = new_reloc; break; case 'c': /* check to see if we have two args */ if ((index(optarg, ',') == NULL) || (index(optarg, ',') != rindex(optarg, ','))) { fprintf(stderr, "usage: -c argument should be <symbolname>,<symbolname>, not \"%s\"\n", optarg); exit(1); } new_change = (change_reloc_struct *)malloc(sizeof(change_reloc_struct)); new_change->old_symbol_name = strndup(optarg, strlen(optarg) - strlen(index(optarg, ','))); new_change->new_symbol_name = strdup(index(optarg, ',') + 1); new_change->next = change_relocs; change_relocs = new_change; break; case 'd': new_delete = (delete_reloc_struct *)malloc(sizeof(delete_reloc_struct)); new_delete->symbol_name = strdup(optarg); new_delete->next = delete_relocs; delete_relocs = new_delete; break; case 'm': if ((index(optarg, '=') == NULL) || (index(optarg, '=') != rindex(optarg, '='))) { fprintf(stderr, "usage: -m argument should be <location>=<value>, not \"%s\"\n", optarg); exit(1); } new_modify = (modify_byte_struct *)malloc(sizeof(modify_byte_struct)); new_modify->location = strtol(optarg, NULL, 0); new_modify->value = strtol(index(optarg, '=') + 1, NULL, 0); if (new_modify->value > 0xff) { fprintf(stderr, "requested modify value %lx for location %lx exceeds 0xff\n", new_modify->value, new_modify->location); exit(1); } new_modify->next = modify_bytes; modify_bytes = new_modify; break; case 'G': new_globalize = (globalize_sym_struct *)malloc(sizeof(globalize_sym_struct)); new_globalize->symbol_name = strdup(optarg); new_globalize->next = globalize_syms; globalize_syms = new_globalize; break; default: fprintf(stderr, "unrecognized argument character |%c|\n", c); } } if ((argc - optind) != 2) { fprintf(stderr, "usage: fixup_relocs [-a newsymbol,location] [-c oldsymbol,newsymbol] [-d symbol] infile.o outfile.o\n"); exit(1); } ibfd = bfd_openr(argv[optind], NULL); if (ibfd == NULL) { bfd_perror("while opening input object file"); exit(1); } /* if I don't do "check_format", there's no data in the bfd object. wtf? */ if (!bfd_check_format(ibfd, bfd_object)) { fprintf(stderr, "input file %s seems to NOT be an object file! exiting.\n", argv[optind]); exit(1); } obfd = bfd_openw(argv[optind+1], bfd_get_target(ibfd)); if (obfd == NULL) { bfd_perror("while opening output object file"); exit(1); } if (!bfd_set_format(obfd, bfd_get_format(ibfd))) { bfd_perror("while setting output object file format"); } /* copy a bunch of necessary global stuff */ bfd_set_start_address(obfd, bfd_get_start_address(ibfd)); bfd_set_file_flags(obfd, bfd_get_file_flags(ibfd)); bfd_set_arch_mach(obfd, bfd_get_arch(ibfd), bfd_get_mach(ibfd)); /* BOZO objcopy sets format again at this point. why? */ bfd_map_over_sections (ibfd, setup_section, obfd); setup_bfd_headers (ibfd, obfd); /* Symbol filtering must happen after the output sections have been created, but before their contents are set. */ symsize = bfd_get_symtab_upper_bound (ibfd); if (symsize < 0) { fprintf(stderr, "problem processing %s\n", bfd_get_filename (ibfd)); return FALSE; } /* count the added relocations so we can put extra space in the output symbol table for them */ int reloc_add_cnt, reloc_delete_cnt; reloc_add_cnt = 0; reloc_delete_cnt = 0; for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) { reloc_add_cnt++; } /* the "change" symbols might also not be in the symbol table yet */ for (new_change = change_relocs; new_change != NULL; new_change = new_change->next) { reloc_add_cnt++; /* the old symbol may be deleted, also */ reloc_delete_cnt++; } for (new_delete = delete_relocs; new_delete != NULL; new_delete = new_delete->next) { reloc_delete_cnt++; } /* filter symbol table in two steps: */ /* 1) move symbols bound for deletion to the end of the output symbol table array */ /* 2) truncate the table at the first of those */ /* this makes it possible to do the reloc processing with the symbol table intact, */ /* and remove the deleted symbols afterwards, without corrupting the reloc data structures */ isympp = malloc (symsize); osympp = malloc (symsize + reloc_add_cnt * sizeof(asymbol *)); delsympp = malloc (reloc_delete_cnt * sizeof(asymbol *)); symcount = bfd_canonicalize_symtab (ibfd, isympp); if (symcount < 0) { fprintf(stderr, "problem processing %s\n", bfd_get_filename (ibfd)); return FALSE; } /* remove any undefined symbols whose relocation entries were deleted or changed */ int osym_idx, delsym_idx; osym_idx = delsym_idx = 0; delsymcount = 0; for (i = 0; i < symcount; i++) { if ((is_delete_reloc(bfd_asymbol_name(isympp[i]), delete_relocs) || (find_change_reloc(bfd_asymbol_name(isympp[i]), change_relocs) != NULL)) && (isympp[i]->section != NULL) && (strcmp(isympp[i]->section->name, BFD_UND_SECTION_NAME) == 0)) { delsympp[delsym_idx++] = isympp[i]; } else { if (is_globalize_sym(bfd_asymbol_name(isympp[i]), globalize_syms)) { isympp[i]->flags = BSF_GLOBAL; } osympp[osym_idx++] = isympp[i]; } } symcount = osym_idx; delsymcount = delsym_idx; osympp[symcount] = NULL; /* add the symbols for additional relocs to the table */ int added_symbol_cnt = 0; for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) { if (find_symbol(osympp, new_reloc->symbol_name) < 0) { /* not yet present, so add it */ asymbol *new_sym; new_sym = bfd_make_empty_symbol(obfd); new_sym->name = strdup(new_reloc->symbol_name); new_sym->section = bfd_get_section_by_name (obfd, ".text"); new_sym->value = new_reloc->loc; new_sym->flags = BSF_GLOBAL; osympp[symcount + added_symbol_cnt++] = new_sym; osympp[symcount + added_symbol_cnt] = NULL; } } /* do the same for changed relocs */ for (new_change = change_relocs; new_change != NULL; new_change = new_change->next) { if (find_symbol(osympp, new_change->new_symbol_name) < 0) { /* not yet present, so add it */ /* since this is a name change, we will reuse the existing address (value field of reloc) */ int old_symbol_idx; if ((old_symbol_idx = find_symbol(isympp, new_change->old_symbol_name)) < 0) { fprintf(stderr, "change command old symbol name %s not found in symbol table! Exiting.\n", new_change->old_symbol_name); exit(1); } asymbol *new_sym; new_sym = bfd_make_empty_symbol(obfd); new_sym->name = strdup(new_change->new_symbol_name); new_sym->section = bfd_und_section_ptr; new_sym->value = isympp[old_symbol_idx]->value; new_sym->flags = BSF_GLOBAL; fprintf(stderr, "adding new symbol %s for change reloc command\n", new_sym->name); osympp[symcount + added_symbol_cnt++] = new_sym; osympp[symcount + added_symbol_cnt] = NULL; } } /* append the soon-to-be deleted symbols to the end of the output symbol table */ for (i = 0; i < delsymcount; i++) { osympp[symcount + added_symbol_cnt + i] = delsympp[i]; } osympp[symcount + added_symbol_cnt + delsymcount] = NULL; bfd_set_symtab (obfd, osympp, symcount + added_symbol_cnt + delsymcount); /* This has to happen after the symbol table has been set. */ bfd_map_over_sections (ibfd, copy_section_relocs_edit, obfd); /* now truncate the symbol table to eliminate the deleted symbols */ osympp[symcount + added_symbol_cnt] = NULL; bfd_set_symtab (obfd, osympp, symcount + added_symbol_cnt); /* now that we've set the relocs and cleaned the symtab, can call this */ bfd_map_over_sections (ibfd, copy_section_data, obfd); bfd_close(obfd); bfd_close(ibfd); return 0; }