From 6f2d32120e50bd3bc24ac0c16f53875a35788314 Mon Sep 17 00:00:00 2001 From: Steve Chamberlain Date: Thu, 29 Jun 1995 00:59:07 +0000 Subject: [PATCH] * ar.c: (print_contents.c, extract_file, do_quick_append): Malloc buffers rather than allocate on stack (so it works on NT). * deflex.l: Names can have an @ in them. * dlltool.c: Loads of stuff. Can now generate .imp files which work with NT .dlls. --- binutils/ChangeLog | 14 + binutils/ar.c | 49 +- binutils/deflex.l | 85 +++ binutils/dlltool.c | 639 ++++++++++++++------ binutils/srconv.c | 181 +++--- binutils/testsuite/binutils-all/objcopy.exp | 5 +- 6 files changed, 687 insertions(+), 286 deletions(-) create mode 100644 binutils/deflex.l diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 1d00170eeee..450533d5cea 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,17 @@ +Wed Jun 28 17:51:24 1995 Steve Chamberlain + + * ar.c: (print_contents.c, extract_file, do_quick_append): + Malloc buffers rather than allocate on stack (so it works + on NT). + * deflex.l: Names can have an @ in them. + * dlltool.c: Loads of stuff. Can now generate .imp files which + work with NT .dlls. + +Thu Jun 22 19:10:50 1995 Stan Shebs + + * mpw-make.in (demangle.c.o): Remove. + (arparse.h): Depend on arparse.c instead of arparse.y. + Wed Jun 21 17:32:45 1995 Ken Raeburn * Makefile.in (DISTSTUFF): Don't include info here. diff --git a/binutils/ar.c b/binutils/ar.c index a7cad3960af..71918a7b85e 100644 --- a/binutils/ar.c +++ b/binutils/ar.c @@ -27,6 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bfd.h" #include "sysdep.h" #include "libiberty.h" +#include "progress.h" #include "bucomm.h" #include "aout/ar.h" #include "libbfd.h" @@ -163,7 +164,10 @@ map_over_members (arch, function, files, count) if (count == 0) { for (head = arch->next; head; head = head->next) - function (head); + { + PROGRESS (1); + function (head); + } return; } /* This may appear to be a baroque way of accomplishing what we want. @@ -175,8 +179,10 @@ map_over_members (arch, function, files, count) for (; count > 0; files++, count--) { boolean found = false; + for (head = arch->next; head; head = head->next) { + PROGRESS (1); if (head->filename == NULL) { /* Some archive formats don't get the filenames filled in @@ -218,6 +224,7 @@ Usage: %s [-]{dmpqrtx}[abcilosuvV] [member-name] archive-file file...\n\ else fprintf (stderr, "\ Usage: %s [-vV] archive\n", program_name); + list_supported_targets (program_name, stderr); xexit (1); } @@ -283,6 +290,8 @@ main (argc, argv) program_name = argv[0]; xmalloc_set_program_name (program_name); + START_PROGRESS (program_name, 0); + bfd_init (); show_version = 0; @@ -410,6 +419,13 @@ main (argc, argv) case 'M': mri_mode = 1; break; + case 'f': + /* On HP/UX 9, the f modifier means to truncate names to 14 + characters when comparing them to existing names. We + always use an extended name table, so the truncation has + no purpose for us. We ignore the modifier for + compatibility with the AR_FLAGS definition in make. */ + break; default: fprintf (stderr, "%s: illegal option -- %c\n", program_name, c); usage (); @@ -523,6 +539,8 @@ main (argc, argv) } } + END_PROGRESS (program_name); + xexit (0); return 0; } @@ -579,6 +597,7 @@ open_inarch (archive_filename) next_one; next_one = bfd_openr_next_archived_file (arch, next_one)) { + PROGRESS (1); *last_one = next_one; last_one = &next_one->next; } @@ -593,6 +612,7 @@ print_contents (abfd) bfd *abfd; { int ncopied = 0; + char *cbuf = xmalloc (BUFSIZE); struct stat buf; long size; if (bfd_stat_arch_elt (abfd, &buf) != 0) @@ -606,7 +626,7 @@ print_contents (abfd) size = buf.st_size; while (ncopied < size) { - char cbuf[BUFSIZE]; + int nread; int tocopy = size - ncopied; if (tocopy > BUFSIZE) @@ -620,6 +640,7 @@ print_contents (abfd) fwrite (cbuf, 1, nread, stdout); ncopied += tocopy; } + free (cbuf); } /* Extract a member of the archive into its own file. @@ -637,7 +658,7 @@ extract_file (abfd) bfd *abfd; { FILE *ostream; - char cbuf[BUFSIZE]; + char *cbuf = xmalloc (BUFSIZE); int nread, tocopy; int ncopied = 0; long size; @@ -706,7 +727,7 @@ extract_file (abfd) if (preserve_dates) { -#ifdef POSIX_UTIME +#if POSIX_UTIME struct utimbuf tb; tb.actime = buf.st_mtime; tb.modtime = buf.st_mtime; @@ -727,6 +748,7 @@ extract_file (abfd) #endif /* ! USE_UTIME */ #endif /* ! POSIX_UTIME */ } +free (cbuf); } /* Just do it quickly; don't worry about dups, armap, or anything like that */ @@ -737,7 +759,7 @@ do_quick_append (archive_filename, files_to_append) char **files_to_append; { FILE *ofile, *ifile; - char buf[BUFSIZE]; + char *buf = xmalloc (BUFSIZE); long tocopy, thistime; bfd *temp; struct stat sbuf; @@ -830,6 +852,7 @@ do_quick_append (archive_filename, files_to_append) } fclose (ofile); bfd_close (temp); + free (buf); } @@ -838,19 +861,12 @@ write_archive (iarch) bfd *iarch; { bfd *obfd; - int namelen = strlen (bfd_get_filename (iarch)); - char *old_name = xmalloc (namelen + 1); - char *new_name = xmalloc (namelen + EXT_NAME_LEN); + char *old_name, *new_name; bfd *contents_head = iarch->next; + old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1); strcpy (old_name, bfd_get_filename (iarch)); - strcpy (new_name, bfd_get_filename (iarch)); - -#ifdef __GO32__ /* avoid long .extensions for MS-DOS */ - strcpy (new_name + namelen, "-a"); -#else - strcpy (new_name + namelen, "-art"); -#endif + new_name = make_tempname (old_name); output_filename = new_name; @@ -1037,7 +1053,8 @@ replace_members (arch, files_to_move) { current = *current_ptr; - if (!strcmp (normalize (*files_to_move), current->filename)) + if (!strcmp (normalize (*files_to_move), + normalize (current->filename))) { if (newer_only) { diff --git a/binutils/deflex.l b/binutils/deflex.l new file mode 100644 index 00000000000..ccbc2dd7287 --- /dev/null +++ b/binutils/deflex.l @@ -0,0 +1,85 @@ +%{ +/* deflex.l - Lexer for .def files */ + +/* Copyright (C) 1995 Free Software Foundation, Inc. + +This file is part of GNU Binutils. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* Contributed by Steve Chamberlain + sac@cygnus.com + +*/ +#define DONTDECLARE_MALLOC +#include "defparse.h" +extern char *strdup(); +int linenumber; + +%} +%% +"NAME" { return NAME;} +"LIBRARY" { return LIBRARY;} +"DESCRIPTION" { return DESCRIPTION;} +"STACKSIZE" { return STACKSIZE;} +"HEAPSIZE" { return HEAPSIZE;} +"CODE" { return CODE;} +"DATA" { return DATA;} +"SECTIONS" { return SECTIONS;} +"EXPORTS" { return EXPORTS;} +"IMPORTS" { return IMPORTS;} +"VERSION" { return VERSION;} +"BASE" { return BASE;} +"CONSTANT" { return CONSTANT; } +"NONAME" { return NONAME; } + +"READ" { return READ;} +"WRITE" { return WRITE;} +"EXECUTE" { return EXECUTE;} +"SHARED" { return SHARED;} + +[0-9][x0-9A-Fa-f]* { yylval.number = strtol (yytext,0,0); + return NUMBER; } + +[A-Za-z$:\-\_][A-Za-z0-9/$:\-\_@]+ { + yylval.id = strdup(yytext); + return ID; + } +"\""[^\"]*"\"" { + yylval.string = strdup (yytext+1); + yylval.string[yyleng-2] = 0; + return STRING; + } + +"\'"[^\']*"\'" { + yylval.string = strdup (yytext+1); + yylval.string[yyleng-2] = 0; + return STRING; + } +"*".* { } +";".* { } +" " { } +"\t" { } +"\n" { linenumber ++ ;} +"=" { return '=';} +"." { return '.';} +"@" { return '@';} +"," { return ',';} +%% +#ifndef yywrap +/* Needed for lex, though not flex. */ +int yywrap() { return 1; } +#endif diff --git a/binutils/dlltool.c b/binutils/dlltool.c index 042a454d90c..3e2c765058d 100644 --- a/binutils/dlltool.c +++ b/binutils/dlltool.c @@ -36,32 +36,32 @@ NAME [ , ] - The result is going to be .EXE + The result is going to be .EXE LIBRARY [ , ] - The result is going to be .DLL + The result is going to be .DLL EXPORTS ( [ = ] [ @ ] [ NONAME ] [CONSTANT] ) * - Declares name1 as an exported symbol from the - DLL, with optional ordinal number + Declares name1 as an exported symbol from the + DLL, with optional ordinal number IMPORTS ( [ = ] . ) * - Ignored for compatibility + Ignored for compatibility DESCRIPTION - Puts into output .exp file in the .rdata section + Puts into output .exp file in the .rdata section [STACKSIZE|HEAPSIZE] [ , ] - Generates --stack|--heap , - in the output .drective section. The linker will - see this and act upon it. + Generates --stack|--heap , + in the output .drective section. The linker will + see this and act upon it. [CODE|DATA] + SECTIONS ( + )* - = READ | WRITE | EXECUTE | SHARED - Generates --attr in the output - .drective section. The linker will see this and act - upon it. + = READ | WRITE | EXECUTE | SHARED + Generates --attr in the output + .drective section. The linker will see this and act + upon it. A -export: in a .drective section in an input .o or .a @@ -70,102 +70,103 @@ - The program generates output files with the prefix supplied - on the command line, or in the def file, or taken from the first - supplied argument. + The program generates output files with the prefix supplied + on the command line, or in the def file, or taken from the first + supplied argument. - The output files are .exp.s and .lib.s + The output files are -exp.s and -lib.s - The .exp.s file contains the information necessary to export - the routines in the DLL. The .lib.s file contains the information - necessary to use the DLL's routines from a referencing program. + The .exp.s file contains the information necessary to export + the routines in the DLL. The .lib.s file contains the information + necessary to use the DLL's routines from a referencing program. -Example: + Example: -file1.c: - asm (".section .drectve"); - asm (".ascii \"-export:adef\""); + file1.c: + asm (".section .drectve"); + asm (".ascii \"-export:adef\""); - adef(char *s) - { - printf("hello from the dll %s\n",s); - } + adef(char *s) + { + printf("hello from the dll %s\n",s); + } - bdef(char *s) - { - printf("hello from the dll and the other entry point %s\n",s); - } + bdef(char *s) + { + printf("hello from the dll and the other entry point %s\n",s); + } -file2.c: - asm (".section .drectve"); - asm (".ascii \"-export:cdef\""); - asm (".ascii \"-export:ddef\""); - cdef(char *s) - { - printf("hello from the dll %s\n",s); - } + file2.c: + asm (".section .drectve"); + asm (".ascii \"-export:cdef\""); + asm (".ascii \"-export:ddef\""); + cdef(char *s) + { + printf("hello from the dll %s\n",s); + } - ddef(char *s) - { - printf("hello from the dll and the other entry point %s\n",s); - } + ddef(char *s) + { + printf("hello from the dll and the other entry point %s\n",s); + } - printf() - { - return 9; - } + printf() + { + return 9; + } -main.c + main.c - main() - { - cdef(); - } + main() + { + cdef(); + } -thedll.def + thedll.def - LIBRARY thedll - HEAPSIZE 0x40000, 0x2000 - EXPORTS bdef @ 20 - cdef @ 30 NONAME + LIBRARY thedll + HEAPSIZE 0x40000, 0x2000 + EXPORTS bdef @ 20 + cdef @ 30 NONAME - SECTIONS donkey READ WRITE - aardvark EXECUTE + SECTIONS donkey READ WRITE + aardvark EXECUTE -# compile up the parts of the dll + # compile up the parts of the dll -gcc -c file1.c -gcc -c file2.c + gcc -c file1.c + gcc -c file2.c -# put them in a library (you don't have to, you -# could name all the .os on the dlltool line) + # put them in a library (you don't have to, you + # could name all the .os on the dlltool line) -ar qcv thedll.in file1.o file2.o -ranlib thedll.in + ar qcv thedll.in file1.o file2.o + ranlib thedll.in -# run this tool over the library and the def file -./dlltool -o thedll -d thedll.def thedll.in + # run this tool over the library and the def file + ./dlltool -o thedll -d thedll.def thedll.in -# build the export table for the dll -as -o thedll.exp thedll.exp.s -# build the dll with the library with file1.o, file2.o and the export table -ld -o thedll.dll thedll.exp thedll.in + # build the export table for the dll + as -o thedll.exp thedll-exp.s + # build the dll with the library with file1.o, file2.o and the export table + ld -o thedll.dll thedll.exp thedll.in -# build the import table for the executable -as -o thedll.lib thedll.lib.s + # build the import table for the executable + as -o thedll.lib thedll-lib.s -# build the mainline -gcc -c themain.c + # build the mainline + gcc -c themain.c -# link the executable with the import library -ld -e main -Tthemain.ld -o themain.exe themain.o thedll.lib + # link the executable with the import library + ld -e main -Tthemain.ld -o themain.exe themain.o thedll.lib + */ -*/ - +#define PAGE_SIZE 4096 +#define PAGE_MASK (-PAGE_SIZE) #include #include #include @@ -180,30 +181,44 @@ char *xmalloc (); char *strdup (); static int machine; - +int suckunderscore; +static int verbose; +FILE *base_file; #ifdef DLLTOOL_ARM -static char *mname = "arm"; +static char *mname = "arm"; #endif #ifdef DLLTOOL_I386 -static char *mname = "i386"; +static char *mname = "i386"; #endif +#define PATHMAX 250 /* What's the right name for this ? */ +char outfile[PATHMAX]; struct mac + { + char *type; + char *how_byte; + char *how_short; + char *how_long; + char *how_asciz; + char *how_comment; + char *how_jump; + char *how_global; + char *how_space; + } +mtable[] += { - char *type; - char *how_byte; - char *how_short; - char *how_long; - char *how_asciz; - char *how_comment; - char *how_jump; - char *how_global; - char *how_space; -} mtable[] -= {{"arm",".byte",".short",".long",".asciz","@","bl",".global",".space"}, - {"i386",".byte",".short",".long",".asciz",";","jmp",".global",".space"}, - 0}; + { + "arm", ".byte", ".short", ".long", ".asciz", "@", "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", ".global", ".space" + } + , + { + "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space" + } + , + 0 +}; #define ASM_BYTE mtable[machine].how_byte #define ASM_SHORT mtable[machine].how_short @@ -214,7 +229,7 @@ struct mac #define ASM_GLOBAL mtable[machine].how_global #define ASM_SPACE mtable[machine].how_space -#define PATHMAX 250 /* What's the right name for this ? */ + static char **oav; int i; @@ -228,7 +243,7 @@ process_def_file (name) FILE *f = fopen (name, "r"); if (!f) { - fprintf (stderr, "Can't open def file %s\n", name); + fprintf (stderr, "%s: Can't open def file %s\n", program_name, name); exit (1); } @@ -246,17 +261,18 @@ typedef struct dlist { char *text; struct dlist *next; -} dlist_type; +} +dlist_type; typedef struct export -{ - char *name; - char *internal_name; - int ordinal; - int constant; - int noname; - struct export *next; -} + { + char *name; + char *internal_name; + int ordinal; + int constant; + int noname; + struct export *next; + } export_type; static char *d_name; /* Arg to NAME or LIBRARY */ @@ -264,16 +280,16 @@ static int d_nfuncs; /* Number of functions exported */ static int d_ord; /* Base ordinal index */ static export_type *d_exports; /*list of exported functions */ static char *d_suffix = "dll"; -static dlist_type *d_list; /* Descriptions */ -static dlist_type *a_list; /* Stuff to go in directives */ +static dlist_type *d_list; /* Descriptions */ +static dlist_type *a_list; /* Stuff to go in directives */ static int d_is_dll; static int d_is_exe; yyerror () { - fprintf (stderr, "Syntax error in def file %s:%d\n", - def_file, linenumber); + fprintf (stderr, "%s: Syntax error in def file %s:%d\n", + program_name, def_file, linenumber); } void @@ -296,12 +312,14 @@ def_exports (name, internal_name, ordinal, noname, constant) d_nfuncs++; } + void def_name (name, base) char *name; int base; { - printf ("NAME %s base %x\n", name, base); + if (verbose) + fprintf (stderr, "%s NAME %s base %x\n", program_name, name, base); if (d_is_dll) { fprintf (stderr, "Can't have LIBRARY and NAME\n"); @@ -317,10 +335,11 @@ def_library (name, base) char *name; int base; { - printf ("LIBRARY %s base %x\n", name, base); + if (verbose) + printf ("%s: LIBRARY %s base %x\n", program_name, name, base); if (d_is_exe) { - fprintf (stderr, "Can't have LIBRARY and NAME\n"); + fprintf (stderr, "%s: Can't have LIBRARY and NAME\n", program_name); } d_name = name; if (strchr (d_name, '.')) @@ -332,16 +351,17 @@ void def_description (desc) char *desc; { - dlist_type *d = (dlist_type *)xmalloc(sizeof(dlist_type)); + dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type)); d->text = strdup (desc); d->next = d_list; d_list = d; } -void new_directive(dir) -char *dir; +void +new_directive (dir) + char *dir; { - dlist_type *d = (dlist_type *)xmalloc(sizeof(dlist_type)); + dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type)); d->text = strdup (dir); d->next = a_list; a_list = d; @@ -353,11 +373,11 @@ def_stacksize (reserve, commit) int commit; { char b[200]; - if (commit>0) - sprintf (b,"-stack 0x%x,0x%x ", reserve, commit); - else - sprintf (b,"-stack 0x%x ", reserve); - new_directive (strdup(b)); + if (commit > 0) + sprintf (b, "-stack 0x%x,0x%x ", reserve, commit); + else + sprintf (b, "-stack 0x%x ", reserve); + new_directive (strdup (b)); } void @@ -366,11 +386,11 @@ def_heapsize (reserve, commit) int commit; { char b[200]; - if (commit>0) - sprintf (b,"-heap 0x%x,0x%x ", reserve, commit); - else - sprintf (b,"-heap 0x%x ", reserve); - new_directive (strdup(b)); + if (commit > 0) + sprintf (b, "-heap 0x%x,0x%x ", reserve, commit); + else + sprintf (b, "-heap 0x%x ", reserve); + new_directive (strdup (b)); } @@ -380,7 +400,8 @@ def_import (internal, module, entry) char *module; char *entry; { - fprintf (stderr, "IMPORTS are ignored"); + if (verbose) + fprintf (stderr, "%s: IMPORTS are ignored", program_name); } void @@ -396,10 +417,10 @@ def_section (name, attr) int attr; { char buf[200]; - char atts[5]; + char atts[5]; char *d = atts; if (attr & 1) - *d++= 'R'; + *d++ = 'R'; if (attr & 2) *d++ = 'W'; @@ -409,26 +430,37 @@ def_section (name, attr) *d++ = 'S'; *d++ = 0; sprintf (buf, "-attr %s %s", name, atts); - new_directive (strdup(buf)); + new_directive (strdup (buf)); } void def_code (attr) int attr; { -def_section ("CODE", attr); + def_section ("CODE", attr); } void def_data (attr) int attr; { - def_section ("DATA",attr); + def_section ("DATA", attr); } /**********************************************************************/ +/* read in and block out the base relocations */ +static void +basenames (abfd) + bfd *abfd; +{ + + + + +} + void scan_open_obj_file (abfd) bfd *abfd; @@ -442,8 +474,10 @@ scan_open_obj_file (abfd) char *p; char *e; bfd_get_section_contents (abfd, s, buf, 0, size); - printf ("Sucking in info from %s\n", - bfd_get_filename (abfd)); + if (verbose) + fprintf (stderr, "%s: Sucking in info from %s\n", + program_name, + bfd_get_filename (abfd)); /* Search for -export: strings */ p = buf; @@ -469,6 +503,13 @@ scan_open_obj_file (abfd) } free (buf); } + + basenames (abfd); + + if (verbose) + fprintf (stderr, "%s: Done readin\n", + program_name); + } @@ -480,7 +521,9 @@ scan_obj_file (filename) if (!f) { - fprintf (stderr, "Unable to open object file %s\n", filename); + fprintf (stderr, "%s: Unable to open object file %s\n", + program_name, + filename); exit (1); } if (bfd_check_format (f, bfd_archive)) @@ -522,21 +565,21 @@ prefix (name) void dump_def_info (f) -FILE *f; + FILE *f; { int i; export_type *exp; - fprintf(f,"%s ", ASM_C); - for (i= 0; oav[i]; i++) - fprintf(f,"%s ", oav[i]); - fprintf(f,"\n"); + fprintf (f, "%s ", ASM_C); + for (i = 0; oav[i]; i++) + fprintf (f, "%s ", oav[i]); + fprintf (f, "\n"); for (i = 0, exp = d_exports; exp; i++, exp = exp->next) { fprintf (f, "%s %d = %s %s @ %d %s%s\n", ASM_C, i, - exp->name, - exp->internal_name, + exp->name, + exp->internal_name, exp->ordinal, exp->noname ? "NONAME " : "", exp->constant ? "CONSTANT" : ""); @@ -544,23 +587,69 @@ FILE *f; } /* Generate the .exp file */ +int +sfunc (a, b) + long *a; + long *b; +{ + return *a - *b; +} + +static void +flush_page (f, need, page_addr, on_page) + FILE *f; + long *need; + long page_addr; + int on_page; +{ + int i; + /* Flush this page */ + fprintf (f, "\t%s\t0x%x\t%s Starting RVA for chunk\n", + ASM_LONG, + page_addr, + ASM_C); + fprintf (f, "\t%s\t0x%x\t%s Size of block\n", + ASM_LONG, + (on_page * 2) + (on_page & 1) * 2 + 8, + ASM_C); + for (i = 0; i < on_page; i++) + { + fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, need[i] - page_addr | 0x3000); + } + /* And padding */ + if (on_page & 1) + fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000); + +} + void gen_exp_file () { FILE *f; - char outfile[PATHMAX]; int i; export_type *exp; dlist_type *dl; - sprintf (outfile, "%s.exp.s", outfile_prefix); + int had_noname = 0; + + sprintf (outfile, "%s-exp.s", outfile_prefix); + + if (verbose) + fprintf (stderr, "%s: Generate exp file %s\n", + program_name, outfile_prefix); f = fopen (outfile, "w"); if (!f) { - fprintf (stderr, "Unable to open output file %s\n", outfile); + fprintf (stderr, "%s: Unable to open output file %s\n", program_name, outfile); exit (1); } + if (verbose) + { + fprintf (stderr, "%s: Opened file %s\n", + program_name, outfile); + } + dump_def_info (f); fprintf (f, "\t.section .edata\n\n"); fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C); @@ -584,13 +673,17 @@ gen_exp_file () i = d_ord; for (exp = d_exports; exp; exp = exp->next) { +#if 0 + /* This seems necessary in the doc, but in real + life it's not used.. */ if (exp->ordinal != i) { - fprintf (f, "\t%s\t%d\t@ %d..%d missing\n", ASM_SPACE, + fprintf (f, "%s\t%s\t%d\t@ %d..%d missing\n", ASM_C, ASM_SPACE, (exp->ordinal - i) * 4, i, exp->ordinal - 1); i = exp->ordinal; } +#endif fprintf (f, "\t%s %s\t%s %d\n", ASM_LONG, exp->internal_name, ASM_C, exp->ordinal); i++; } @@ -598,10 +691,17 @@ gen_exp_file () fprintf (f, "anames:\n"); for (i = 0, exp = d_exports; exp; i++, exp = exp->next) - if (exp->noname) - fprintf (f, "\t%s 0\t%sNoname\n", ASM_LONG, ASM_C); - else - fprintf (f, "\t%s n%d\n", ASM_LONG, i); + { + if (exp->noname) + { + had_noname = 1; + fprintf (f, "\t%s nNoname\n", ASM_LONG, ASM_C); + } + else + { + fprintf (f, "\t%s n%d\n", ASM_LONG, i); + } + } fprintf (f, "anords:\n"); for (exp = d_exports; exp; exp = exp->next) @@ -613,18 +713,20 @@ gen_exp_file () else fprintf (f, "n%d: %s \"%s\"\n", i, ASM_TEXT, exp->name); + if (had_noname) + fprintf (f, "nNoname: %s \"__noname__\"\n", ASM_TEXT); if (a_list) { - fprintf(f,"\t.section .drectve\n"); + fprintf (f, "\t.section .drectve\n"); for (dl = a_list; dl; dl = dl->next) { - fprintf (f,"\t%s\t\"%s\"\n", ASM_TEXT, dl->text); + fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text); } } - if (d_list) + if (d_list) { - fprintf(f,"\t.section .rdata\n"); + fprintf (f, "\t.section .rdata\n"); for (dl = d_list; dl; dl = dl->next) { char *p; @@ -633,35 +735,91 @@ gen_exp_file () be quote characters in the string */ l = 0; - for (p = dl->text; *p; p++) { - if (l == 0) - fprintf(f,"\t%s\t", ASM_BYTE); - else - fprintf(f,","); - fprintf(f,"%d", *p); - if (p[1] == 0) { - fprintf(f,",0\n"); - break; + for (p = dl->text; *p; p++) + { + if (l == 0) + fprintf (f, "\t%s\t", ASM_BYTE); + else + fprintf (f, ","); + fprintf (f, "%d", *p); + if (p[1] == 0) + { + fprintf (f, ",0\n"); + break; + } + if (++l == 10) + { + fprintf (f, "\n"); + l = 0; + } } - if (++l == 10) { - fprintf(f,"\n"); - l = 0; + } + } + + /* Dump the reloc section if a base file is provided */ + if (base_file) + { + int addr; + long need[PAGE_SIZE]; + long page_addr; + int numbytes; + int num_entries; + long *copy; + int j; + int on_page; + fprintf (f, "\t.section\t.reloc\n"); + fseek (base_file, 0, SEEK_END); + numbytes = ftell (base_file); + fseek (base_file, 0, SEEK_SET); + copy = malloc (numbytes); + fread (copy, 1, numbytes, base_file); + num_entries = numbytes / sizeof (long); + + qsort (copy, num_entries, sizeof (long), sfunc); + + addr = copy[0]; + page_addr = addr & PAGE_MASK; /* work out the page addr */ + on_page = 0; + for (j = 0; j < num_entries; j++) + { + addr = copy[j]; + if ((addr & PAGE_MASK) != page_addr) + { + flush_page (f, need, page_addr, on_page); + on_page = 0; + page_addr = addr & PAGE_MASK; } - } + need[on_page++] = addr; } + flush_page (f, need, page_addr, on_page); } + fclose (f); } +static char * +xlate (char *name) +{ + char *p; + if (!suckunderscore) + return name; + + if (name[0] == '_') + name++; + p = strchr (name, '@'); + if (p) + *p = 0; + return name; +} + /**********************************************************************/ gen_lib_file () { - char outfile[PATHMAX]; int i; FILE *f; export_type *exp; - sprintf (outfile, "%s.lib.s", outfile_prefix); + sprintf (outfile, "%s-lib.s", outfile_prefix); f = fopen (outfile, "w"); if (!f) @@ -677,12 +835,12 @@ gen_lib_file () for (i = 0, exp = d_exports; exp; i++, exp = exp->next) { fprintf (f, "\t%s\t%s\n", ASM_GLOBAL, exp->name); - fprintf (f, "\t%s\t__imp__%s\n", ASM_GLOBAL, exp->name); + fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name); } for (i = 0, exp = d_exports; exp; i++, exp = exp->next) { - fprintf (f, "%s:\t%s\t__imp__%s\n", exp->name, ASM_JUMP, exp->name); + fprintf (f, "%s:\t%s\t__imp_%s\n", exp->name, ASM_JUMP, exp->name); } @@ -694,14 +852,28 @@ gen_lib_file () fprintf (f, "\t%s\tiname\t%s imported dll's name\n", ASM_LONG, ASM_C); fprintf (f, "\t%s\tfthunk\t%s pointer to firstthunk\n", ASM_LONG, ASM_C); + fprintf (f, "%sStuff for compatibility\n", ASM_C); + fprintf (f, "\t.section\t.idata$3\n"); + fprintf (f, "\t%s\t0\n", ASM_LONG); + fprintf (f, "\t%s\t0\n", ASM_LONG); + fprintf (f, "\t%s\t0\n", ASM_LONG); + fprintf (f, "\t%s\t0\n", ASM_LONG); + fprintf (f, "\t%s\t0\n", ASM_LONG); + fprintf (f, "\t.section\t.idata$5\n"); + fprintf (f, "\t%s\t0\n", ASM_LONG); + + fprintf (f, "\t.section\t.idata$4\n"); + fprintf (f, "\t%s\t0\n", ASM_LONG); + fprintf (f, "\n%s Loader modifies this\n", ASM_C); fprintf (f, "\t.section .idata$5\n"); fprintf (f, "fthunk:\n"); for (i = 0, exp = d_exports; exp; i++, exp = exp->next) { - fprintf (f, "__imp__%s:\n", exp->name); + fprintf (f, "__imp_%s:\n", exp->name); fprintf (f, "\t%s\tID%d\n", ASM_LONG, i); } + fprintf (f, "\t%s\t0\n", ASM_LONG); fprintf (f, "\n%s Hint name array\n", ASM_C); fprintf (f, "\t.section .idata$4\n"); @@ -711,15 +883,16 @@ gen_lib_file () fprintf (f, "\t%s\tID%d\n", ASM_LONG, i); } + fprintf (f, "\t%s\t0\n", ASM_LONG); fprintf (f, "%s Hint/name array storage and import dll name\n", ASM_C); fprintf (f, "\t.section .idata$6\n"); for (i = 0, exp = d_exports; exp; i++, exp = exp->next) { fprintf (f, "ID%d:\t%s\t%d\n", i, ASM_SHORT, exp->ordinal); - fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, exp->name); + fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name)); } - + fprintf (f, "\t%s\t0\n", ASM_LONG); fprintf (f, "iname:\t%s\t\"%s.%s\"\n", ASM_TEXT, outfile_prefix, d_suffix); fclose (f); } @@ -819,9 +992,11 @@ process_duplicates (d_export_vec) export_type *b = d_export_vec[i + 1]; more = 1; - - fprintf (stderr, "warning, ignoring duplicate EXPORT %s\n", - a->name); + if (verbose) + fprintf (stderr, "Warning, ignoring duplicate EXPORT %s %d,%d\n", + a->name, + a->ordinal, + b->ordinal); if (a->ordinal != -1 && b->ordinal != -1) { @@ -849,27 +1024,58 @@ fill_ordinals (d_export_vec) export_type **d_export_vec; { int lowest = 0; + int unset = 0; + char *ptr; qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc); - /* fill in the unset ordinals with ones from the minimum */ + /* fill in the unset ordinals with ones from our range */ + + ptr = (char *) malloc (65536); + + memset (ptr, 65536, 0); + + /* Mark in our large vector all the numbers that are taken */ for (i = 0; i < d_nfuncs; i++) { - if (d_export_vec[i]->ordinal == -1) + if (d_export_vec[i]->ordinal != -1) { - d_export_vec[i]->ordinal = lowest++; + ptr[d_export_vec[i]->ordinal] = 1; + if (lowest == 0) + lowest = d_export_vec[i]->ordinal; } - else + } + + for (i = 0; i < d_nfuncs; i++) + { + if (d_export_vec[i]->ordinal == -1) { - if (lowest == d_export_vec[i]->ordinal) - { - fprintf (stderr, "Warning, Duplicate ordinal %s @ %d\n", - d_export_vec[i]->name, - d_export_vec[i]->ordinal); - } - lowest = d_export_vec[i]->ordinal + 1; + int j; + for (j = lowest; j < 65536; j++) + if (ptr[j] == 0) + { + ptr[j] = 1; + d_export_vec[i]->ordinal = j; + goto done; + } + + for (j = 1; j < lowest; j++) + if (ptr[j] == 0) + { + ptr[j] = 1; + d_export_vec[i]->ordinal = j; + goto done; + } + done:; + } } + free (ptr); + + /* And resort */ + + qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc); + /* Work out the lowest ordinal number */ if (d_export_vec[0]) d_ord = d_export_vec[0]->ordinal; @@ -910,15 +1116,26 @@ usage (file, status) FILE *file; int status; { - fprintf (file, "Usage %s [-m|--machine machine] [-o outprefix] [-d|--def deffile] [--def deffile]\n", program_name); + fprintf (file, "Usage %s \n", program_name); + fprintf (file, "\t -m Generate code for \n"); + fprintf (file, "\t --machine \n"); + fprintf (file, "\t -o Set output prefix\n"); + fprintf (file, "\t -d Name input .def file\n"); + fprintf (file, "\t --def \n"); + fprintf (file, "\t --base-file Read linker generated base file\n"); + fprintf (file, "\t -b \n"); + fprintf (file, "\t -v Verbose\n"); + exit (status); } static struct option long_options[] = { {"def", required_argument, NULL, 'd'}, + {"underscore", no_argument, NULL, 'u'}, {"help", no_argument, NULL, 'h'}, {"machine", required_argument, NULL, 'm'}, + {"base-file", required_argument, NULL, 'b'}, 0 }; @@ -931,14 +1148,14 @@ main (ac, av) char *firstarg = 0; program_name = av[0]; oav = av; - - while ((c = getopt_long (ac, av, "h?m:o:Dd:", long_options, 0)) != EOF) + + while ((c = getopt_long (ac, av, "vbuh?m:o:Dd:", long_options, 0)) != EOF) { switch (c) { case 'h': case '?': - usage(stderr,0); + usage (stderr, 0); break; case 'm': mname = optarg; @@ -946,35 +1163,50 @@ main (ac, av) case 'o': outfile_prefix = optarg; break; + case 'v': + verbose = 1; + break; case 'D': yydebug = 1; break; + case 'u': + suckunderscore = 1; + break; case 'd': def_file = optarg; break; + case 'b': + base_file = fopen (optarg, "r"); + if (!base_file) + { + fprintf (stderr, "%s: Unable to open base-file %s\n", + av[0], + optarg); + exit (1); + } + break; default: usage (stderr, 1); } } - for (i = 0; mtable[i].type; i++) + for (i = 0; mtable[i].type; i++) { if (strcmp (mtable[i].type, mname) == 0) break; } - if (!mtable[i].type) + if (!mtable[i].type) { - fprintf(stderr,"Machine not supported\n"); - exit(1); + fprintf (stderr, "Machine not supported\n"); + exit (1); } machine = i; if (def_file) { - process_def_file (def_file); } while (optind < ac) @@ -1001,8 +1233,15 @@ main (ac, av) } outfile_prefix = prefix (outfile_prefix); + if (verbose) + fprintf (stderr, "%s: Outfile prefix is %s\n", + program_name, outfile_prefix); mangle_defs (); + gen_exp_file (); + + gen_lib_file (); + return 0; } diff --git a/binutils/srconv.c b/binutils/srconv.c index cb62657e7ca..9066f1135fa 100644 --- a/binutils/srconv.c +++ b/binutils/srconv.c @@ -25,19 +25,18 @@ All debugging information is preserved */ #include -#include -#include -#include -#include +#include "sysdep.h" #include "bucomm.h" #include "sysroff.h" #include "coffgrok.h" +#include +#include #include "coff/internal.h" #include "../bfd/libcoff.h" #define PROGRAM_VERSION "1.5" -/*#define FOOP1 1*/ +/*#define FOOP1 1 */ static int sh; static int h8300; @@ -50,10 +49,12 @@ static FILE *file; static bfd *abfd; static int debug = 0; static int quick = 0; - +static int noprescan = 0; static struct coff_ofile *tree; +/* Obsolete ?? + static int absolute_p; + */ -static int absolute_p; static int segmented_p; static int code; @@ -298,10 +299,11 @@ wr_tr () } static void -wr_un (ptr, sfile, first) +wr_un (ptr, sfile, first, nsecs) struct coff_ofile *ptr; struct coff_sfile *sfile; int first; + int nsecs; { struct IT_un un; @@ -314,7 +316,15 @@ wr_un (ptr, sfile, first) else un.format = FORMAT_OM; un.spare1 = 0; + + +#if 0 un.nsections = ptr->nsections - 1; /* Don't count the abs section */ +#else + /*NEW - only count sections with size */ + un.nsections = nsecs; +#endif + un.nextdefs = 0; un.nextrefs = 0; /* Count all the undefined and defined variables with global scope */ @@ -440,13 +450,13 @@ wr_ob (p, section) unsigned char stuff[200]; i = 0; - while (i < section->size) + while (i < section->bfd_section->_raw_size) { struct IT_ob ob; int todo = 200; /* Copy in 200 byte lumps */ ob.spare = 0; - if (i + todo > section->size) - todo = section->size - i; + if (i + todo > section->bfd_section->_raw_size) + todo = section->bfd_section->_raw_size - i; if (first) { @@ -467,9 +477,28 @@ wr_ob (p, section) ob.data.len = todo; bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo); ob.data.data = stuff; - sysroff_swap_ob_out (file, &ob /*, i + todo < section->size*/ ); + sysroff_swap_ob_out (file, &ob /*, i + todo < section->size */ ); i += todo; } + /* Now fill the rest with blanks */ + while (i < section->size) + { + struct IT_ob ob; + int todo = 200; /* Copy in 200 byte lumps */ + ob.spare = 0; + if (i + todo > section->size) + todo = section->size - i; + ob.saf = 0; + + ob.cpf = 0; /* Never compress */ + ob.data.len = todo; + memset (stuff, 0, todo); + ob.data.data = stuff; + sysroff_swap_ob_out (file, &ob); + i += todo; + } + /* Now fill the rest with blanks */ + } static void @@ -824,42 +853,43 @@ walk_tree_type_1 (sfile, symbol, type, nest) } } -static void -dty_start () -{ - struct IT_dty dty; - dty.end = 0; - dty.neg = 0x1001; - dty.spare = 0; - sysroff_swap_dty_out (file, &dty); -} - -static void -dty_stop () -{ - struct IT_dty dty; - dty.end = 0; - dty.neg = 0x1001; - dty.end = 1; - sysroff_swap_dty_out (file, &dty); -} - - -static void -dump_tree_structure (sfile, symbol, type, nest) - struct coff_sfile *sfile; - struct coff_symbol *symbol; - struct coff_type *type; - int nest; -{ - if (symbol->type->type == coff_function_type) - { - - - } - -} - +/* Obsolete ? + static void + dty_start () + { + struct IT_dty dty; + dty.end = 0; + dty.neg = 0x1001; + dty.spare = 0; + sysroff_swap_dty_out (file, &dty); + } + + static void + dty_stop () + { + struct IT_dty dty; + dty.end = 0; + dty.neg = 0x1001; + dty.end = 1; + sysroff_swap_dty_out (file, &dty); + } + + + static void + dump_tree_structure (sfile, symbol, type, nest) + struct coff_sfile *sfile; + struct coff_symbol *symbol; + struct coff_type *type; + int nest; + { + if (symbol->type->type == coff_function_type) + { + + + } + + } + */ static void walk_tree_type (sfile, symbol, type, nest) @@ -1067,8 +1097,8 @@ walk_tree_symbol (sfile, section, symbol, nest) break; case coff_where_member_of_enum: /* dsy.bitunit = 0; - dsy.field_len = symbol->type->size; - dsy.field_off = symbol->where->offset;*/ + dsy.field_len = symbol->type->size; + dsy.field_off = symbol->where->offset; */ break; case coff_where_register: case coff_where_unknown: @@ -1327,7 +1357,7 @@ wr_dus (p, sfile) } /* Find the offset of the .text section for this sfile in the - .text section for the output file */ + .text section for the output file */ static int find_base (sfile, section) @@ -1537,12 +1567,13 @@ wr_cs () for all the sections which appear in the output file, even if there isn't an equivalent one on the input */ -static void +static int wr_sc (ptr, sfile) struct coff_ofile *ptr; struct coff_sfile *sfile; { int i; +int scount = 0; /* First work out the total number of sections */ int total_sec = ptr->nsections; @@ -1555,7 +1586,7 @@ wr_sc (ptr, sfile) struct coff_symbol *symbol; struct myinfo *info - = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo)); + = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo)); @@ -1646,14 +1677,13 @@ wr_sc (ptr, sfile) { sc.contents = CONTENTS_CODE; } - - - sysroff_swap_sc_out (file, &sc); - - - + /* NEW */ + if (sc.length) { + sysroff_swap_sc_out (file, &sc); + scount++; + } } - +return scount; } static void @@ -1731,8 +1761,16 @@ wr_unit_info (ptr) sfile; sfile = sfile->next) { - wr_un (ptr, sfile, first); - wr_sc (ptr, sfile); + long p1; + long p2; + int nsecs; + p1 = ftell (file); + wr_un (ptr, sfile, first, 0); + nsecs = wr_sc (ptr, sfile); + p2 = ftell (file); + fseek (file, p1, 0); + wr_un (ptr, sfile, first, nsecs); + fseek (file, p2, 0); wr_er (ptr, sfile, first); wr_ed (ptr, sfile, first); first = 0; @@ -1776,7 +1814,7 @@ prescan (tree) if (s->visible->type == coff_vis_common) { struct coff_where *w = s->where; - /* s->visible->type = coff_vis_ext_def; leave it as common */ + /* s->visible->type = coff_vis_ext_def; leave it as common */ common_section->size = align (common_section->size); w->offset = common_section->size + common_section->address; w->section = common_section; @@ -1817,6 +1855,7 @@ main (ac, av) { {"debug", no_argument, 0, 'd'}, {"quick", no_argument, 0, 'q'}, + {"noprescan", no_argument, 0, 'n'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {NULL, no_argument, 0, 0} @@ -1828,7 +1867,7 @@ main (ac, av) program_name = av[0]; xmalloc_set_program_name (program_name); - while ((opt = getopt_long (ac, av, "dhVq", long_options, + while ((opt = getopt_long (ac, av, "dhVqn", long_options, (int *) NULL)) != EOF) { @@ -1837,21 +1876,24 @@ main (ac, av) case 'q': quick = 1; break; + case 'n': + noprescan = 1; + break; case 'd': debug = 1; break; case 'h': show_help (); - /*NOTREACHED*/ + /*NOTREACHED */ case 'V': printf ("GNU %s version %s\n", program_name, PROGRAM_VERSION); exit (0); - /*NOTREACHED*/ + /*NOTREACHED */ case 0: break; default: show_usage (stderr, 1); - /*NOTREACHED*/ + /*NOTREACHED */ } } @@ -1889,7 +1931,7 @@ main (ac, av) if (!output_file) { /* Take a .o off the input file and stick on a .obj. If - it doesn't end in .o, then stick a .obj on anyway */ + it doesn't end in .o, then stick a .obj on anyway */ int len = strlen (input_file); output_file = xmalloc (len + 5); @@ -1936,7 +1978,8 @@ main (ac, av) if (debug) printf ("ids %d %d\n", base1, base2); tree = coff_grok (abfd); - prescan (tree); + if (!noprescan) + prescan (tree); wr_module (tree); return 0; } diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp index bf4366f22a5..039b24b25b6 100644 --- a/binutils/testsuite/binutils-all/objcopy.exp +++ b/binutils/testsuite/binutils-all/objcopy.exp @@ -47,14 +47,17 @@ if ![string match "" $got] then { # in the first place, and may order things a little differently. # Those systems should use setup_xfail here. - setup_xfail "sh-*-coff" "sh-*-hms" + setup_xfail "sh-*-coff" "sh-*-hms" + setup_xfail "arm-*-pe" setup_xfail "m68*-*-hpux*" "m68*-*-sunos*" "m68*-*-coff" "m68*-*-vxworks*" setup_xfail "m68*-ericsson-ose" setup_xfail "i*86-*-linux" setup_xfail "a29k-*-udi" "a29k-*-coff" setup_xfail "i960-*-vxworks5.1" "i960-*-coff" setup_xfail "h8300-*-hms" "h8300-*-coff" + setup_xfail "h8500-*-hms" "h8500-*-coff" setup_xfail "hppa*-*-*" + clear_xfail "hppa*-*-*elf*" setup_xfail "m88*-*-coff" if [string match "" $exec_output] then { -- 2.30.2