struct compile_module * compile_object_load (const char *object_file, const char *source_file) { struct cleanup *cleanups, *cleanups_free_objfile; bfd *abfd; struct setup_sections_data setup_sections_data; CORE_ADDR addr, func_addr, regs_addr; struct bound_minimal_symbol bmsym; long storage_needed; asymbol **symbol_table, **symp; long number_of_symbols, missing_symbols; struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; unsigned dptr_type_len = TYPE_LENGTH (dptr_type); struct compile_module *retval; struct type *regs_type; char *filename, **matching; struct objfile *objfile; filename = tilde_expand (object_file); cleanups = make_cleanup (xfree, filename); abfd = gdb_bfd_open (filename, gnutarget, -1); if (abfd == NULL) error (_("\"%s\": could not open as compiled module: %s"), filename, bfd_errmsg (bfd_get_error ())); make_cleanup_bfd_unref (abfd); if (!bfd_check_format_matches (abfd, bfd_object, &matching)) error (_("\"%s\": not in loadable format: %s"), filename, gdb_bfd_errmsg (bfd_get_error (), matching)); if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0) error (_("\"%s\": not in object format."), filename); setup_sections_data.last_size = 0; setup_sections_data.last_section_first = abfd->sections; setup_sections_data.last_prot = -1; setup_sections_data.last_max_alignment = 1; bfd_map_over_sections (abfd, setup_sections, &setup_sections_data); setup_sections (abfd, NULL, &setup_sections_data); storage_needed = bfd_get_symtab_upper_bound (abfd); if (storage_needed < 0) error (_("Cannot read symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in "Reading symbols from ..." message for automatically generated file. */ objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL); cleanups_free_objfile = make_cleanup_free_objfile (objfile); bmsym = lookup_minimal_symbol_text (GCC_FE_WRAPPER_FUNCTION, objfile); if (bmsym.minsym == NULL || MSYMBOL_TYPE (bmsym.minsym) == mst_file_text) error (_("Could not find symbol \"%s\" of compiled module \"%s\"."), GCC_FE_WRAPPER_FUNCTION, filename); func_addr = BMSYMBOL_VALUE_ADDRESS (bmsym); /* The memory may be later needed by bfd_generic_get_relocated_section_contents called from default_symfile_relocate. */ symbol_table = obstack_alloc (&objfile->objfile_obstack, storage_needed); number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); if (number_of_symbols < 0) error (_("Cannot parse symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); missing_symbols = 0; for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++) { asymbol *sym = *symp; if (sym->flags != 0) continue; if (compile_debug) fprintf_unfiltered (gdb_stdout, "lookup undefined ELF symbol \"%s\"\n", sym->name); sym->flags = BSF_GLOBAL; sym->section = bfd_abs_section_ptr; if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0) { sym->value = 0; continue; } bmsym = lookup_minimal_symbol (sym->name, NULL, NULL); switch (bmsym.minsym == NULL ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym)) { case mst_text: sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym); break; default: warning (_("Could not find symbol \"%s\" " "for compiled module \"%s\"."), sym->name, filename); missing_symbols++; } } if (missing_symbols) error (_("%ld symbols were missing, cannot continue."), missing_symbols); bfd_map_over_sections (abfd, copy_sections, symbol_table); regs_type = get_regs_type (objfile); if (regs_type == NULL) regs_addr = 0; else { /* Use read-only non-executable memory protection. */ regs_addr = gdbarch_infcall_mmap (target_gdbarch (), TYPE_LENGTH (regs_type), GDB_MMAP_PROT_READ); gdb_assert (regs_addr != 0); store_regs (regs_type, regs_addr); } discard_cleanups (cleanups_free_objfile); do_cleanups (cleanups); retval = xmalloc (sizeof (*retval)); retval->objfile = objfile; retval->source_file = xstrdup (source_file); retval->func_addr = func_addr; retval->regs_addr = regs_addr; return retval; }
static CORE_ADDR ppc_linux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) { gdb_byte buf[4]; struct obj_section *sect; struct objfile *objfile; unsigned long insn; CORE_ADDR plt_start = 0; CORE_ADDR symtab = 0; CORE_ADDR strtab = 0; int num_slots = -1; int reloc_index = -1; CORE_ADDR plt_table; CORE_ADDR reloc; CORE_ADDR sym; long symidx; char symname[1024]; struct minimal_symbol *msymbol; /* Find the section pc is in; return if not in .plt */ sect = find_pc_section (pc); if (!sect || strcmp (sect->the_bfd_section->name, ".plt") != 0) return 0; objfile = sect->objfile; /* Pick up the instruction at pc. It had better be of the form li r11, IDX where IDX is an index into the plt_table. */ if (target_read_memory (pc, buf, 4) != 0) return 0; insn = extract_unsigned_integer (buf, 4); if ((insn & 0xffff0000) != 0x39600000 /* li r11, VAL */ ) return 0; reloc_index = (insn << 16) >> 16; /* Find the objfile that pc is in and obtain the information necessary for finding the symbol name. */ for (sect = objfile->sections; sect < objfile->sections_end; ++sect) { const char *secname = sect->the_bfd_section->name; if (strcmp (secname, ".plt") == 0) plt_start = sect->addr; else if (strcmp (secname, ".rela.plt") == 0) num_slots = ((int) sect->endaddr - (int) sect->addr) / 12; else if (strcmp (secname, ".dynsym") == 0) symtab = sect->addr; else if (strcmp (secname, ".dynstr") == 0) strtab = sect->addr; } /* Make sure we have all the information we need. */ if (plt_start == 0 || num_slots == -1 || symtab == 0 || strtab == 0) return 0; /* Compute the value of the plt table */ plt_table = plt_start + 72 + 8 * num_slots; /* Get address of the relocation entry (Elf32_Rela) */ if (target_read_memory (plt_table + reloc_index, buf, 4) != 0) return 0; reloc = extract_unsigned_integer (buf, 4); sect = find_pc_section (reloc); if (!sect) return 0; if (strcmp (sect->the_bfd_section->name, ".text") == 0) return reloc; /* Now get the r_info field which is the relocation type and symbol index. */ if (target_read_memory (reloc + 4, buf, 4) != 0) return 0; symidx = extract_unsigned_integer (buf, 4); /* Shift out the relocation type leaving just the symbol index */ /* symidx = ELF32_R_SYM(symidx); */ symidx = symidx >> 8; /* compute the address of the symbol */ sym = symtab + symidx * 4; /* Fetch the string table index */ if (target_read_memory (sym, buf, 4) != 0) return 0; symidx = extract_unsigned_integer (buf, 4); /* Fetch the string; we don't know how long it is. Is it possible that the following will fail because we're trying to fetch too much? */ if (target_read_memory (strtab + symidx, (gdb_byte *) symname, sizeof (symname)) != 0) return 0; /* This might not work right if we have multiple symbols with the same name; the only way to really get it right is to perform the same sort of lookup as the dynamic linker. */ msymbol = lookup_minimal_symbol_text (symname, NULL); if (!msymbol) return 0; return SYMBOL_VALUE_ADDRESS (msymbol); }