/* Set parameters about this a.out file that are machine-dependent. This routine is called from some_aout_object_p just before it returns. */ static const bfd_target * MY (callback) (bfd *abfd) { struct internal_exec *execp = exec_hdr (abfd); /* Calculate the file positions of the parts of a newly read aout header */ obj_textsec (abfd)->size = N_TXTSIZE (*execp); /* The virtual memory addresses of the sections */ obj_textsec (abfd)->vma = N_TXTADDR (*execp); obj_datasec (abfd)->vma = N_DATADDR (*execp); obj_bsssec (abfd)->vma = N_BSSADDR (*execp); obj_textsec (abfd)->lma = obj_textsec (abfd)->vma; obj_datasec (abfd)->lma = obj_datasec (abfd)->vma; obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma; /* The file offsets of the sections */ obj_textsec (abfd)->filepos = N_TXTOFF (*execp); obj_datasec (abfd)->filepos = N_DATOFF (*execp); /* The file offsets of the relocation info */ obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp); obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp); /* The file offsets of the string table and symbol table. */ obj_sym_filepos (abfd) = N_SYMOFF (*execp); obj_str_filepos (abfd) = N_STROFF (*execp); /* Determine the architecture and machine type of the object file. */ #ifdef SET_ARCH_MACH SET_ARCH_MACH (abfd, *execp); #else bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0); #endif if (obj_aout_subformat (abfd) == gnu_encap_format) { /* The file offsets of the relocation info */ obj_textsec (abfd)->rel_filepos = N_GNU_TRELOFF (*execp); obj_datasec (abfd)->rel_filepos = N_GNU_DRELOFF (*execp); /* The file offsets of the string table and symbol table. */ obj_sym_filepos (abfd) = N_GNU_SYMOFF (*execp); obj_str_filepos (abfd) = (obj_sym_filepos (abfd) + execp->a_syms); abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS; bfd_get_symcount (abfd) = execp->a_syms / 12; obj_symbol_entry_size (abfd) = 12; obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; } return abfd->xvec; }
int hide_aout(int inf, const char *filename) { struct stat infstat; struct relocation_info *relp; struct nlist *symp; int rc; /* * do some error checking. */ if(fstat(inf, &infstat) == -1) { perror(filename); return 1; } /* * Read the entire file into memory. XXX - Really, we only need to * read the header and from TRELOFF to the end of the file. */ if((aoutdata = (char *) malloc(infstat.st_size)) == NULL) { fprintf(stderr, "%s: too big to read into memory\n", filename); return 1; } if((rc = read(inf, aoutdata, infstat.st_size)) < infstat.st_size) { fprintf(stderr, "%s: read error: %s\n", filename, rc == -1? strerror(errno) : "short read"); return 1; } /* * Calculate offsets and sizes from the header. */ hdrp = (struct exec *) aoutdata; #ifdef __FreeBSD__ textrel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp)); datarel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp) + hdrp->a_trsize); #else textrel = (struct relocation_info *) (aoutdata + N_TRELOFF(*hdrp)); datarel = (struct relocation_info *) (aoutdata + N_DRELOFF(*hdrp)); #endif symbase = (struct nlist *) (aoutdata + N_SYMOFF(*hdrp)); strbase = (char *) (aoutdata + N_STROFF(*hdrp)); ntextrel = hdrp->a_trsize / sizeof(struct relocation_info); ndatarel = hdrp->a_drsize / sizeof(struct relocation_info); nsyms = hdrp->a_syms / sizeof(struct nlist); /* * Zap the type field of all globally-defined symbols. The linker will * subsequently ignore these entries. Don't zap any symbols in the * keep list. */ for(symp = symbase; symp < symbase + nsyms; symp++) { if(!IS_GLOBAL_DEFINED(symp)) /* keep undefined syms */ continue; /* keep (C) symbols which are on the keep list */ if(SYMSTR(symp)[0] == '_' && in_keep_list(SYMSTR(symp) + 1)) continue; symp->n_type = 0; } /* * Check whether the relocation entries reference any symbols that we * just zapped. I don't know whether ld can handle this case, but I * haven't encountered it yet. These checks are here so that the program * doesn't fail silently should such symbols be encountered. */ for(relp = textrel; relp < textrel + ntextrel; relp++) check_reloc(filename, relp); for(relp = datarel; relp < datarel + ndatarel; relp++) check_reloc(filename, relp); /* * Write the .o file back out to disk. XXX - Really, we only need to * write the symbol table entries back out. */ lseek(inf, 0, SEEK_SET); if((rc = write(inf, aoutdata, infstat.st_size)) < infstat.st_size) { fprintf(stderr, "%s: write error: %s\n", filename, rc == -1? strerror(errno) : "short write"); return 1; } return 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 bfd_boolean aout_adobe_write_object_contents (bfd *abfd) { struct external_exec swapped_hdr; static struct external_segdesc sentinel[1]; /* Initialized to zero. */ asection *sect; bfd_size_type amt; exec_hdr (abfd)->a_info = ZMAGIC; /* Calculate text size as total of text sections, etc. */ exec_hdr (abfd)->a_text = 0; exec_hdr (abfd)->a_data = 0; exec_hdr (abfd)->a_bss = 0; exec_hdr (abfd)->a_trsize = 0; exec_hdr (abfd)->a_drsize = 0; for (sect = abfd->sections; sect; sect = sect->next) { if (sect->flags & SEC_CODE) { exec_hdr (abfd)->a_text += sect->size; exec_hdr (abfd)->a_trsize += sect->reloc_count * sizeof (struct reloc_std_external); } else if (sect->flags & SEC_DATA) { exec_hdr (abfd)->a_data += sect->size; exec_hdr (abfd)->a_drsize += sect->reloc_count * sizeof (struct reloc_std_external); } else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD)) exec_hdr (abfd)->a_bss += sect->size; } exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct external_nlist); exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr); amt = EXEC_BYTES_SIZE; if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 || bfd_bwrite (& swapped_hdr, amt, abfd) != amt) return FALSE; /* Now write out the section information. Text first, data next, rest afterward. */ for (sect = abfd->sections; sect; sect = sect->next) if (sect->flags & SEC_CODE) aout_adobe_write_section (abfd, sect); for (sect = abfd->sections; sect; sect = sect->next) if (sect->flags & SEC_DATA) aout_adobe_write_section (abfd, sect); for (sect = abfd->sections; sect; sect = sect->next) if (!(sect->flags & (SEC_CODE | SEC_DATA))) aout_adobe_write_section (abfd, sect); /* Write final `sentinel` section header (with type of 0). */ amt = sizeof (*sentinel); if (bfd_bwrite (sentinel, amt, abfd) != amt) return FALSE; /* Now write out reloc info, followed by syms and strings. */ if (bfd_get_symcount (abfd) != 0) { if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET) != 0) return FALSE; if (! aout_32_write_syms (abfd)) return FALSE; if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*exec_hdr (abfd))), SEEK_SET) != 0) return FALSE; for (sect = abfd->sections; sect; sect = sect->next) if (sect->flags & SEC_CODE) if (!aout_32_squirt_out_relocs (abfd, sect)) return FALSE; if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET) != 0) return FALSE; for (sect = abfd->sections; sect; sect = sect->next) if (sect->flags & SEC_DATA) if (!aout_32_squirt_out_relocs (abfd, sect)) return FALSE; } return TRUE; }
void hide_syms(char *filename) { int inf, outf, rc; struct stat infstat; struct relocation_info *relp; struct nlist *symp; char *buf; u_char zero = 0; /* * Open the file and do some error checking. */ if ((inf = open(filename, O_RDWR)) == -1) { perror(filename); return; } if (fstat(inf, &infstat) == -1) { perror(filename); close(inf); return; } if (infstat.st_size < sizeof(struct exec)) { fprintf(stderr, "%s: short file\n", filename); close(inf); return; } if ((buf = mmap(NULL, infstat.st_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, inf, 0)) == MAP_FAILED) { fprintf(stderr, "%s: cannot map\n", filename); close(inf); return; } #ifdef _NLIST_DO_ELF if (buf[0] == 0x7f && (buf[1] == 'E' || buf[1] == 'O') && buf[2] == 'L' && buf[3] == 'F') { elf_hide(inf, buf); return; } #endif /* _NLIST_DO_ELF */ #ifdef _NLIST_DO_ECOFF if (!ECOFF_BADMAG((struct ecoff_exechdr *) buf)) { ecoff_hide(inf, buf); return; } #endif /* _NLIST_DO_ECOFF */ #ifdef DO_AOUT aoutdata = buf; /* * Check the header and calculate offsets and sizes from it. */ hdrp = (struct exec *) aoutdata; if (N_BADMAG(*hdrp)) { fprintf(stderr, "%s: bad magic: not an a.out, ecoff or elf file\n", filename); close(inf); return; } textrel = (struct relocation_info *) (aoutdata + N_TRELOFF(*hdrp)); datarel = (struct relocation_info *) (aoutdata + N_DRELOFF(*hdrp)); symbase = (struct nlist *) (aoutdata + N_SYMOFF(*hdrp)); strbase = (char *) (aoutdata + N_STROFF(*hdrp)); ntextrel = hdrp->a_trsize / sizeof(struct relocation_info); ndatarel = hdrp->a_drsize / sizeof(struct relocation_info); nsyms = hdrp->a_syms / sizeof(struct nlist); /* * Zap the type field of all globally-defined symbols. The linker will * subsequently ignore these entries. Don't zap any symbols in the * keep list. */ for (symp = symbase; symp < symbase + nsyms; symp++) if (IS_GLOBAL_DEFINED(symp) && !in_keep_list(SYMSTR(symp))) { /* * XXX Our VM system has some problems, so * avoid the VM system.... */ lseek(inf, (off_t) ((void *) &symp->n_type - (void *) buf), SEEK_SET); write(inf, &zero, sizeof zero); symp->n_type = 0; } /* * Check whether the relocation entries reference any symbols that we * just zapped. I don't know whether ld can handle this case, but I * haven't encountered it yet. These checks are here so that the program * doesn't fail silently should such symbols be encountered. */ for (relp = textrel; relp < textrel + ntextrel; relp++) check_reloc(filename, relp); for (relp = datarel; relp < datarel + ndatarel; relp++) check_reloc(filename, relp); msync(buf, infstat.st_size, MS_SYNC); munmap(buf, infstat.st_size); close(inf); #endif /* DO_AOUT */ }
void run_header(struct exec *exhdr, int extended_info) { char *id = NULL; assert(NULL != exhdr); /* print raw values */ printf( "\ta_midmag 0x%08x (mid %d, magic 0%o, flag 0x%x)\n" "\ta_text 0x%08x\n" "\ta_data 0x%08x\n" "\ta_bss 0x%08x\n" "\ta_syms 0x%08x\n" "\ta_entry 0x%08x\n" "\ta_trsize 0x%08x\n" "\ta_drsize 0x%08x\n", exhdr->a_midmag, N_GETMID(*exhdr), N_GETMAGIC(*exhdr), N_GETFLAG(*exhdr), exhdr->a_text, exhdr->a_data, exhdr->a_bss, exhdr->a_syms, exhdr->a_entry, exhdr->a_trsize, exhdr->a_drsize ); printf( "magic number %04o: %s\n", N_GETMAGIC(*exhdr), N_GETMAGIC(*exhdr) == OMAGIC ? "old impure format" : N_GETMAGIC(*exhdr) == NMAGIC ? "read-only text" : N_GETMAGIC(*exhdr) == ZMAGIC ? "demand load format" : N_GETMAGIC(*exhdr) == QMAGIC ? "deprecated format" : "totally funky" ); switch (N_GETMID(*exhdr)) { case MID_ZERO: id = "unknown - implementation dependent"; break; case MID_SUN010: id = "sun 68010/68020 binary"; break; case MID_SUN020: id = "sun 68020-only binary"; break; case MID_PC386: id = "386 PC binary. (so quoth BFD)"; break; case MID_HP200: id = "hp200 (68010) BSD binary"; break; case MID_I386: id = "i386 BSD binary"; break; case MID_M68K: id = "m68k BSD binary with 8K page sizes"; break; case MID_M68K4K: id = "m68k BSD binary with 4K page sizes"; break; case MID_NS32532: id = "ns32532"; break; case MID_SPARC: id = "sparc"; break; case MID_PMAX: id = "pmax"; break; case MID_VAX: id = "vax"; break; case MID_ALPHA: id = "Alpha BSD binary"; break; case MID_MIPS: id = "big-endian MIPS"; break; case MID_ARM6: id = "ARM6"; break; case MID_HP300: id = "hp300 (68020+68881) BSD binary"; break; case MID_HPUX: id = "hp200/300 HP-UX binary"; break; case MID_HPUX800: id = "hp800 HP-UX binary"; break; default: id = "don't know"; break; } printf("type %d, %s\n", N_GETMID(*exhdr), id); /* this left shift seems a bit bogus */ switch((N_GETFLAG(*exhdr) & EX_DPMASK)>>4) { case 0: id = "traditional executable or object file"; break; case 1: id = "object file contains PIC code"; break; case 2: id = "dynamic executable"; break; case 3: id = "position independent executable image"; break; default: id = NULL; } if (NULL != id) printf("flags: 0x%x, %s\n", N_GETFLAG(*exhdr), id); else printf("flags: 0x%x\n", N_GETFLAG(*exhdr)); if (extended_info) { unsigned long txt_addr; unsigned long dat_addr; unsigned long bss_addr; /* N_TXTADDR and N_DATADDR macros DON'T WORK */ if (N_GETMAGIC(*exhdr) == ZMAGIC) { txt_addr = __LDPGSZ; dat_addr = ((txt_addr + exhdr->a_text + __LDPGSZ - 1) & ~(__LDPGSZ - 1)); } else if (N_GETMAGIC(*exhdr) == OMAGIC) { txt_addr = 0; dat_addr = txt_addr + exhdr->a_text; } else { txt_addr = 0xdeadbeef; dat_addr = 0xcafebabe; } bss_addr = dat_addr + exhdr->a_data; printf(" text segment size = 0x%lx, text segment file offset = %ld\n", exhdr->a_text, N_TXTOFF(*exhdr)); printf(" data segment size = 0x%lx, data segment file offset = %ld\n", exhdr->a_data, N_DATOFF(*exhdr)); printf(" bss segment size = 0x%lx\n", exhdr->a_bss); printf(" text segment relocation size = 0x%lx, file offset = %ld, %d text relocations\n", exhdr->a_trsize, N_TRELOFF(*exhdr), exhdr->a_trsize/sizeof(struct relocation_info)); printf(" data segment relocation size = 0x%lx, file offset = %ld, %d data relocations\n", exhdr->a_drsize, N_DRELOFF(*exhdr), exhdr->a_drsize/sizeof(struct relocation_info)); printf(" symbol table size = 0x%lx, symbol table file offset = %ld (%d symbols)\n", exhdr->a_syms, N_SYMOFF(*exhdr), exhdr->a_syms/sizeof(struct nlist)); printf(" string table file offset = 0x%lx (%d)\n", N_STROFF(*exhdr), N_STROFF(*exhdr)); printf(" entry point = 0x%lx\n", exhdr->a_entry); printf(" text address = 0x%lx\n\tdata address = 0x%lx\n" "\tbss address = 0x%lx\n", txt_addr, dat_addr, bss_addr /* N_TXTADDR(*exhdr), N_DATADDR(*exhdr), N_BSSADDR(*exhdr) */ ); } }
int main(int ac, char **av) { FILE *fin = NULL; struct exec *exhdr = NULL; char *fname = NULL; char *stringtable; int strtbl_sz; struct relocation_info *data_reloc = NULL, *text_reloc = NULL; struct nlist *symbol_table = NULL; int show_header = 0; int show_data_reloc = 0; int show_text_reloc = 0; int show_symbol_table = 0; int print_symnames = 1; int correspondence = 0; int hdr_info = 0; int opt; while (-1 != (opt = getopt(ac, av, "hdtsacxn"))) { switch (opt) { case 'h': show_header = 1; break; case 'x': show_header = hdr_info = 1; break; /* show_header implied */ case 'd': show_data_reloc = 1; break; case 't': show_text_reloc = 1; break; case 's': show_symbol_table = 1; break; case 'c': correspondence = 1; break; case 'n': print_symnames = 0; break; case 'a': show_header = show_data_reloc = show_text_reloc = show_symbol_table = correspondence = hdr_info = 1; break; default: errout: fprintf(stderr, "%s: show exec header, relocation and symbol table data\n", av[0]); fprintf(stderr, "usage: %s [-h] [-d] [-t] [-s] [-c] [-x] [-a] <filename>\n", av[0]); fprintf(stderr, " -h: show exec header\n" " -x: show info derivable from exec header \n" " -d: show data segment relocations\n" " -t: show text segment relocations\n" " -c: show symbols that correspond to relocations\n" " -s: show symbol table\n" " -n: when showing symbol table, don't print symbol names\n" " -a: show it all\n"); return 1; break; } } if (0 == show_header && 0 == show_data_reloc && 0 == show_text_reloc && 0 == show_symbol_table) show_header = show_data_reloc = show_text_reloc = show_symbol_table = correspondence = 1; if (optind < ac) fname = av[optind]; if (NULL == fname) { fprintf(stderr, "Need a file to examine\n"); goto errout; } if (NULL == (fin = fopen(fname, "r"))) { fprintf(stderr, "Couldn't open \"%s\" for reading: %s\n", fname, strerror(errno)); return 1; } if (stat(fname, &attributes) < 0) { fprintf(stderr, "Problem on stat(2) of \"%s\": %s\n", fname, strerror(errno)); fclose(fin); return 1; } exhdr = (struct exec *)read_extent(fin, sizeof(*exhdr), 0, __LINE__); if (NULL == exhdr) { cleanup(fin, 1, exhdr); return 2; } if (show_header) { puts("a.out header:"); run_header(exhdr, hdr_info); } if (N_BADMAG(*exhdr)) { fprintf(stderr, "%s isn't a recognized NetBSD a.out file\n", fname); cleanup(fin, 1, exhdr); return 3; } stringtable = read_stringtable(fin, exhdr, &strtbl_sz); data_reloc = (struct relocation_info *)read_extent(fin, exhdr->a_drsize, N_DRELOFF(*exhdr), __LINE__); text_reloc = (struct relocation_info *)read_extent(fin, exhdr->a_trsize, N_TRELOFF(*exhdr), __LINE__); symbol_table = (struct nlist *) read_extent(fin, exhdr->a_syms, N_SYMOFF(*exhdr), __LINE__); if (show_data_reloc) { puts("\nData relocations:"); run_reloc(exhdr, exhdr->a_drsize, data_reloc, symbol_table, stringtable, strtbl_sz, correspondence); } if (show_text_reloc) { puts("\nText relocations:"); run_reloc(exhdr, exhdr->a_trsize, text_reloc, symbol_table, stringtable, strtbl_sz, correspondence); } if (show_symbol_table) { puts("\nSymbol table:"); run_symtable(exhdr, symbol_table, stringtable, strtbl_sz, print_symnames); } cleanup(fin, 5, exhdr, stringtable, data_reloc, text_reloc, symbol_table); return 0; }
static bfd_boolean MY (write_object_contents) (bfd * abfd) { struct external_exec exec_bytes; struct internal_exec *execp = exec_hdr (abfd); bfd_size_type text_size; /* dummy vars */ file_ptr text_end; memset (&exec_bytes, 0, sizeof (exec_bytes)); obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; if (adata (abfd).magic == undecided_magic) NAME (aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); execp->a_syms = 0; execp->a_entry = bfd_get_start_address (abfd); execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * obj_reloc_entry_size (abfd)); execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * obj_reloc_entry_size (abfd)); N_SET_MACHTYPE (*execp, 0xc); N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); NAME (aout,swap_exec_header_out) (abfd, execp, &exec_bytes); /* update fields not covered by default swap_exec_header_out */ /* this is really the sym table size but we store it in drelocs */ H_PUT_32 (abfd, (bfd_get_symcount (abfd) * 12), exec_bytes.e_drelocs); if (bfd_seek (abfd, (file_ptr) 0, FALSE) != 0 || (bfd_bwrite (&exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd) != EXEC_BYTES_SIZE)) return FALSE; /* Write out the symbols, and then the relocs. We must write out the symbols first so that we know the symbol indices. */ if (bfd_get_symcount (abfd) != 0) { /* Skip the relocs to where we want to put the symbols. */ if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp) + execp->a_drsize), SEEK_SET) != 0) return FALSE; } if (!MY (write_syms) (abfd)) return FALSE; if (bfd_get_symcount (abfd) != 0) { if (bfd_seek (abfd, (file_ptr) N_TRELOFF (*execp), SEEK_CUR) != 0) return FALSE; if (!NAME (aout,squirt_out_relocs) (abfd, obj_textsec (abfd))) return FALSE; if (bfd_seek (abfd, (file_ptr) N_DRELOFF (*execp), SEEK_CUR) != 0) return FALSE; if (!NAME (aout,squirt_out_relocs) (abfd, obj_datasec (abfd))) return FALSE; } return TRUE; }