static void write_gcore_file_1 (bfd *obfd) { struct cleanup *cleanup; void *note_data = NULL; int note_size = 0; asection *note_sec = NULL; /* An external target method must build the notes section. */ /* FIXME: uweigand/2011-10-06: All architectures that support core file generation should be converted to gdbarch_make_corefile_notes; at that point, the target vector method can be removed. */ if (!gdbarch_make_corefile_notes_p (target_gdbarch ())) note_data = target_make_corefile_notes (obfd, ¬e_size); else note_data = gdbarch_make_corefile_notes (target_gdbarch (), obfd, ¬e_size); cleanup = make_cleanup (xfree, note_data); if (note_data == NULL || note_size == 0) error (_("Target does not support core file generation.")); /* Create the note section. */ 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 (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size)) warning (_("writing note section (%s)"), bfd_errmsg (bfd_get_error ())); do_cleanups (cleanup); }
/* FIXME: add comment: */ static void dump_bfd_file(const char *filename, const char *mode, const char *target, CORE_ADDR vaddr, const bfd_byte *buf, int len) { bfd *obfd; asection *osection; obfd = bfd_openw_with_cleanup(filename, target, mode); osection = bfd_make_section_anyway(obfd, ".newsec"); bfd_set_section_size(obfd, osection, len); if (bfd_set_section_vma(obfd, osection, vaddr)) { ; } if (bfd_set_section_alignment(obfd, osection, 0)) { ; } bfd_set_section_flags(obfd, osection, (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD)); osection->entsize = 0; bfd_set_section_contents(obfd, osection, buf, 0, len); }
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 setup_sections (bfd *abfd, asection *sect, void *data_voidp) { struct setup_sections_data *data = data_voidp; CORE_ADDR alignment; unsigned prot; if (sect != NULL) { /* It is required by later bfd_get_relocated_section_contents. */ if (sect->output_section == NULL) sect->output_section = sect; if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0) return; /* Make the memory always readable. */ prot = GDB_MMAP_PROT_READ; if ((bfd_get_section_flags (abfd, sect) & SEC_READONLY) == 0) prot |= GDB_MMAP_PROT_WRITE; if ((bfd_get_section_flags (abfd, sect) & SEC_CODE) != 0) prot |= GDB_MMAP_PROT_EXEC; if (compile_debug) fprintf_unfiltered (gdb_stdlog, "module \"%s\" section \"%s\" size %s prot %u\n", bfd_get_filename (abfd), bfd_get_section_name (abfd, sect), paddress (target_gdbarch (), bfd_get_section_size (sect)), prot); } else prot = -1; if (sect == NULL || (data->last_prot != prot && bfd_get_section_size (sect) != 0)) { CORE_ADDR addr; asection *sect_iter; if (data->last_size != 0) { addr = gdbarch_infcall_mmap (target_gdbarch (), data->last_size, data->last_prot); munmap_list_add (data->munmap_list_headp, addr, data->last_size); if (compile_debug) fprintf_unfiltered (gdb_stdlog, "allocated %s bytes at %s prot %u\n", paddress (target_gdbarch (), data->last_size), paddress (target_gdbarch (), addr), data->last_prot); } else addr = 0; if ((addr & (data->last_max_alignment - 1)) != 0) error (_("Inferior compiled module address %s " "is not aligned to BFD required %s."), paddress (target_gdbarch (), addr), paddress (target_gdbarch (), data->last_max_alignment)); for (sect_iter = data->last_section_first; sect_iter != sect; sect_iter = sect_iter->next) if ((bfd_get_section_flags (abfd, sect_iter) & SEC_ALLOC) != 0) bfd_set_section_vma (abfd, sect_iter, addr + bfd_get_section_vma (abfd, sect_iter)); data->last_size = 0; data->last_section_first = sect; data->last_prot = prot; data->last_max_alignment = 1; } if (sect == NULL) return; alignment = ((CORE_ADDR) 1) << bfd_get_section_alignment (abfd, sect); data->last_max_alignment = max (data->last_max_alignment, alignment); data->last_size = (data->last_size + alignment - 1) & -alignment; bfd_set_section_vma (abfd, sect, data->last_size); data->last_size += bfd_get_section_size (sect); data->last_size = (data->last_size + alignment - 1) & -alignment; }
static void setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg) { bfd *obfd = obfdarg; struct section_list *p; sec_ptr osection; bfd_size_type size; bfd_vma vma; bfd_vma lma; const char *err; const char * name; name = bfd_section_name (ibfd, isection); osection = bfd_make_section_anyway (obfd, name); if (osection == NULL) { perror("setup_section: making"); } size = bfd_section_size (ibfd, isection); if (! bfd_set_section_size (obfd, osection, size)) { perror("setup_section: size"); } vma = bfd_section_vma (ibfd, isection); if (! bfd_set_section_vma (obfd, osection, vma)) { perror("setup_section: vma"); } lma = isection->lma; osection->lma = lma; /* FIXME: This is probably not enough. If we change the LMA we may have to recompute the header for the file as well. */ if (!bfd_set_section_alignment (obfd, osection, bfd_section_alignment (ibfd, isection))) { perror("setup_section: alignment"); } if (!bfd_set_section_flags (obfd, osection, bfd_get_section_flags(ibfd, isection))) { perror("setup_section: flags"); } /* Copy merge entity size. */ osection->entsize = isection->entsize; /* This used to be mangle_section; we do here to avoid using bfd_get_section_by_name since some formats allow multiple sections with the same name. */ isection->output_section = osection; isection->output_offset = 0; /* Allow the BFD backend to copy any private data it understands from the input section to the output section. */ if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection)) { perror("setup_section: private data"); } /* All went well. */ return; perror("setup_section: %s: section `%s': error in %s: %s"), bfd_get_filename (ibfd), bfd_section_name (ibfd, isection), err, bfd_errmsg (bfd_get_error ()); }
static void macho_add_oso_symfile (oso_el *oso, const gdb_bfd_ref_ptr &abfd, const char *name, struct objfile *main_objfile, symfile_add_flags symfile_flags) { int storage; int i; asymbol **symbol_table; asymbol **symp; struct bfd_hash_table table; int nbr_sections; /* Per section flag to mark which section have been rebased. */ unsigned char *sections_rebased; if (mach_o_debug_level > 0) printf_unfiltered (_("Loading debugging symbols from oso: %s\n"), oso->name); if (!bfd_check_format (abfd.get (), bfd_object)) { warning (_("`%s': can't read symbols: %s."), oso->name, bfd_errmsg (bfd_get_error ())); return; } if (abfd->my_archive == NULL && oso->mtime != bfd_get_mtime (abfd.get ())) { warning (_("`%s': file time stamp mismatch."), oso->name); return; } if (!bfd_hash_table_init_n (&table, macho_sym_hash_newfunc, sizeof (struct macho_sym_hash_entry), oso->nbr_syms)) { warning (_("`%s': can't create hash table"), oso->name); return; } bfd_set_cacheable (abfd.get (), 1); /* Read symbols table. */ storage = bfd_get_symtab_upper_bound (abfd.get ()); symbol_table = (asymbol **) xmalloc (storage); bfd_canonicalize_symtab (abfd.get (), symbol_table); /* Init section flags. */ nbr_sections = bfd_count_sections (abfd.get ()); sections_rebased = (unsigned char *) alloca (nbr_sections); for (i = 0; i < nbr_sections; i++) sections_rebased[i] = 0; /* Put symbols for the OSO file in the hash table. */ for (symp = oso->oso_sym; symp != oso->end_sym; symp++) { const asymbol *sym = *symp; bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym; switch (mach_o_sym->n_type) { case N_ENSYM: case N_BNSYM: case N_GSYM: sym = NULL; break; case N_FUN: if (sym->name == NULL || sym->name[0] == 0) sym = NULL; break; case N_STSYM: break; default: sym = NULL; break; } if (sym != NULL) { struct macho_sym_hash_entry *ent; ent = (struct macho_sym_hash_entry *) bfd_hash_lookup (&table, sym->name, TRUE, FALSE); if (ent->sym != NULL) complaint (_("Duplicated symbol %s in symbol table"), sym->name); else { if (mach_o_debug_level > 4) { struct gdbarch *arch = get_objfile_arch (main_objfile); printf_unfiltered (_("Adding symbol %s (addr: %s)\n"), sym->name, paddress (arch, sym->value)); } ent->sym = sym; } } } /* Relocate symbols of the OSO. */ for (i = 0; symbol_table[i]; i++) { asymbol *sym = symbol_table[i]; bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym; if (mach_o_sym->n_type & BFD_MACH_O_N_STAB) continue; if ((mach_o_sym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF && sym->value != 0) { /* For common symbol use the min symtab and modify the OSO symbol table. */ CORE_ADDR res; res = macho_resolve_oso_sym_with_minsym (main_objfile, sym); if (res != 0) { sym->section = bfd_com_section_ptr; sym->value = res; } } else if ((mach_o_sym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT) { /* Normal symbol. */ asection *sec = sym->section; bfd_mach_o_section *msec; unsigned int sec_type; /* Skip buggy ones. */ if (sec == NULL || sections_rebased[sec->index] != 0) continue; /* Only consider regular, non-debugging sections. */ msec = bfd_mach_o_get_mach_o_section (sec); sec_type = msec->flags & BFD_MACH_O_SECTION_TYPE_MASK; if ((sec_type == BFD_MACH_O_S_REGULAR || sec_type == BFD_MACH_O_S_ZEROFILL) && (msec->flags & BFD_MACH_O_S_ATTR_DEBUG) == 0) { CORE_ADDR addr = 0; if ((mach_o_sym->n_type & BFD_MACH_O_N_EXT) != 0) { /* Use the min symtab for global symbols. */ addr = macho_resolve_oso_sym_with_minsym (main_objfile, sym); } else { struct macho_sym_hash_entry *ent; ent = (struct macho_sym_hash_entry *) bfd_hash_lookup (&table, sym->name, FALSE, FALSE); if (ent != NULL) addr = bfd_asymbol_value (ent->sym); } /* Adjust the section. */ if (addr != 0) { CORE_ADDR res = addr - sym->value; if (mach_o_debug_level > 3) { struct gdbarch *arch = get_objfile_arch (main_objfile); printf_unfiltered (_("resolve sect %s with %s (set to %s)\n"), sec->name, sym->name, paddress (arch, res)); } bfd_set_section_vma (abfd.get (), sec, res); sections_rebased[sec->index] = 1; } } else { /* Mark the section as never rebased. */ sections_rebased[sec->index] = 2; } } } bfd_hash_table_free (&table); /* We need to clear SYMFILE_MAINLINE to avoid interractive question from symfile.c:symbol_file_add_with_addrs_or_offsets. */ symbol_file_add_from_bfd (abfd.get (), name, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE), NULL, main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW | OBJF_USERLOADED), main_objfile); }