Пример #1
0
LONGEST
target_bfd_xfer_partial (struct target_ops *ops,
			 enum target_object object,
			 const char *annex, gdb_byte *readbuf,
			 const gdb_byte *writebuf,
			 ULONGEST offset, LONGEST len)
{
  switch (object)
    {
    case TARGET_OBJECT_MEMORY:
      {
	struct section_table *s = target_section_by_addr (ops, offset);
	if (s == NULL)
	  return -1;
	/* If the length extends beyond the section, truncate it.  Be
           careful to not suffer from overflow (wish S contained a
           length).  */
	if ((offset - s->addr + len) > (s->endaddr - s->addr))
	  len = (s->endaddr - s->addr) - (offset - s->addr);
	if (readbuf != NULL
	    && !bfd_get_section_contents (s->bfd, s->the_bfd_section,
					  readbuf, offset - s->addr, len))
	  return -1;
#if 1
	if (writebuf != NULL)
	  return -1;
#else
	/* FIXME: cagney/2003-10-31: The BFD interface doesn't yet
           take a const buffer.  */
	if (writebuf != NULL
	    && !bfd_set_section_contents (s->bfd, s->the_bfd_section,
					  writebuf, offset - s->addr, len))
	  return -1;
#endif
	return len;
      }
    default:
      return -1;
    }
}
Пример #2
0
/* 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);
}
Пример #3
0
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, &note_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;
}
Пример #4
0
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()));
}
Пример #5
0
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);
}
Пример #6
0
static int
section_table_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr,
			   int len, int write,
			   struct target_section *sections,
			   struct target_section *sections_end,
			   const char *section_name)
{
  int res;
  struct target_section *p;
  CORE_ADDR nextsectaddr, memend;

  if (len <= 0)
    internal_error (__FILE__, __LINE__, _("failed internal consistency check"));

  memend = memaddr + len;
  nextsectaddr = memend;

  for (p = sections; p < sections_end; p++)
    {
      if (section_name && strcmp (section_name, p->the_bfd_section->name) != 0)
	continue;		/* not the section we need */
      if (memaddr >= p->addr)
        {
	  if (memend <= p->endaddr)
	    {
	      /* Entire transfer is within this section.  */
	      if (write)
		res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
						myaddr, memaddr - p->addr,
						len);
	      else
		res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
						myaddr, memaddr - p->addr,
						len);
	      return (res != 0) ? len : 0;
	    }
	  else if (memaddr >= p->endaddr)
	    {
	      /* This section ends before the transfer starts.  */
	      continue;
	    }
	  else
	    {
	      /* This section overlaps the transfer.  Just do half.  */
	      len = p->endaddr - memaddr;
	      if (write)
		res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
						myaddr, memaddr - p->addr,
						len);
	      else
		res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
						myaddr, memaddr - p->addr,
						len);
	      return (res != 0) ? len : 0;
	    }
        }
      else
	nextsectaddr = min (nextsectaddr, p->addr);
    }

  if (nextsectaddr >= memend)
    return 0;			/* We can't help */
  else
    return -(nextsectaddr - memaddr);	/* Next boundary where we can help */
}
Пример #7
0
bfd_boolean
_bfd_write_section_stabs (bfd *output_bfd,
			  struct stab_info *sinfo,
			  asection *stabsec,
			  void * *psecinfo,
			  bfd_byte *contents)
{
  struct stab_section_info *secinfo;
  struct stab_excl_list *e;
  bfd_byte *sym, *tosym, *symend;
  bfd_size_type *pstridx;

  secinfo = (struct stab_section_info *) *psecinfo;

  if (secinfo == NULL)
    return bfd_set_section_contents (output_bfd, stabsec->output_section,
				     contents, stabsec->output_offset,
				     stabsec->size);

  /* Handle each N_BINCL entry.  */
  for (e = secinfo->excls; e != NULL; e = e->next)
    {
      bfd_byte *excl_sym;

      BFD_ASSERT (e->offset < stabsec->rawsize);
      excl_sym = contents + e->offset;
      bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
      excl_sym[TYPEOFF] = e->type;
    }

  /* Copy over all the stabs symbols, omitting the ones we don't want,
     and correcting the string indices for those we do want.  */
  tosym = contents;
  symend = contents + stabsec->rawsize;
  for (sym = contents, pstridx = secinfo->stridxs;
       sym < symend;
       sym += STABSIZE, ++pstridx)
    {
      if (*pstridx != (bfd_size_type) -1)
	{
	  if (tosym != sym)
	    memcpy (tosym, sym, STABSIZE);
	  bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);

	  if (sym[TYPEOFF] == 0)
	    {
	      /* This is the header symbol for the stabs section.  We
		 don't really need one, since we have merged all the
		 input stabs sections into one, but we generate one
		 for the benefit of readers which expect to see one.  */
	      BFD_ASSERT (sym == contents);
	      bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
			  tosym + VALOFF);
	      bfd_put_16 (output_bfd,
			  stabsec->output_section->size / STABSIZE - 1,
			  tosym + DESCOFF);
	    }

	  tosym += STABSIZE;
	}
    }

  BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->size);

  return bfd_set_section_contents (output_bfd, stabsec->output_section,
				   contents, (file_ptr) stabsec->output_offset,
				   stabsec->size);
}
Пример #8
0
int
xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
	     struct mem_attrib *attrib, struct target_ops *target)
{
  int res;
  struct section_table *p;
  CORE_ADDR nextsectaddr, memend;
  asection *section = NULL;

