void plugin_maybe_claim (struct ld_plugin_input_file *file, lang_input_statement_type *entry) { int claimed = 0; /* We create a dummy BFD, initially empty, to house whatever symbols the plugin may want to add. */ file->handle = plugin_get_ir_dummy_bfd (entry->the_bfd->filename, entry->the_bfd); if (plugin_call_claim_file (file, &claimed)) einfo (_("%P%F: %s: plugin reported error claiming file\n"), plugin_error_plugin ()); /* fd belongs to us, not the plugin; but we don't need it. */ close (file->fd); if (claimed) { /* Discard the real file's BFD and substitute the dummy one. */ /* BFD archive handling caches elements so we can't call bfd_close for archives. */ if (entry->the_bfd->my_archive == NULL) bfd_close (entry->the_bfd); entry->the_bfd = file->handle; entry->flags.claimed = TRUE; bfd_make_readable (entry->the_bfd); } else { /* If plugin didn't claim the file, we don't need the dummy bfd. Can't avoid speculatively creating it, alas. */ bfd_close_all_done (file->handle); entry->flags.claimed = FALSE; } }
~bfd_cache() { if (abfd) { bfd_cache_close(abfd); bfd_free_cached_info(abfd); bfd_close_all_done(abfd); } }
void objdump(const char *path) { bfd_init(); bfd *abfd = bfd_openr(path, NULL); if (abfd == NULL) errx(1, bfd_errmsg(bfd_get_error())); if (!bfd_check_format(abfd, bfd_object)) { bfd_close_all_done(abfd); errx(1, "File is not a valid object file."); } printf("%s: file format %s\n", path, bfd_get_target(abfd)); printf("architecture: %s, flags: 0x%08x\n", bfd_printable_arch_mach(bfd_get_arch(abfd), bfd_get_mach(abfd)), abfd->flags); printf("start address 0x%016lx", bfd_get_start_address(abfd)); printf("\n"); printf("Sections:\n"); printf("Idx Name Size VMA LMA File off Algn\n"); printf(" Flags Content\n"); object_stats stats = { FALSE, FALSE }; bfd_map_over_sections(abfd, (void (*)(bfd *, asection *, void *))print_section, &stats); if (stats.contains_hello && stats.contains_world) printf("\nThis file might be a hello world program!\n"); bfd_close(abfd); }
/** * Close BFD context, releasing its resources and nullifying its pointer. */ static void bfd_util_close_context_null(bfd_ctx_t **bc_ptr) { bfd_ctx_t *bc = *bc_ptr; if (bc != NULL) { mutex_lock(&bc->lock); /* Not a fast mutex since we'll destroy it */ if (bc->symbols != NULL) free(bc->symbols); /* Not xfree(): created by the bfd library */ /* * We use bfd_close_all_done() and not bfd_close() because the latter * causes a SIGSEGV now that we are using bfd_fdopenr(). The fault * occurs in some part trying to write changes to the file... * * Since the file is opened as read-only and we don't expect any * write operation, using bfd_close_all_done() is a viable workaround * for this BFD library bug. */ if (bc->handle != NULL) bfd_close_all_done(bc->handle); /* Workaround for BFD bug */ symbols_free_null(&bc->text_symbols); bc->magic = 0; mutex_destroy(&bc->lock); xfree(bc); *bc_ptr = NULL; } }
void asmir_close(asm_program_t *p) { // FIXME: free sections bfd_close_all_done(p->abfd); free(p); vx_FreeAll(); }
static void arch_bfdDestroy(bfd_t * bfdParams) { if (bfdParams->syms) { free(bfdParams->syms); } if (bfdParams->bfdh) { bfd_close_all_done(bfdParams->bfdh); } }
trap::ExecLoader::~ExecLoader() { if (this->exec_image != NULL) { if (!bfd_close_all_done(this->exec_image)) { //An Error has occurred; lets see what it is THROW_ERROR("Cannot close binary parser: " << bfd_errmsg(bfd_get_error()) << '.'); } } if (this->program_data != NULL) { delete [] this->program_data; } } // ExecLoader::~ExecLoader()
static struct bfd* new_bfd_internal( const char* filename, int arch, int machine ) { char** matching; enum bfd_architecture _arch = (enum bfd_architecture) arch; struct bfd* p = bfd_openr( filename, DEFAULT_TARGET ); const bfd_arch_info_type* info; if ( !p ) error_exit( "failure: bfd_openr" ); if ( _arch == bfd_arch_unknown ) { if ( bfd_check_format( p, bfd_archive ) ) { // TODO: add archive handling code bfd_close_all_done( p ); error_exit( "currently not supported." ); } if ( bfd_check_format_matches( p, bfd_object, &matching ) ) { return p; } if ( bfd_get_error() == bfd_error_file_ambiguously_recognized ) { bfd_close_all_done( p ); error_exit( "file format is ambiguosly matched" ); } if ( bfd_get_error() != bfd_error_file_not_recognized ) { bfd_close_all_done( p ); error_exit( "file is not recognized" ); } if ( bfd_check_format_matches( p, bfd_core, &matching ) ) { return p; } error_exit( "failed to load the given file" ); return NULL; /* this will never be called */ } else { info = bfd_lookup_arch( _arch, machine ); if ( !info ) error_exit( "failed to lookup archicture" ); bfd_set_arch_info( p, info ); return p; } }
static bfd * initialize_bfd(const char *filename) { bfd * abfd; char **matching; char *target = "i686-pc-linux-gnu"; bfd_init(); if(!bfd_set_default_target(target)) { fprintf(stderr, "initialize_bfd: couldn't set default bfd target\n"); return NULL; } abfd = bfd_openr(filename, target); if(abfd == NULL) { fprintf(stderr, "initialize_bfd: cannot open %s\n", filename); return NULL; } if (bfd_check_format (abfd, bfd_archive)) { fprintf(stderr, "initalize_bfd: archive files not supported\n"); bfd_close_all_done(abfd); return NULL; } /* if(!bfd_check_format_matches(abfd, bfd_object, &matching)) { */ if( (!bfd_check_format_matches(abfd, bfd_object, &matching)) && (!bfd_check_format_matches(abfd, bfd_core, &matching)) ) { fprintf(stderr, "initialize_bfd: bfd_check_format_matches failed\n"); bfd_close_all_done(abfd); return NULL; } return abfd; }
void free_asm_program(asm_program_t *p) { for(map<address_t, section_t *>::const_iterator it = p->sections.begin(); it != p->sections.end(); it++) { // FIXME: is this all that's required to free sections? free(it->second); } for(map<address_t, asm_function_t *>::const_iterator it = p->functions.begin(); it != p->functions.end(); it++) { free_asm_function(it->second); } bfd_close_all_done(p->abfd); delete p; }
void delete_bfd( bhp _p ) { bh* p = (bh*) _p; if ( p->disasp ) { free( p->disasp->buffer ); free( p->disasp ); p->disasp = NULL; } if ( bfd_close_all_done( p->bfdp ) == TRUE ) return; else error_exit( "failed to close with bfd_close_all_done" ); free( p ); p = NULL; }
void arch_bfdDisasm(pid_t pid, uint8_t * mem, size_t size, char *instr) { while (pthread_mutex_lock(&arch_bfd_mutex)) ; bfd_init(); char fname[PATH_MAX]; snprintf(fname, sizeof(fname), "/proc/%d/exe", pid); bfd *bfdh = bfd_openr(fname, NULL); if (bfdh == NULL) { LOGMSG(l_WARN, "bfd_openr('/proc/%d/exe') failed", pid); goto out; } if (!bfd_check_format(bfdh, bfd_object)) { LOGMSG(l_WARN, "bfd_check_format() failed"); goto out; } disassembler_ftype disassemble = disassembler(bfdh); if (disassemble == NULL) { LOGMSG(l_WARN, "disassembler() failed"); goto out; } struct disassemble_info info; init_disassemble_info(&info, instr, arch_bfdFPrintF); info.arch = bfd_get_arch(bfdh); info.mach = bfd_get_mach(bfdh); info.buffer = mem; info.buffer_length = size; info.section = NULL; info.endian = bfd_little_endian(bfdh) ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG; disassemble_init_for_target(&info); strcpy(instr, ""); if (disassemble(0, &info) <= 0) { snprintf(instr, _HF_INSTR_SZ, "[DIS-ASM_FAILURE]"); } out: bfdh ? bfd_close_all_done(bfdh) : 0; while (pthread_mutex_unlock(&arch_bfd_mutex)) ; return; }
void replace_hello(const char *input_path, const char *output_path) { bfd_init(); bfd *ibfd = bfd_openr(input_path, NULL); if (ibfd == NULL) errx(1, bfd_errmsg(bfd_get_error())); if (!bfd_check_format(ibfd, bfd_object)) { bfd_close_all_done(ibfd); errx(1, "Input file is not a valid object file."); } bfd *obfd = bfd_openw(output_path, bfd_get_target(ibfd)); if (obfd == NULL) { bfd_close_all_done(ibfd); errx(1, bfd_errmsg(bfd_get_error())); } if (!bfd_set_format(obfd, bfd_get_format(ibfd))) { bfd_close_all_done(ibfd); bfd_close_all_done(obfd); errx(1, "Setting obfd format failed: %s\n", bfd_errmsg(bfd_get_error())); } bfd_set_arch_info(obfd, bfd_get_arch_info(ibfd)); // Create sections for .data asection *section = bfd_get_section_by_name(ibfd, ".data"); while (section != NULL) { if (section->flags & SEC_HAS_CONTENTS) { char *section_contents = (char *)malloc(section->size); bfd_get_section_contents(ibfd, section, section_contents, 0, section->size); char *hello_pos = (char *)memmem(section_contents, section->size, "hello", 5); if (hello_pos != NULL) { if (bfd_make_section_anyway_with_flags(obfd, ".data", section->flags) == NULL) { free(section_contents); bfd_close_all_done(ibfd); bfd_close_all_done(obfd); errx(1, bfd_errmsg(bfd_get_error())); } } free(section_contents); } section = bfd_get_next_section_by_name(ibfd, section); } asection *comment_section = bfd_make_section_anyway_with_flags(obfd, ".comment.my_objcopy", SEC_HAS_CONTENTS); if (comment_section == NULL) { bfd_close_all_done(ibfd); bfd_close_all_done(obfd); errx(1, bfd_errmsg(bfd_get_error())); } if (!bfd_set_section_size(obfd, comment_section, 3)) { bfd_close_all_done(ibfd); bfd_close_all_done(obfd); errx(1, bfd_errmsg(bfd_get_error())); } if (!bfd_set_section_contents(obfd, comment_section, "moo", 0, 3)) { bfd_close_all_done(ibfd); bfd_close_all_done(obfd); errx(1, bfd_errmsg(bfd_get_error())); } // section = bfd_get_section_by_name(ibfd, ".data"); // asection *osection = bfd_get_section_by_name(obfd, ".data"); // if (osection == NULL) { // bfd_close_all_done(ibfd); // bfd_close_all_done(obfd); // errx(1, bfd_errmsg(bfd_get_error())); // } // while (section != NULL) { // if (section->flags & SEC_HAS_CONTENTS) { // char *section_contents = (char *)malloc(section->size); // bfd_get_section_contents(ibfd, section, section_contents, 0, section->size); // // char *hello_pos = (char *)memmem(section_contents, section->size, "hello", 5); // if (hello_pos != NULL) { // hello_pos[1] = 'o'; // hello_pos[4] = 'a'; // if (bfd_set_section_contents(obfd, osection, section_contents, 0, section->size)) { // free(section_contents); // bfd_close_all_done(ibfd); // bfd_close_all_done(obfd); // errx(1, bfd_errmsg(bfd_get_error())); // } // } // // free(section_contents); // osection = bfd_get_next_section_by_name(obfd, osection); // } // // section = bfd_get_next_section_by_name(ibfd, section); // } if (!bfd_close(obfd)) errx(1, "Closing obfd failed: %s\n", bfd_errmsg(bfd_get_error())); if (!bfd_close(ibfd)) errx(1, "Closing ibfd failed: %s\n", bfd_errmsg(bfd_get_error())); }
static const bfd_target * plugin_object_p (bfd *ibfd) { int claimed; plugin_input_file_t *input; struct ld_plugin_input_file file; bfd *abfd; /* Don't try the dummy object file. */ if ((ibfd->flags & BFD_PLUGIN) != 0) return NULL; if (ibfd->plugin_format != bfd_plugin_unknown) { if (ibfd->plugin_format == bfd_plugin_yes) return ibfd->plugin_dummy_bfd->xvec; else return NULL; } /* We create a dummy BFD, initially empty, to house whatever symbols the plugin may want to add. */ abfd = plugin_get_ir_dummy_bfd (ibfd->filename, ibfd); input = bfd_alloc (abfd, sizeof (*input)); if (input == NULL) einfo (_("%P%F: plugin failed to allocate memory for input: %s\n"), bfd_get_error ()); if (!bfd_plugin_open_input (ibfd, &file)) return NULL; if (file.name == ibfd->filename) { /* We must copy filename attached to ibfd if it is not an archive member since it may be freed by bfd_close below. */ file.name = plugin_strdup (abfd, file.name); } file.handle = input; /* The plugin API expects that the file descriptor won't be closed and reused as done by the bfd file cache. So dup one. */ file.fd = dup (file.fd); if (file.fd < 0) return NULL; input->abfd = abfd; input->view_buffer.addr = NULL; input->view_buffer.filesize = 0; input->view_buffer.offset = 0; input->fd = file.fd; input->use_mmap = FALSE; input->offset = file.offset; input->filesize = file.filesize; input->name = plugin_strdup (abfd, ibfd->filename); claimed = 0; if (plugin_call_claim_file (&file, &claimed)) einfo (_("%P%F: %s: plugin reported error claiming file\n"), plugin_error_plugin ()); if (input->fd != -1 && !bfd_plugin_target_p (ibfd->xvec)) { /* FIXME: fd belongs to us, not the plugin. GCC plugin, which doesn't need fd after plugin_call_claim_file, doesn't use BFD plugin target vector. Since GCC plugin doesn't call release_input_file, we close it here. LLVM plugin, which needs fd after plugin_call_claim_file and calls release_input_file after it is done, uses BFD plugin target vector. This scheme doesn't work when a plugin needs fd and doesn't use BFD plugin target vector neither. */ close (input->fd); input->fd = -1; } if (claimed) { ibfd->plugin_format = bfd_plugin_yes; ibfd->plugin_dummy_bfd = abfd; bfd_make_readable (abfd); return abfd->xvec; } else { #if HAVE_MMAP if (input->use_mmap) { /* If plugin didn't claim the file, unmap the buffer. */ char *addr = input->view_buffer.addr; off_t size = input->view_buffer.filesize; # if HAVE_GETPAGESIZE off_t bias = input->view_buffer.offset % plugin_pagesize; size += bias; addr -= bias; # endif munmap (addr, size); } #endif /* If plugin didn't claim the file, we don't need the dummy bfd. Can't avoid speculatively creating it, alas. */ ibfd->plugin_format = bfd_plugin_no; bfd_close_all_done (abfd); return NULL; } }
static const bfd_target * plugin_object_p (bfd *ibfd) { int claimed; plugin_input_file_t *input; off_t offset, filesize; struct ld_plugin_input_file file; bfd *abfd; bfd_boolean inarchive; const char *name; int fd; /* Don't try the dummy object file. */ if ((ibfd->flags & BFD_PLUGIN) != 0) return NULL; if (ibfd->plugin_format != bfd_plugin_uknown) { if (ibfd->plugin_format == bfd_plugin_yes) return ibfd->plugin_dummy_bfd->xvec; else return NULL; } inarchive = bfd_my_archive (ibfd) != NULL; name = inarchive ? bfd_my_archive (ibfd)->filename : ibfd->filename; fd = open (name, O_RDONLY | O_BINARY); if (fd < 0) return NULL; /* We create a dummy BFD, initially empty, to house whatever symbols the plugin may want to add. */ abfd = plugin_get_ir_dummy_bfd (ibfd->filename, ibfd); input = bfd_alloc (abfd, sizeof (*input)); if (input == NULL) einfo (_("%P%F: plugin failed to allocate memory for input: %s\n"), bfd_get_error ()); if (inarchive) { /* Offset and filesize must refer to the individual archive member, not the whole file, and must exclude the header. Fortunately for us, that is how the data is stored in the origin field of the bfd and in the arelt_data. */ offset = ibfd->origin; filesize = arelt_size (ibfd); } else { offset = 0; filesize = lseek (fd, 0, SEEK_END); /* We must copy filename attached to ibfd if it is not an archive member since it may be freed by bfd_close below. */ name = plugin_strdup (abfd, name); } file.name = name; file.offset = offset; file.filesize = filesize; file.fd = fd; file.handle = input; input->abfd = abfd; input->view_buffer.addr = NULL; input->view_buffer.filesize = 0; input->view_buffer.offset = 0; input->fd = fd; input->use_mmap = FALSE; input->offset = offset; input->filesize = filesize; input->name = plugin_strdup (abfd, ibfd->filename); claimed = 0; if (plugin_call_claim_file (&file, &claimed)) einfo (_("%P%F: %s: plugin reported error claiming file\n"), plugin_error_plugin ()); if (input->fd != -1 && ! bfd_plugin_target_p (ibfd->xvec)) { /* FIXME: fd belongs to us, not the plugin. GCC plugin, which doesn't need fd after plugin_call_claim_file, doesn't use BFD plugin target vector. Since GCC plugin doesn't call release_input_file, we close it here. LLVM plugin, which needs fd after plugin_call_claim_file and calls release_input_file after it is done, uses BFD plugin target vector. This scheme doesn't work when a plugin needs fd and doesn't use BFD plugin target vector neither. */ close (fd); input->fd = -1; } if (claimed) { ibfd->plugin_format = bfd_plugin_yes; ibfd->plugin_dummy_bfd = abfd; bfd_make_readable (abfd); return abfd->xvec; } else { #if HAVE_MMAP if (input->use_mmap) { /* If plugin didn't claim the file, unmap the buffer. */ char *addr = input->view_buffer.addr; off_t size = input->view_buffer.filesize; # if HAVE_GETPAGESIZE off_t bias = input->view_buffer.offset % plugin_pagesize; size += bias; addr -= bias; # endif munmap (addr, size); } #endif /* If plugin didn't claim the file, we don't need the dummy bfd. Can't avoid speculatively creating it, alas. */ ibfd->plugin_format = bfd_plugin_no; bfd_close_all_done (abfd); return NULL; } }