  if (len <= 0)
    internal_error (__FILE__, __LINE__, _("failed internal consistency check"));

  if (overlay_debugging)
    {
      section = find_pc_overlay (memaddr);
      if (pc_in_unmapped_range (memaddr, section))
	memaddr = overlay_mapped_address (memaddr, section);
    }

  memend = memaddr + len;
  nextsectaddr = memend;

  for (p = target->to_sections; p < target->to_sections_end; p++)
    {
      if (overlay_debugging && section && p->the_bfd_section &&
	  strcmp (section->name, p->the_bfd_section->name) != 0)
	continue;		/* not the section we need */
      if (memaddr >= p->addr)
        {
	  if (memend <= p->endaddr)
	    {
	      /* Entire transfer is within this section.  */
	      if (write)
		res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
						myaddr, memaddr - p->addr,
						len);
	      else
		res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
						myaddr, memaddr - p->addr,
						len);
	      return (res != 0) ? len : 0;
	    }
	  else if (memaddr >= p->endaddr)
	    {
	      /* This section ends before the transfer starts.  */
	      continue;
	    }
	  else
	    {
	      /* This section overlaps the transfer.  Just do half.  */
	      len = p->endaddr - memaddr;
	      if (write)
		res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
						myaddr, memaddr - p->addr,
						len);
	      else
		res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
						myaddr, memaddr - p->addr,
						len);
	      return (res != 0) ? len : 0;
	    }
        }
      else
	nextsectaddr = min (nextsectaddr, p->addr);
    }

  if (nextsectaddr >= memend)
    return 0;			/* We can't help */
  else
    return -(nextsectaddr - memaddr);	/* Next boundary where we can help */
}
/* the finishing piece for each section */
static void copy_section_data (bfd *ibfd, sec_ptr isection, void *obfdarg)
{
    bfd *obfd = obfdarg;
    sec_ptr osection;
    bfd_size_type size;
    struct add_reloc_struct *new_reloc;

    size = bfd_get_section_size (isection);

    osection = isection->output_section;

    if (size == 0 || osection == 0)
	return;

    if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
	&& bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS) {

	void *memhunk;

	mcheck_check_all();

	memhunk = malloc (size);

	if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
	    return;

	if (strcmp(bfd_get_section_name(ibfd, isection), ".text") == 0) {

	    /* make the data modifications, if requested */
	    modify_byte_struct *mbyte_ptr = modify_bytes;
	    while (mbyte_ptr != NULL) {
		((unsigned char *)memhunk)[mbyte_ptr->location] = (char)(mbyte_ptr->value & 0xff);
		mbyte_ptr = mbyte_ptr->next;
	    }

	    /* make sure additional relocs have proper data present */
	    /* kernel implements relocs relative to what's already there in the data! */
	    /* so if we're overriding a call, we need to set the old PC-relative data back to 0xfffffffc */
	    for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) {
		((unsigned char *)memhunk)[new_reloc->loc]   = (unsigned char)0xfc;
		((unsigned char *)memhunk)[new_reloc->loc+1] = (unsigned char)0xff;
		((unsigned char *)memhunk)[new_reloc->loc+2] = (unsigned char)0xff;
		((unsigned char *)memhunk)[new_reloc->loc+3] = (unsigned char)0xff;
	    }
	}

	if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
	    return;

	/* note that bfd_set_section_contents will render the symbol table noncanonical */
	/* (the array will not be NULL terminated) */

	free (memhunk);
    }
    else if (!(bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)) {
	fprintf(stderr, "not copying input section %s because flags %x do not indicate contents (%x)\n",
	       isection->name,
	       bfd_get_section_flags (ibfd, isection),
	       SEC_HAS_CONTENTS);
    }
    else {
	fprintf(stderr, "not copying output section %s because flags %x do not indicate contents (%x)\n",
	       osection->name,
	       bfd_get_section_flags (obfd, osection),
	       SEC_HAS_CONTENTS);
    }
}